#!/usr/local/bin/php \n"); die; } $CONDUIT_TOKEN_FILE = $argv[1]; $OUTPUT_DIR = $argv[2]; ///////////////////////////////////////////////////////////////////////////////// // Global configuration. $HOST = 'phabricator.local'; ///////////////////////////////////////////////////////////////////////////////// // Utilities. // Create an instance of the AphrontApplicationConfiguration configured with all // invariant settings (settings which do not change between handlers of different // revisions). function CreateApplicationConfiguration() { global $HOST; $application_configuration = new AphrontApplicationConfiguration(); $application_configuration->setHost($HOST); return $application_configuration; } ///////////////////////////////////////////////////////////////////////////////// // Global state. $site = id(new PhabricatorPlatformSite()); $viewer = PhabricatorUser::getOmnipotentUser(); $application_configuration = CreateApplicationConfiguration(); $application = id(new PhabricatorDifferentialApplication()); $revision_controller = id(new DifferentialRevisionViewController()) ->setCurrentApplication($application); $routing_map = id(new AphrontRoutingMap()) ->setSite($site) ->setApplication($application) ->setRoutes($application->getRoutes()); $conduit = id(new ConduitClient('https://developer.blender.org/api/')) ->setConduitToken(trim(file_get_contents($CONDUIT_TOKEN_FILE))); ///////////////////////////////////////////////////////////////////////////////// // Baking logic and loop. function EnsureDirectoryOrDie($dir) { if (!is_dir($dir)) { if (!mkdir($dir, 0777, true)) { print("Error creating output durectory $dir\n"); die; } } } function EnsureOutputDirectoryOrDie() { global $OUTPUT_DIR; EnsureDirectoryOrDie($OUTPUT_DIR); } function MakeGenericOutputDirectory($subject) { global $OUTPUT_DIR; $dir = $OUTPUT_DIR . DIRECTORY_SEPARATOR . $subject; EnsureDirectoryOrDie($dir); return $dir; } function MakeRevisionBaseOutputFileName($revision, $diff_id, $subject) { $dir = MakeGenericOutputDirectory($subject); $file_name = $dir . DIRECTORY_SEPARATOR . 'D' . $revision->getID(); if (!is_null($diff_id)) { $file_name .= '.' . $diff_id; } return $file_name; } function MakeRevisionHTMLOutputFileName($revision, $diff_id) { return MakeRevisionBaseOutputFileName( $revision, $diff_id, 'revision') . '.html'; } function MakeRawDiffOutputFileName($revision, $diff_id) { return MakeRevisionBaseOutputFileName( $revision, $diff_id, 'raw_diff') . '.diff'; } function MakePasteOutputFileNameFromHandle($handle) { return MakeGenericOutputDirectory('paste') . DIRECTORY_SEPARATOR . $handle->getName() . '.txt'; } function MakeFileOutputFileNameFromFile($file) { $dir = MakeGenericOutputDirectory('file'); $id = $file->getID(); EnsureDirectoryOrDie($dir . DIRECTORY_SEPARATOR . 'F' . $id); return $dir. DIRECTORY_SEPARATOR . $file->getSafeFileNameForBake(); } function BakeDifferentialToResponse($revision, $diff_id = NULL) { global $application_configuration; global $revision_controller; global $routing_map; global $viewer; $revision_id = $revision->getID(); if (is_null($diff_id)) { printf('Baking D' . $revision_id . ' ...' . "\n"); } else { printf('Baking D' . $revision_id . ', diff ' . $diff_id . ' ...' . "\n"); } $path = '/D' . $revision_id; $route_result = $routing_map->routePath($path); $uri_data = $route_result->getURIData(); $application_configuration->setPath($path); $request_data = array( ); if (!is_null($diff_id)) { $request_data['id'] = $diff_id; } $request = $application_configuration->buildRequest() ->setUser($viewer) ->setRequestData($request_data) ->setURIMap($uri_data); $response = id($revision_controller) ->setRequest($request) ->handleRequest($request); return $response; } function BakeResponseToHTML($response) { $html = ''; foreach ($response->renderChildren() as $child) { $html .= $child->render(); } return $html; } function StorePasteHandle($handle) { global $viewer; $file_name = MakePasteOutputFileNameFromHandle($handle); if (file_exists($file_name)) { return; } $paste = id(new PhabricatorPasteQuery()) ->setViewer($viewer) ->withPHIDs(array($handle->getPHID())) ->needRawContent(true) ->executeOne(); file_put_contents($file_name, $paste->getRawContent()); } function StoreFile($file) { print("Loading and storing file F{$file->getID()}\n"); $file_name = MakeFileOutputFileNameFromFile($file); file_put_contents($file_name, $file->loadFileData()); } function StoreFileHandle($handle) { global $viewer; $file = id(new PhabricatorFileQuery()) ->setViewer($viewer) ->withPHIDs(array($handle->getPHID())) ->needTransforms( array( PhabricatorFileThumbnailTransform::TRANSFORM_PREVIEW, )) ->executeOne(); $file_name = MakeFileOutputFileNameFromFile($file); if (file_exists($file_name)) { return; } StoreFile($file); $preview_xform = $file->getTransform(PhabricatorFileThumbnailTransform::TRANSFORM_PREVIEW); if ($preview_xform) { StoreFile($preview_xform); } } function StoreResponseAttachments($response) { $user = $response->getRequest()->getUser(); $handlePool = $user->getHandlePool(); $handles = $handlePool->getHandles(); foreach ($handles as $phid => $handle) { $type = $handle->getType(); if ($type == PhabricatorPastePastePHIDType::TYPECONST) { StorePasteHandle($handle); } else if ($type == PhabricatorFileFilePHIDType::TYPECONST) { StoreFileHandle($handle); } else { // print("$type\n"); } } } function StoreRawDiff($revision, $diff_id) { if (is_null($diff_id)) { return; } global $viewer; global $conduit; $output_file = MakeRawDiffOutputFileName($revision, $diff_id); if (file_exists($output_file)) { return; } print("Requesting and storing the raw diff ...\n"); $diff = id(new DifferentialDiffQuery()) ->setViewer($viewer) ->withIDs(array($diff_id)) ->needChangesets(true) ->executeOne(); $raw_changes = $diff->buildChangesList(); $changes = array(); foreach ($raw_changes as $changedict) { $changes[] = ArcanistDiffChange::newFromDictionary($changedict); } $bundle = ArcanistBundle::newFromChanges($changes); $bundle->setConduit($conduit); $raw_diff = $bundle->toGitPatch(); file_put_contents($output_file, $raw_diff); } function BakeDifferentialToFile($revision, $diff_id = NULL) { $response = BakeDifferentialToResponse($revision, $diff_id); $html = BakeResponseToHTML($response); $output_file = MakeRevisionHTMLOutputFileName($revision, $diff_id); file_put_contents($output_file, $html); file_put_contents($output_file . '.title', $response->getTitle()); StoreResponseAttachments($response); StoreRawDiff($revision, $diff_id); } EnsureOutputDirectoryOrDie(); print('Querying differential revisions from the database ... ' . "\n"); $revisions = id(new DifferentialRevisionQuery()) ->setViewer($viewer) ->needDiffIDs(true) ->setOrder('oldest') ->execute(); foreach ($revisions as $revision_id => $revision) { BakeDifferentialToFile($revision); foreach ($revision->getDiffIDs() as $diff_id) { BakeDifferentialToFile($revision, $diff_id); } } ?>