示例#1
0
/**
 * NOTE: This is an ADVANCED feature that improves performance but adds a lot
 * of complexity! This is only suitable for production servers because workers
 * won't pick up changes between when they spawn and when they handle a request.
 *
 * Phabricator spends a significant portion of its runtime loading classes
 * and functions, even with APC enabled. Since we have very rigidly-defined
 * rules about what can go in a module (specifically: no side effects), it
 * is safe to load all the libraries *before* we receive a request.
 *
 * Normally, SAPIs don't provide a way to do this, but with a patched PHP-FPM
 * SAPI you can provide a warmup file that it will execute before a request
 * is received.
 *
 * We're limited in what we can do here, since request information won't
 * exist yet, but we can load class and function definitions, which is what
 * we're really interested in.
 *
 * Once this file exists, the FCGI process will drop into its normal accept loop
 * and eventually process a request.
 */
function __warmup__()
{
    $root = dirname(dirname(dirname(dirname(__FILE__))));
    require_once $root . '/libphutil/src/__phutil_library_init__.php';
    require_once $root . '/arcanist/src/__phutil_library_init__.php';
    require_once $root . '/phabricator/src/__phutil_library_init__.php';
    // Load every symbol. We could possibly refine this -- we don't need to load
    // every Controller, for instance.
    $loader = new PhutilSymbolLoader();
    $loader->selectAndLoadSymbols();
    define('__WARMUP__', true);
}
 public function registerLibrary($name, $path)
 {
     if (basename($path) != '__phutil_library_init__.php') {
         throw new PhutilBootloaderException('Only directories with a __phutil_library_init__.php file may be ' . 'registered as libphutil libraries.');
     }
     $path = dirname($path);
     // Detect attempts to load the same library multiple times from different
     // locations. This might mean you're doing something silly like trying to
     // include two different versions of something, or it might mean you're
     // doing something subtle like running a different version of 'arc' on a
     // working copy of Arcanist.
     if (isset($this->registeredLibraries[$name])) {
         $old_path = $this->registeredLibraries[$name];
         if ($old_path != $path) {
             throw new PhutilLibraryConflictException($name, $old_path, $path);
         }
     }
     $this->registeredLibraries[$name] = $path;
     // For libphutil v2 libraries, load all functions when we load the library.
     if (!class_exists('PhutilSymbolLoader', false)) {
         $root = $this->getLibraryRoot('phutil');
         $this->executeInclude($root . '/symbols/PhutilSymbolLoader.php');
     }
     $loader = new PhutilSymbolLoader();
     $loader->setLibrary($name)->setType('function');
     try {
         $loader->selectAndLoadSymbols();
     } catch (PhutilBootloaderException $ex) {
         // Ignore this, it happens if a global function's file is removed or
         // similar. Worst case is that we fatal when calling the function, which
         // is no worse than fataling here.
     } catch (PhutilMissingSymbolException $ex) {
         // Ignore this, it happens if a global function is removed. Everything
         // else loaded so proceed forward: worst case is a fatal when we
         // hit a function call to a function which no longer exists, which is
         // no worse than fataling here.
     }
     if (empty($_SERVER['PHUTIL_DISABLE_RUNTIME_EXTENSIONS'])) {
         $extdir = $path . DIRECTORY_SEPARATOR . 'extensions';
         if (Filesystem::pathExists($extdir)) {
             $extensions = id(new FileFinder($extdir))->withSuffix('php')->withType('f')->withFollowSymlinks(true)->setForceMode('php')->find();
             foreach ($extensions as $extension) {
                 $this->loadExtension($name, $path, $extdir . DIRECTORY_SEPARATOR . $extension);
             }
         }
     }
     return $this;
 }
 public final function buildController()
 {
     $map = $this->getURIMap();
     $mapper = new AphrontURIMapper($map);
     $request = $this->getRequest();
     $path = $request->getPath();
     list($controller_class, $uri_data) = $mapper->mapPath($path);
     if (!$controller_class) {
         if (!preg_match('@/$@', $path)) {
             // If we failed to match anything but don't have a trailing slash, try
             // to add a trailing slash and issue a redirect if that resolves.
             list($controller_class, $uri_data) = $mapper->mapPath($path . '/');
             // NOTE: For POST, just 404 instead of redirecting, since the redirect
             // will be a GET without parameters.
             if ($controller_class && !$request->isHTTPPost()) {
                 $uri = $request->getRequestURI()->setPath($path . '/');
                 return $this->buildRedirectController($uri);
             }
         }
         return $this->build404Controller();
     }
     PhutilSymbolLoader::loadClass($controller_class);
     $controller = newv($controller_class, array($request));
     return array($controller, $uri_data);
 }
 protected final function updateCommitData($author, $message)
 {
     $commit = $this->commit;
     $data = id(new PhabricatorRepositoryCommitData())->loadOneWhere('commitID = %d', $commit->getID());
     if (!$data) {
         $data = new PhabricatorRepositoryCommitData();
     }
     $data->setCommitID($commit->getID());
     $data->setAuthorName($author);
     $data->setCommitMessage($message);
     $repository = $this->repository;
     $detail_parser = $repository->getDetail('detail-parser', 'PhabricatorRepositoryDefaultCommitMessageDetailParser');
     if ($detail_parser) {
         PhutilSymbolLoader::loadClass($detail_parser);
         $parser_obj = newv($detail_parser, array($commit, $data));
         $parser_obj->parseCommitDetails();
     }
     $data->save();
     $revision_id = $data->getCommitDetail('differential.revisionID');
     if ($revision_id) {
         $revision = id(new DifferentialRevision())->load($revision_id);
         if ($revision) {
             queryfx($revision->establishConnection('w'), 'INSERT IGNORE INTO %T (revisionID, commitPHID) VALUES (%d, %s)', DifferentialRevision::TABLE_COMMIT, $revision->getID(), $commit->getPHID());
             if ($revision->getStatus() != DifferentialRevisionStatus::COMMITTED) {
                 $editor = new DifferentialCommentEditor($revision, $revision->getAuthorPHID(), DifferentialAction::ACTION_COMMIT);
                 $editor->save();
             }
         }
     }
 }
 public function establishLiveConnection($mode)
 {
     $conf_provider = PhabricatorEnv::getEnvConfig('mysql.configuration_provider', 'DatabaseConfigurationProvider');
     PhutilSymbolLoader::loadClass($conf_provider);
     $conf = newv($conf_provider, array($this, $mode));
     return new AphrontMySQLDatabaseConnection(array('user' => $conf->getUser(), 'pass' => $conf->getPassword(), 'host' => $conf->getHost(), 'database' => $conf->getDatabase()));
 }
 public static function getConfiguration()
 {
     // Get DB info. Note that we are using a dummy PhabricatorUser object in
     // creating the DatabaseConfigurationProvider, which is not used at all.
     $conf_provider = PhabricatorEnv::getEnvConfig('mysql.configuration_provider', 'DatabaseConfigurationProvider');
     PhutilSymbolLoader::loadClass($conf_provider);
     $conf = newv($conf_provider, array(new PhabricatorUser(), 'r'));
     return $conf;
 }
 protected final function updateCommitData($author, $message)
 {
     $commit = $this->commit;
     $data = id(new PhabricatorRepositoryCommitData())->loadOneWhere('commitID = %d', $commit->getID());
     if (!$data) {
         $data = new PhabricatorRepositoryCommitData();
     }
     $data->setCommitID($commit->getID());
     $data->setAuthorName($author);
     $data->setCommitMessage($message);
     $repository = $this->repository;
     $detail_parser = $repository->getDetail('detail-parser', 'PhabricatorRepositoryDefaultCommitMessageDetailParser');
     if ($detail_parser) {
         PhutilSymbolLoader::loadClass($detail_parser);
         $parser_obj = newv($detail_parser, array($commit, $data));
         $parser_obj->parseCommitDetails();
     }
     $data->save();
     $conn_w = id(new DifferentialRevision())->establishConnection('w');
     // NOTE: The `differential_commit` table has a unique ID on `commitPHID`,
     // preventing more than one revision from being associated with a commit.
     // Generally this is good and desirable, but with the advent of hash
     // tracking we may end up in a situation where we match several different
     // revisions. We just kind of ignore this and pick one, we might want to
     // revisit this and do something differently. (If we match several revisions
     // someone probably did something very silly, though.)
     $revision_id = $data->getCommitDetail('differential.revisionID');
     if (!$revision_id) {
         $hashes = $this->getCommitHashes($this->repository, $this->commit);
         if ($hashes) {
             $query = new DifferentialRevisionQuery();
             $query->withCommitHashes($hashes);
             $revisions = $query->execute();
             if (!empty($revisions)) {
                 $revision = $this->identifyBestRevision($revisions);
                 $revision_id = $revision->getID();
             }
         }
     }
     if ($revision_id) {
         $revision = id(new DifferentialRevision())->load($revision_id);
         if ($revision) {
             queryfx($conn_w, 'INSERT IGNORE INTO %T (revisionID, commitPHID) VALUES (%d, %s)', DifferentialRevision::TABLE_COMMIT, $revision->getID(), $commit->getPHID());
             if ($revision->getStatus() != DifferentialRevisionStatus::COMMITTED) {
                 $message = null;
                 $committer = $data->getCommitDetail('authorPHID');
                 if (!$committer) {
                     $committer = $revision->getAuthorPHID();
                     $message = 'Change committed by ' . $data->getAuthorName() . '.';
                 }
                 $editor = new DifferentialCommentEditor($revision, $committer, DifferentialAction::ACTION_COMMIT);
                 $editor->setMessage($message)->save();
             }
         }
     }
 }
function __phutil_autoload($class_name)
{
    // Occurs in PHP 5.2 with `call_user_func(array($this, 'self::f'))`.
    if ($class_name === 'self' || $class_name === 'parent') {
        return;
    }
    try {
        $loader = new PhutilSymbolLoader();
        $symbols = $loader->setType('class')->setName($class_name)->selectAndLoadSymbols();
        if (!$symbols) {
            throw new PhutilMissingSymbolException($class_name, pht('class or interface'), pht("the class or interface '%s' is not defined in the library " . "map for any loaded %s library.", $class_name, 'phutil'));
        }
    } catch (PhutilMissingSymbolException $ex) {
        $should_throw = true;
        foreach (debug_backtrace() as $backtrace) {
            if (empty($backtrace['function'])) {
                continue;
            }
            switch ($backtrace['function']) {
                case 'class_exists':
                case 'interface_exists':
                case 'method_exists':
                case 'property_exists':
                case 'trait_exists':
                    $should_throw = false;
                    break;
            }
        }
        if (!$should_throw) {
            return false;
        }
        // If there are other SPL autoloaders installed, we need to give them a
        // chance to load the class. Throw the exception if we're the last
        // autoloader; if not, swallow it and let them take a shot.
        $autoloaders = spl_autoload_functions();
        $last = end($autoloaders);
        if ($last == __FUNCTION__) {
            throw $ex;
        }
    }
}
 public static function stopProfiler()
 {
     if (self::$profilerStarted) {
         $data = xhprof_disable();
         $data = serialize($data);
         $file_class = 'PhabricatorFile';
         PhutilSymbolLoader::loadClass($file_class);
         $file = call_user_func(array($file_class, 'newFromFileData'), $data, array('mime-type' => 'application/xhprof', 'name' => 'profile.xhprof'));
         return $file->getPHID();
     } else {
         return null;
     }
 }
function __phutil_autoload($class_name)
{
    // Occurs in PHP 5.2 with `call_user_func(array($this, 'self::f'))`.
    if ($class_name === 'self' || $class_name === 'parent') {
        return;
    }
    try {
        $loader = new PhutilSymbolLoader();
        $symbols = $loader->setType('class')->setName($class_name)->selectAndLoadSymbols();
        if (!$symbols) {
            throw new PhutilMissingSymbolException($class_name, 'class or interface', "the class or interface '{$class_name}' is not defined in the library " . "map for any loaded phutil library.");
        }
    } catch (PhutilMissingSymbolException $ex) {
        // If there are other SPL autoloaders installed, we need to give them a
        // chance to load the class. Throw the exception if we're the last
        // autoloader; if not, swallow it and let them take a shot.
        $autoloaders = spl_autoload_functions();
        $last = end($autoloaders);
        if ($last == __FUNCTION__) {
            throw $ex;
        }
    }
}
 public static function stopProfiler()
 {
     if (self::$profilerStarted) {
         $data = xhprof_disable();
         $data = serialize($data);
         $file_class = 'PhabricatorFile';
         PhutilSymbolLoader::loadClass($file_class);
         // Since these happen on GET we can't do guarded writes.
         $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
         $file = call_user_func(array($file_class, 'newFromFileData'), $data, array('mime-type' => 'application/xhprof', 'name' => 'profile.xhprof'));
         return $file->getPHID();
     } else {
         return null;
     }
 }
 public static final function newFromDiffusionRequest(DiffusionRequest $request)
 {
     $repository = $request->getRepository();
     switch ($repository->getVersionControlSystem()) {
         case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
             $class = 'DiffusionGitBranchQuery';
             break;
         default:
             throw new Exception("Unsupported VCS!");
     }
     PhutilSymbolLoader::loadClass($class);
     $query = new $class();
     $query->request = $request;
     return $query;
 }
 public static function newProvider($which)
 {
     switch ($which) {
         case self::PROVIDER_FACEBOOK:
             $class = 'PhabricatorOAuthProviderFacebook';
             break;
         case self::PROVIDER_GITHUB:
             $class = 'PhabricatorOAuthProviderGithub';
             break;
         default:
             throw new Exception('Unknown OAuth provider.');
     }
     PhutilSymbolLoader::loadClass($class);
     return newv($class, array());
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $task_phid = $request->getValue('task_phid');
     $orig_rev_phids = $request->getValue('orig_rev_phids');
     if (empty($orig_rev_phids)) {
         $orig_rev_phids = array();
     }
     $new_rev_phids = $request->getValue('new_rev_phids');
     if (empty($new_rev_phids)) {
         $new_rev_phids = array();
     }
     $task_class = PhabricatorEnv::getEnvConfig('differential.attach-task-class');
     if (!$task_class) {
         throw new ConduitException('ERR_NO_TASKATTACHER_DEFINED');
     }
     PhutilSymbolLoader::loadClass($task_class);
     $task_attacher = newv($task_class, array());
     $task_attacher->updateTaskRevisionAssoc($task_phid, $orig_rev_phids, $new_rev_phids);
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $methods = $this->getAllMethods();
     if (empty($methods[$this->method])) {
         $this->method = key($methods);
     }
     $method_class = $methods[$this->method];
     PhutilSymbolLoader::loadClass($method_class);
     $method_object = newv($method_class, array());
     $error_description = array();
     $error_types = $method_object->defineErrorTypes();
     if ($error_types) {
         $error_description[] = '<ul>';
         foreach ($error_types as $error => $meaning) {
             $error_description[] = '<li>' . '<strong>' . phutil_escape_html($error) . ':</strong> ' . phutil_escape_html($meaning) . '</li>';
         }
         $error_description[] = '</ul>';
         $error_description = implode("\n", $error_description);
     } else {
         $error_description = "This method does not raise any specific errors.";
     }
     $form = new AphrontFormView();
     $form->setUser($request->getUser())->setAction('/api/' . $this->method)->appendChild(id(new AphrontFormStaticControl())->setLabel('Description')->setValue($method_object->getMethodDescription()))->appendChild(id(new AphrontFormStaticControl())->setLabel('Returns')->setValue($method_object->defineReturnType()))->appendChild(id(new AphrontFormMarkupControl())->setLabel('Errors')->setValue($error_description))->appendChild('<p class="aphront-form-instructions">Enter parameters using ' . '<strong>JSON</strong>. For instance, to enter a list, type: ' . '<tt>["apple", "banana", "cherry"]</tt>');
     $params = $method_object->defineParamTypes();
     foreach ($params as $param => $desc) {
         $form->appendChild(id(new AphrontFormTextControl())->setLabel($param)->setName("params[{$param}]")->setCaption(phutil_escape_html($desc)));
     }
     $form->appendChild(id(new AphrontFormSelectControl())->setLabel('Output Format')->setName('output')->setOptions(array('human' => 'Human Readable', 'json' => 'JSON')))->appendChild(id(new AphrontFormSubmitControl())->setValue('Call Method'));
     $panel = new AphrontPanelView();
     $panel->setHeader('Conduit API: ' . phutil_escape_html($this->method));
     $panel->appendChild($form);
     $panel->setWidth(AphrontPanelView::WIDTH_WIDE);
     $view = new AphrontSideNavView();
     foreach ($this->buildNavItems() as $item) {
         $view->addNavItem($item);
     }
     $view->appendChild($panel);
     return $this->buildStandardPageResponse(array($view), array('title' => 'Conduit Console', 'tab' => 'console'));
 }
 public static final function newFromDiffusionRequest(DiffusionRequest $request)
 {
     $repository = $request->getRepository();
     switch ($repository->getVersionControlSystem()) {
         case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
             // TODO: Verify local-path?
             $class = 'DiffusionGitBrowseQuery';
             break;
         case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
             $class = 'DiffusionMercurialBrowseQuery';
             break;
         case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
             $class = 'DiffusionSvnBrowseQuery';
             break;
         default:
             throw new Exception("Unsupported VCS!");
     }
     PhutilSymbolLoader::loadClass($class);
     $query = new $class();
     $query->request = $request;
     return $query;
 }
 public final function buildController()
 {
     $map = $this->getURIMap();
     $mapper = new AphrontURIMapper($map);
     $request = $this->getRequest();
     $path = $request->getPath();
     list($controller_class, $uri_data) = $mapper->mapPath($path);
     if (!$controller_class) {
         if (!preg_match('@/$@', $path)) {
             // If we failed to match anything but don't have a trailing slash, try
             // to add a trailing slash and issue a redirect if that resolves.
             list($controller_class, $uri_data) = $mapper->mapPath($path . '/');
             if ($controller_class) {
                 return $this->buildRedirectController($path . '/');
             }
         }
         return $this->build404Controller();
     }
     PhutilSymbolLoader::loadClass($controller_class);
     $controller = newv($controller_class, array($request));
     return array($controller, $uri_data);
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $viewer_is_anonymous = !$user->isLoggedIn();
     $revision = id(new DifferentialRevision())->load($this->revisionID);
     if (!$revision) {
         return new Aphront404Response();
     }
     $revision->loadRelationships();
     $diffs = $revision->loadDiffs();
     if (!$diffs) {
         throw new Exception("This revision has no diffs. Something has gone quite wrong.");
     }
     $diff_vs = $request->getInt('vs');
     $target = end($diffs);
     $target_id = $request->getInt('id');
     if ($target_id) {
         if (isset($diffs[$target_id])) {
             $target = $diffs[$target_id];
         }
     }
     $diffs = mpull($diffs, null, 'getID');
     if (empty($diffs[$diff_vs])) {
         $diff_vs = null;
     }
     list($aux_fields, $props) = $this->loadAuxiliaryFieldsAndProperties($revision, $target, array('local:commits', 'arc:unit'));
     list($changesets, $vs_map, $rendering_references) = $this->loadChangesetsAndVsMap($diffs, $diff_vs, $target);
     $comments = $revision->loadComments();
     $comments = array_merge($this->getImplicitComments($revision), $comments);
     $all_changesets = $changesets;
     $inlines = $this->loadInlineComments($comments, $all_changesets);
     $object_phids = array_merge($revision->getReviewers(), $revision->getCCPHIDs(), $revision->loadCommitPHIDs(), array($revision->getAuthorPHID(), $user->getPHID()), mpull($comments, 'getAuthorPHID'));
     foreach ($comments as $comment) {
         $metadata = $comment->getMetadata();
         $added_reviewers = idx($metadata, DifferentialComment::METADATA_ADDED_REVIEWERS);
         if ($added_reviewers) {
             foreach ($added_reviewers as $phid) {
                 $object_phids[] = $phid;
             }
         }
         $added_ccs = idx($metadata, DifferentialComment::METADATA_ADDED_CCS);
         if ($added_ccs) {
             foreach ($added_ccs as $phid) {
                 $object_phids[] = $phid;
             }
         }
     }
     foreach ($revision->getAttached() as $type => $phids) {
         foreach ($phids as $phid => $info) {
             $object_phids[] = $phid;
         }
     }
     $aux_phids = array();
     foreach ($aux_fields as $key => $aux_field) {
         $aux_phids[$key] = $aux_field->getRequiredHandlePHIDsForRevisionView();
     }
     $object_phids = array_merge($object_phids, array_mergev($aux_phids));
     $object_phids = array_unique($object_phids);
     $handles = id(new PhabricatorObjectHandleData($object_phids))->loadHandles();
     foreach ($aux_fields as $key => $aux_field) {
         // Make sure each field only has access to handles it specifically
         // requested, not all handles. Otherwise you can get a field which works
         // only in the presence of other fields.
         $aux_field->setHandles(array_select_keys($handles, $aux_phids[$key]));
     }
     $reviewer_warning = null;
     $has_live_reviewer = false;
     foreach ($revision->getReviewers() as $reviewer) {
         if (!$handles[$reviewer]->isDisabled()) {
             $has_live_reviewer = true;
         }
     }
     if (!$has_live_reviewer) {
         $reviewer_warning = new AphrontErrorView();
         $reviewer_warning->setSeverity(AphrontErrorView::SEVERITY_WARNING);
         $reviewer_warning->setTitle('No Active Reviewers');
         if ($revision->getReviewers()) {
             $reviewer_warning->appendChild('<p>All specified reviewers are disabled. You may want to add ' . 'some new reviewers.</p>');
         } else {
             $reviewer_warning->appendChild('<p>This revision has no specified reviewers. You may want to ' . 'add some.</p>');
         }
     }
     $request_uri = $request->getRequestURI();
     $limit = 100;
     $large = $request->getStr('large');
     if (count($changesets) > $limit && !$large) {
         $count = number_format(count($changesets));
         $warning = new AphrontErrorView();
         $warning->setTitle('Very Large Diff');
         $warning->setSeverity(AphrontErrorView::SEVERITY_WARNING);
         $warning->setWidth(AphrontErrorView::WIDTH_WIDE);
         $warning->appendChild("<p>This diff is very large and affects {$count} files. Use " . "Table of Contents to open files in a standalone view. " . "<strong>" . phutil_render_tag('a', array('href' => $request_uri->alter('large', 'true')->setFragment('differential-review-toc')), 'Show All Files Inline') . "</strong>");
         $warning = $warning->render();
         $visible_changesets = array();
     } else {
         $warning = null;
         $visible_changesets = $changesets;
     }
     $revision_detail = new DifferentialRevisionDetailView();
     $revision_detail->setRevision($revision);
     $revision_detail->setAuxiliaryFields($aux_fields);
     $actions = $this->getRevisionActions($revision);
     $custom_renderer_class = PhabricatorEnv::getEnvConfig('differential.revision-custom-detail-renderer');
     if ($custom_renderer_class) {
         // TODO: build a better version of the action links and deprecate the
         // whole DifferentialRevisionDetailRenderer class.
         PhutilSymbolLoader::loadClass($custom_renderer_class);
         $custom_renderer = newv($custom_renderer_class, array());
         $actions = array_merge($actions, $custom_renderer->generateActionLinks($revision, $target));
     }
     $whitespace = $request->getStr('whitespace', DifferentialChangesetParser::WHITESPACE_IGNORE_ALL);
     $arc_project = $target->loadArcanistProject();
     if ($arc_project) {
         $symbol_indexes = $this->buildSymbolIndexes($target, $arc_project, $visible_changesets);
         $repository = $arc_project->loadRepository();
     } else {
         $symbol_indexes = array();
         $repository = null;
     }
     $revision_detail->setActions($actions);
     $revision_detail->setUser($user);
     $comment_view = new DifferentialRevisionCommentListView();
     $comment_view->setComments($comments);
     $comment_view->setHandles($handles);
     $comment_view->setInlineComments($inlines);
     $comment_view->setChangesets($all_changesets);
     $comment_view->setUser($user);
     $comment_view->setTargetDiff($target);
     $comment_view->setVersusDiffID($diff_vs);
     $changeset_view = new DifferentialChangesetListView();
     $changeset_view->setChangesets($visible_changesets);
     if (!$viewer_is_anonymous) {
         $changeset_view->setInlineCommentControllerURI('/differential/comment/inline/edit/' . $revision->getID() . '/');
     }
     $changeset_view->setStandaloneURI('/differential/changeset/');
     $changeset_view->setRawFileURIs('/differential/changeset/?view=old', '/differential/changeset/?view=new');
     $changeset_view->setUser($user);
     $changeset_view->setDiff($target);
     $changeset_view->setRenderingReferences($rendering_references);
     $changeset_view->setVsMap($vs_map);
     $changeset_view->setWhitespace($whitespace);
     if ($repository) {
         $changeset_view->setRepository($repository, $target);
     }
     $changeset_view->setSymbolIndexes($symbol_indexes);
     $diff_history = new DifferentialRevisionUpdateHistoryView();
     $diff_history->setDiffs($diffs);
     $diff_history->setSelectedVersusDiffID($diff_vs);
     $diff_history->setSelectedDiffID($target->getID());
     $diff_history->setSelectedWhitespace($whitespace);
     $diff_history->setUser($user);
     $local_view = new DifferentialLocalCommitsView();
     $local_view->setUser($user);
     $local_view->setLocalCommits(idx($props, 'local:commits'));
     if ($repository) {
         $other_revisions = $this->loadOtherRevisions($changesets, $target, $repository);
     } else {
         $other_revisions = array();
     }
     $other_view = null;
     if ($other_revisions) {
         $other_view = $this->renderOtherRevisions($other_revisions);
     }
     $toc_view = new DifferentialDiffTableOfContentsView();
     $toc_view->setChangesets($changesets);
     $toc_view->setVisibleChangesets($visible_changesets);
     $toc_view->setUnitTestData(idx($props, 'arc:unit', array()));
     if ($repository) {
         $toc_view->setRepository($repository);
     }
     $toc_view->setDiff($target);
     $toc_view->setUser($user);
     $toc_view->setStandaloneViewLink(empty($visible_changesets));
     $toc_view->setVsMap($vs_map);
     $toc_view->setRevisionID($revision->getID());
     $toc_view->setWhitespace($whitespace);
     if (!$viewer_is_anonymous) {
         $draft = id(new PhabricatorDraft())->loadOneWhere('authorPHID = %s AND draftKey = %s', $user->getPHID(), 'differential-comment-' . $revision->getID());
         if ($draft) {
             $draft = $draft->getDraft();
         } else {
             $draft = null;
         }
         $comment_form = new DifferentialAddCommentView();
         $comment_form->setRevision($revision);
         $comment_form->setActions($this->getRevisionCommentActions($revision));
         $comment_form->setActionURI('/differential/comment/save/');
         $comment_form->setUser($user);
         $comment_form->setDraft($draft);
     }
     $pane_id = celerity_generate_unique_node_id();
     Javelin::initBehavior('differential-keyboard-navigation', array('haunt' => $pane_id));
     $page_pane = id(new DifferentialPrimaryPaneView())->setLineWidthFromChangesets($changesets)->setID($pane_id)->appendChild($comment_view->render() . $diff_history->render() . $warning . $local_view->render() . $toc_view->render() . $other_view . $changeset_view->render());
     if ($comment_form) {
         $page_pane->appendChild($comment_form->render());
     }
     return $this->buildStandardPageResponse(array($reviewer_warning, $revision_detail, $page_pane), array('title' => 'D' . $revision->getID() . ' ' . $revision->getTitle()));
 }
 protected function loadAvailableDaemonClasses()
 {
     $loader = new PhutilSymbolLoader();
     return $loader->setAncestorClass('PhutilDaemon')->setConcreteOnly(true)->selectSymbolsWithoutLoading();
 }
示例#20
0
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
$root = dirname(dirname(dirname(__FILE__)));
require_once $root . '/scripts/__init_script__.php';
phutil_require_module('phutil', 'symbols');
PhutilSymbolLoader::loadClass('PhabricatorRepository');
PhutilSymbolLoader::loadClass('PhabricatorRepositoryCommit');
$commit = new PhabricatorRepositoryCommit();
$conn_w = id(new PhabricatorRepository())->establishConnection('w');
$sizes = queryfx_all($conn_w, 'SELECT repositoryID, count(*) N FROM %T GROUP BY repositoryID', $commit->getTableName());
$sizes = ipull($sizes, 'N', 'repositoryID');
$maxes = queryfx_all($conn_w, 'SELECT repositoryID, max(epoch) maxEpoch FROM %T GROUP BY repositoryID', $commit->getTableName());
$maxes = ipull($maxes, 'maxEpoch', 'repositoryID');
$repository_ids = array_keys($sizes + $maxes);
echo "Updating " . count($repository_ids) . " repositories";
foreach ($repository_ids as $repository_id) {
    $last_commit = queryfx_one($conn_w, 'SELECT id FROM %T WHERE repositoryID = %d AND epoch = %d LIMIT 1', $commit->getTableName(), $repository_id, idx($maxes, $repository_id, 0));
    if ($last_commit) {
        $last_commit = $last_commit['id'];
    } else {
        $last_commit = 0;
    }
 public function loadHandles()
 {
     $types = array();
     foreach ($this->phids as $phid) {
         $type = $this->lookupType($phid);
         $types[$type][] = $phid;
     }
     $handles = array();
     $external_loaders = PhabricatorEnv::getEnvConfig('phid.external-loaders');
     foreach ($types as $type => $phids) {
         switch ($type) {
             case PhabricatorPHIDConstants::PHID_TYPE_MAGIC:
                 // Black magic!
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     switch ($phid) {
                         case ManiphestTaskOwner::OWNER_UP_FOR_GRABS:
                             $handle->setName('Up For Grabs');
                             $handle->setFullName('upforgrabs (Up For Grabs)');
                             break;
                         default:
                             $handle->setName('Foul Magicks');
                             break;
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_USER:
                 $class = 'PhabricatorUser';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $users = $object->loadAllWhere('phid IN (%Ls)', $phids);
                 $users = mpull($users, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($users[$phid])) {
                         $handle->setName('Unknown User');
                     } else {
                         $user = $users[$phid];
                         $handle->setName($user->getUsername());
                         $handle->setURI('/p/' . $user->getUsername() . '/');
                         $handle->setEmail($user->getEmail());
                         $handle->setFullName($user->getUsername() . ' (' . $user->getRealName() . ')');
                         $handle->setAlternateID($user->getID());
                         $img_phid = $user->getProfileImagePHID();
                         if ($img_phid) {
                             $handle->setImageURI(PhabricatorFileURI::getViewURIForPHID($img_phid));
                         }
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_MLST:
                 $class = 'PhabricatorMetaMTAMailingList';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $lists = $object->loadAllWhere('phid IN (%Ls)', $phids);
                 $lists = mpull($lists, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($lists[$phid])) {
                         $handle->setName('Unknown Mailing List');
                     } else {
                         $list = $lists[$phid];
                         $handle->setEmail($list->getEmail());
                         $handle->setName($list->getName());
                         $handle->setURI($list->getURI());
                         $handle->setFullName($list->getName());
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_DREV:
                 $class = 'DifferentialRevision';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $revs = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $revs = mpull($revs, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($revs[$phid])) {
                         $handle->setName('Unknown Revision');
                     } else {
                         $rev = $revs[$phid];
                         $handle->setName($rev->getTitle());
                         $handle->setURI('/D' . $rev->getID());
                         $handle->setFullName('D' . $rev->getID() . ': ' . $rev->getTitle());
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_CMIT:
                 $class = 'PhabricatorRepositoryCommit';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $commits = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $commits = mpull($commits, null, 'getPHID');
                 $repository_ids = mpull($commits, 'getRepositoryID');
                 $repositories = id(new PhabricatorRepository())->loadAllWhere('id in (%Ld)', array_unique($repository_ids));
                 $callsigns = mpull($repositories, 'getCallsign');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($commits[$phid]) || !isset($callsigns[$repository_ids[$phid]])) {
                         $handle->setName('Unknown Commit');
                     } else {
                         $commit = $commits[$phid];
                         $callsign = $callsigns[$repository_ids[$phid]];
                         $repository = $repositories[$repository_ids[$phid]];
                         $commit_identifier = $commit->getCommitIdentifier();
                         // In case where the repository for the commit was deleted,
                         // we don't have have info about the repository anymore.
                         if ($repository) {
                             $vcs = $repository->getVersionControlSystem();
                             if ($vcs == PhabricatorRepositoryType::REPOSITORY_TYPE_GIT) {
                                 $short_identifier = substr($commit_identifier, 0, 16);
                             } else {
                                 $short_identifier = $commit_identifier;
                             }
                             $handle->setName('r' . $callsign . $short_identifier);
                         } else {
                             $handle->setName('Commit ' . 'r' . $callsign . $commit_identifier);
                         }
                         $handle->setURI('/r' . $callsign . $commit_identifier);
                         $handle->setFullName('r' . $callsign . $commit_identifier);
                         $handle->setTimestamp($commit->getEpoch());
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_TASK:
                 $class = 'ManiphestTask';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $tasks = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $tasks = mpull($tasks, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($tasks[$phid])) {
                         $handle->setName('Unknown Revision');
                     } else {
                         $task = $tasks[$phid];
                         $handle->setName($task->getTitle());
                         $handle->setURI('/T' . $task->getID());
                         $handle->setFullName('T' . $task->getID() . ': ' . $task->getTitle());
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_FILE:
                 $class = 'PhabricatorFile';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $files = $object->loadAllWhere('phid IN (%Ls)', $phids);
                 $files = mpull($files, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($files[$phid])) {
                         $handle->setName('Unknown File');
                     } else {
                         $file = $files[$phid];
                         $handle->setName($file->getName());
                         $handle->setURI($file->getViewURI());
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_PROJ:
                 $class = 'PhabricatorProject';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $projects = $object->loadAllWhere('phid IN (%Ls)', $phids);
                 $projects = mpull($projects, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($projects[$phid])) {
                         $handle->setName('Unknown Project');
                     } else {
                         $project = $projects[$phid];
                         $handle->setName($project->getName());
                         $handle->setURI('/project/view/' . $project->getID() . '/');
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_REPO:
                 $class = 'PhabricatorRepository';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $repositories = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $repositories = mpull($repositories, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($repositories[$phid])) {
                         $handle->setName('Unknown Repository');
                     } else {
                         $repository = $repositories[$phid];
                         $handle->setName($repository->getCallsign());
                         $handle->setURI('/diffusion/' . $repository->getCallsign() . '/');
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_OPKG:
                 $class = 'PhabricatorOwnersPackage';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $packages = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $packages = mpull($packages, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($packages[$phid])) {
                         $handle->setName('Unknown Package');
                     } else {
                         $package = $packages[$phid];
                         $handle->setName($package->getName());
                         $handle->setURI('/owners/package/' . $package->getID() . '/');
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_APRJ:
                 $project_dao = newv('PhabricatorRepositoryArcanistProject', array());
                 $projects = $project_dao->loadAllWhere('phid IN (%Ls)', $phids);
                 $projects = mpull($projects, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($projects[$phid])) {
                         $handle->setName('Unknown Arcanist Project');
                     } else {
                         $project = $projects[$phid];
                         $handle->setName($project->getName());
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_WIKI:
                 $document_dao = newv('PhrictionDocument', array());
                 $content_dao = newv('PhrictionContent', array());
                 $conn = $document_dao->establishConnection('r');
                 $documents = queryfx_all($conn, 'SELECT * FROM %T document JOIN %T content
           ON document.contentID = content.id
           WHERE document.phid IN (%Ls)', $document_dao->getTableName(), $content_dao->getTableName(), $phids);
                 $documents = ipull($documents, null, 'phid');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($documents[$phid])) {
                         $handle->setName('Unknown Document');
                     } else {
                         $info = $documents[$phid];
                         $handle->setName($info['title']);
                         $handle->setURI(PhrictionDocument::getSlugURI($info['slug']));
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             default:
                 $loader = null;
                 if (isset($external_loaders[$type])) {
                     $loader = $external_loaders[$type];
                 } else {
                     if (isset($external_loaders['*'])) {
                         $loader = $external_loaders['*'];
                     }
                 }
                 if ($loader) {
                     PhutilSymbolLoader::loadClass($loader);
                     $object = newv($loader, array());
                     $handles += $object->loadHandles($phids);
                     break;
                 }
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setType($type);
                     $handle->setPHID($phid);
                     $handle->setName('Unknown Object');
                     $handle->setFullName('An Unknown Object');
                     $handles[$phid] = $handle;
                 }
                 break;
         }
     }
     return $handles;
 }
 public function buildDefaultMailer()
 {
     $class_name = PhabricatorEnv::getEnvConfig('metamta.mail-adapter');
     PhutilSymbolLoader::loadClass($class_name);
     return newv($class_name, array());
 }
 public function run()
 {
     $svnargs = $this->getArgument('svnargs');
     $repository = $svnargs[0];
     $transaction = $svnargs[1];
     list($commit_message) = execx('svnlook log --transaction %s %s', $transaction, $repository);
     if (strpos($commit_message, '@bypass-lint') !== false) {
         return 0;
     }
     // TODO: Do stuff with commit message.
     list($changed) = execx('svnlook changed --transaction %s %s', $transaction, $repository);
     $paths = array();
     $changed = explode("\n", trim($changed));
     foreach ($changed as $line) {
         $matches = null;
         preg_match('/^..\\s*(.*)$/', $line, $matches);
         $paths[$matches[1]] = strlen($matches[1]);
     }
     $resolved = array();
     $failed = array();
     $missing = array();
     $found = array();
     asort($paths);
     foreach ($paths as $path => $length) {
         foreach ($resolved as $rpath => $root) {
             if (!strncmp($path, $rpath, strlen($rpath))) {
                 $resolved[$path] = $root;
                 continue 2;
             }
         }
         $config = $path;
         if (basename($config) == '.arcconfig') {
             $resolved[$config] = $config;
             continue;
         }
         $config = rtrim($config, '/');
         $last_config = $config;
         do {
             if (!empty($missing[$config])) {
                 break;
             } else {
                 if (!empty($found[$config])) {
                     $resolved[$path] = $found[$config];
                     break;
                 }
             }
             list($err) = exec_manual('svnlook cat --transaction %s %s %s', $transaction, $repository, $config ? $config . '/.arcconfig' : '.arcconfig');
             if ($err) {
                 $missing[$path] = true;
             } else {
                 $resolved[$path] = $config ? $config . '/.arcconfig' : '.arcconfig';
                 $found[$config] = $resolved[$path];
                 break;
             }
             $config = dirname($config);
             if ($config == '.') {
                 $config = '';
             }
             if ($config == $last_config) {
                 break;
             }
             $last_config = $config;
         } while (true);
         if (empty($resolved[$path])) {
             $failed[] = $path;
         }
     }
     if ($failed && $resolved) {
         $failed_paths = '        ' . implode("\n        ", $failed);
         $resolved_paths = '        ' . implode("\n        ", array_keys($resolved));
         throw new ArcanistUsageException("This commit includes a mixture of files in Arcanist projects and " . "outside of Arcanist projects. A commit which affects an Arcanist " . "project must affect only that project.\n\n" . "Files in projects:\n\n" . $resolved_paths . "\n\n" . "Files not in projects:\n\n" . $failed_paths);
     }
     if (!$resolved) {
         // None of the affected paths are beneath a .arcconfig file.
         return 0;
     }
     $groups = array();
     foreach ($resolved as $path => $project) {
         $groups[$project][] = $path;
     }
     if (count($groups) > 1) {
         $message = array();
         foreach ($groups as $project => $group) {
             $message[] = "Files underneath '{$project}':\n\n";
             $message[] = "        " . implode("\n        ", $group) . "\n\n";
         }
         $message = implode('', $message);
         throw new ArcanistUsageException("This commit includes a mixture of files from different Arcanist " . "projects. A commit which affects an Arcanist project must affect " . "only that project.\n\n" . $message);
     }
     $config_file = key($groups);
     $project_root = dirname($config_file);
     $paths = reset($groups);
     list($config) = execx('svnlook cat --transaction %s %s %s', $transaction, $repository, $config_file);
     $working_copy = ArcanistWorkingCopyIdentity::newFromRootAndConfigFile($project_root, $config, $config_file . " (svnlook: {$transaction} {$repository})");
     $repository_api = new ArcanistSubversionHookAPI($project_root, $transaction, $repository);
     $lint_engine = $working_copy->getConfig('lint_engine');
     if (!$lint_engine) {
         return 0;
     }
     PhutilSymbolLoader::loadClass($lint_engine);
     $engine = newv($lint_engine, array());
     $engine->setWorkingCopy($working_copy);
     $engine->setMinimumSeverity(ArcanistLintSeverity::SEVERITY_ERROR);
     $engine->setPaths($paths);
     $engine->setCommitHookMode(true);
     $engine->setHookAPI($repository_api);
     try {
         $results = $engine->run();
     } catch (ArcanistNoEffectException $no_effect) {
         // Nothing to do, bail out.
         return 0;
     }
     $renderer = new ArcanistLintRenderer();
     $failures = array();
     foreach ($results as $result) {
         if (!$result->getMessages()) {
             continue;
         }
         $failures[] = $result;
     }
     if ($failures) {
         $at = "@";
         $msg = phutil_console_format("\n**LINT ERRORS**\n\n" . "This changeset has lint errors. You must fix all lint errors before " . "you can commit.\n\n" . "You can add '{$at}bypass-lint' to your commit message to disable " . "lint checks for this commit, or '{$at}nolint' to the file with " . "errors to disable lint for that file.\n\n");
         echo phutil_console_wrap($msg);
         foreach ($failures as $result) {
             echo $renderer->renderLintResult($result);
         }
         return 1;
     }
     return 0;
 }
 public function run()
 {
     $lease_ownership_name = $this->getLeaseOwnershipName();
     $task_table = new PhabricatorWorkerTask();
     $taskdata_table = new PhabricatorWorkerTaskData();
     $sleep = 0;
     do {
         $conn_w = $task_table->establishConnection('w');
         queryfx($conn_w, 'UPDATE %T SET leaseOwner = %s, leaseExpires = UNIX_TIMESTAMP() + 15
       WHERE leaseOwner IS NULL LIMIT 1', $task_table->getTableName(), $lease_ownership_name);
         $rows = $conn_w->getAffectedRows();
         if (!$rows) {
             $rows = queryfx($conn_w, 'UPDATE %T SET leaseOwner = %s, leaseExpires = UNIX_TIMESTAMP() + 15
         WHERE leaseExpires < UNIX_TIMESTAMP() LIMIT 1', $task_table->getTableName(), $lease_ownership_name);
             $rows = $conn_w->getAffectedRows();
         }
         if ($rows) {
             $data = queryfx_all($conn_w, 'SELECT task.*, taskdata.data _taskData, UNIX_TIMESTAMP() _serverTime
         FROM %T task LEFT JOIN %T taskdata
           ON taskdata.id = task.dataID
         WHERE leaseOwner = %s AND leaseExpires > UNIX_TIMESTAMP()
         LIMIT 1', $task_table->getTableName(), $taskdata_table->getTableName(), $lease_ownership_name);
             $tasks = $task_table->loadAllFromArray($data);
             $tasks = mpull($tasks, null, 'getID');
             $task_data = array();
             foreach ($data as $row) {
                 $tasks[$row['id']]->setServerTime($row['_serverTime']);
                 if ($row['_taskData']) {
                     $task_data[$row['id']] = json_decode($row['_taskData'], true);
                 } else {
                     $task_data[$row['id']] = null;
                 }
             }
             foreach ($tasks as $task) {
                 // TODO: We should detect if we acquired a task with an expired lease
                 // and log about it / bump up failure count.
                 // TODO: We should detect if we acquired a task with an excessive
                 // failure count and fail it permanently.
                 $data = idx($task_data, $task->getID());
                 $class = $task->getTaskClass();
                 try {
                     PhutilSymbolLoader::loadClass($class);
                     if (!is_subclass_of($class, 'PhabricatorWorker')) {
                         throw new Exception("Task class '{$class}' does not extend PhabricatorWorker.");
                     }
                     $worker = newv($class, array($data));
                     $lease = $worker->getRequiredLeaseTime();
                     if ($lease !== null) {
                         $task->setLeaseDuration($lease);
                     }
                     $worker->executeTask();
                     $task->delete();
                     if ($data !== null) {
                         queryfx($conn_w, 'DELETE FROM %T WHERE id = %d', $taskdata_table->getTableName(), $task->getDataID());
                     }
                 } catch (Exception $ex) {
                     $task->setFailureCount($task->getFailureCount() + 1);
                     $task->save();
                     throw $ex;
                 }
             }
             $sleep = 0;
         } else {
             $sleep = min($sleep + 1, 30);
         }
         $this->sleep($sleep);
     } while (true);
 }
示例#25
0
phutil_require_module('phutil', 'error');
PhutilErrorHandler::setErrorListener(array('DarkConsoleErrorLogPluginAPI', 'handleErrors'));
foreach (PhabricatorEnv::getEnvConfig('load-libraries') as $library) {
    phutil_load_library($library);
}
if (PhabricatorEnv::getEnvConfig('phabricator.setup')) {
    PhabricatorSetup::runSetup();
    return;
}
$host = $_SERVER['HTTP_HOST'];
$path = $_REQUEST['__path__'];
switch ($host) {
    default:
        $config_key = 'aphront.default-application-configuration-class';
        $config_class = PhabricatorEnv::getEnvConfig($config_key);
        PhutilSymbolLoader::loadClass($config_class);
        $application = newv($config_class, array());
        break;
}
$application->setHost($host);
$application->setPath($path);
$application->willBuildRequest();
$request = $application->buildRequest();
$application->setRequest($request);
list($controller, $uri_data) = $application->buildController();
try {
    $response = $controller->willBeginExecution();
    if (!$response) {
        $controller->willProcessRequest($uri_data);
        $response = $controller->processRequest();
    }
 public function processRequest()
 {
     $current_user = $this->getRequest()->getUser();
     $provider = $this->provider;
     if (!$provider->isProviderEnabled()) {
         return new Aphront400Response();
     }
     $provider_name = $provider->getProviderName();
     $provider_key = $provider->getProviderKey();
     $request = $this->getRequest();
     if ($request->getStr('error')) {
         $error_view = id(new PhabricatorOAuthFailureView())->setRequest($request);
         return $this->buildErrorResponse($error_view);
     }
     $error_response = $this->retrieveAccessToken($provider);
     if ($error_response) {
         return $error_response;
     }
     $userinfo_uri = new PhutilURI($provider->getUserInfoURI());
     $userinfo_uri->setQueryParams(array('access_token' => $this->accessToken));
     $user_json = @file_get_contents($userinfo_uri);
     $user_data = json_decode($user_json, true);
     $provider->setUserData($user_data);
     $provider->setAccessToken($this->accessToken);
     $user_id = $provider->retrieveUserID();
     $provider_key = $provider->getProviderKey();
     $oauth_info = $this->retrieveOAuthInfo($provider);
     if ($current_user->getPHID()) {
         if ($oauth_info->getID()) {
             if ($oauth_info->getUserID() != $current_user->getID()) {
                 $dialog = new AphrontDialogView();
                 $dialog->setUser($current_user);
                 $dialog->setTitle('Already Linked to Another Account');
                 $dialog->appendChild('<p>The ' . $provider_name . ' account you just authorized ' . 'is already linked to another Phabricator account. Before you can ' . 'associate your ' . $provider_name . ' account with this Phabriactor ' . 'account, you must unlink it from the Phabricator account it is ' . 'currently linked to.</p>');
                 $dialog->addCancelButton('/settings/page/' . $provider_key . '/');
                 return id(new AphrontDialogResponse())->setDialog($dialog);
             } else {
                 return id(new AphrontRedirectResponse())->setURI('/settings/page/' . $provider_key . '/');
             }
         }
         $existing_oauth = id(new PhabricatorUserOAuthInfo())->loadOneWhere('userID = %d AND oauthProvider = %s', $current_user->getID(), $provider_key);
         if ($existing_oauth) {
             $dialog = new AphrontDialogView();
             $dialog->setUser($current_user);
             $dialog->setTitle('Already Linked to an Account From This Provider');
             $dialog->appendChild('<p>The account you are logged in with is already linked to a ' . $provider_name . ' account. Before you can link it to a different ' . $provider_name . ' account, you must unlink the old account.</p>');
             $dialog->addCancelButton('/settings/page/' . $provider_key . '/');
             return id(new AphrontDialogResponse())->setDialog($dialog);
         }
         if (!$request->isDialogFormPost()) {
             $dialog = new AphrontDialogView();
             $dialog->setUser($current_user);
             $dialog->setTitle('Link ' . $provider_name . ' Account');
             $dialog->appendChild('<p>Link your ' . $provider_name . ' account to your Phabricator ' . 'account?</p>');
             $dialog->addHiddenInput('token', $provider->getAccessToken());
             $dialog->addHiddenInput('expires', $oauth_info->getTokenExpires());
             $dialog->addHiddenInput('state', $this->oauthState);
             $dialog->addSubmitButton('Link Accounts');
             $dialog->addCancelButton('/settings/page/' . $provider_key . '/');
             return id(new AphrontDialogResponse())->setDialog($dialog);
         }
         $oauth_info->setUserID($current_user->getID());
         $this->saveOAuthInfo($oauth_info);
         return id(new AphrontRedirectResponse())->setURI('/settings/page/' . $provider_key . '/');
     }
     $next_uri = $request->getCookie('next_uri', '/');
     // Login with known auth.
     if ($oauth_info->getID()) {
         $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
         $known_user = id(new PhabricatorUser())->load($oauth_info->getUserID());
         $request->getApplicationConfiguration()->willAuthenticateUserWithOAuth($known_user, $oauth_info, $provider);
         $session_key = $known_user->establishSession('web');
         $this->saveOAuthInfo($oauth_info);
         $request->setCookie('phusr', $known_user->getUsername());
         $request->setCookie('phsid', $session_key);
         $request->clearCookie('next_uri');
         return id(new AphrontRedirectResponse())->setURI($next_uri);
     }
     $oauth_email = $provider->retrieveUserEmail();
     if ($oauth_email) {
         $known_email = id(new PhabricatorUser())->loadOneWhere('email = %s', $oauth_email);
         if ($known_email) {
             $dialog = new AphrontDialogView();
             $dialog->setUser($current_user);
             $dialog->setTitle('Already Linked to Another Account');
             $dialog->appendChild('<p>The ' . $provider_name . ' account you just authorized has an ' . 'email address which is already in use by another Phabricator ' . 'account. To link the accounts, log in to your Phabricator ' . 'account and then go to Settings.</p>');
             $dialog->addCancelButton('/login/');
             return id(new AphrontDialogResponse())->setDialog($dialog);
         }
     }
     if (!$provider->isProviderRegistrationEnabled()) {
         $dialog = new AphrontDialogView();
         $dialog->setUser($current_user);
         $dialog->setTitle('No Account Registration With ' . $provider_name);
         $dialog->appendChild('<p>You can not register a new account using ' . $provider_name . '; ' . 'you can only use your ' . $provider_name . ' account to log into an ' . 'existing Phabricator account which you have registered through ' . 'other means.</p>');
         $dialog->addCancelButton('/login/');
         return id(new AphrontDialogResponse())->setDialog($dialog);
     }
     $class = PhabricatorEnv::getEnvConfig('controller.oauth-registration');
     PhutilSymbolLoader::loadClass($class);
     $controller = newv($class, array($this->getRequest()));
     $controller->setOAuthProvider($provider);
     $controller->setOAuthInfo($oauth_info);
     $controller->setOAuthState($this->oauthState);
     return $this->delegateToController($controller);
 }
示例#27
0
 public function run()
 {
     $bootloader = PhutilBootloader::getInstance();
     $affected_modules = array();
     foreach ($this->getPaths() as $path) {
         $library_root = phutil_get_library_root_for_path($path);
         if (!$library_root) {
             continue;
         }
         $library_name = phutil_get_library_name_for_root($library_root);
         if (!$library_name) {
             throw new Exception("Attempting to run unit tests on a libphutil library which has not " . "been loaded, at:\n\n" . "    {$library_root}\n\n" . "This probably means one of two things:\n\n" . "    - You may need to add this library to .arcconfig.\n" . "    - You may be running tests on a copy of libphutil or arcanist\n" . "      using a different copy of libphutil or arcanist. This\n" . "      operation is not supported.");
         }
         $path = Filesystem::resolvePath($path);
         if (!is_dir($path)) {
             $path = dirname($path);
         }
         if ($path == $library_root) {
             continue;
         }
         $library_path = Filesystem::readablePath($path, $library_root);
         do {
             // Add the module and all parent modules as affected modules, which
             // means we'll look for __tests__ to run here and in any containing
             // module.
             $affected_modules[$library_name . ':' . $library_path] = array('name' => $library_name, 'root' => $library_root, 'path' => $library_path);
             $library_path = dirname($library_path);
         } while ($library_path != '.');
     }
     $tests = array();
     foreach ($affected_modules as $library_info) {
         $library_name = $library_info['name'];
         $library_root = $library_info['root'];
         $module = $library_info['path'];
         if (basename($module) == '__tests__') {
             // Okay, this is a __tests__ module.
         } else {
             $exists = $bootloader->moduleExists($library_name, $module . '/__tests__');
             if ($exists) {
                 // This is a module which has a __tests__ module in it.
                 $module .= '/__tests__';
             } else {
                 // Look for a parent named __tests__.
                 $rpos = strrpos($module, '/__tests__');
                 if ($rpos === false) {
                     // No tests to run since there is no child or parent module named
                     // __tests__.
                     continue;
                 }
                 // Select the parent named __tests__.
                 $module = substr($module, 0, $rpos + strlen('/__tests__'));
             }
         }
         $module_key = $library_name . ':' . $module;
         $tests[$module_key] = array('library' => $library_name, 'root' => $library_root, 'module' => $module);
     }
     if (!$tests) {
         throw new ArcanistNoEffectException("No tests to run.");
     }
     $run_tests = array();
     foreach ($tests as $test) {
         $symbols = id(new PhutilSymbolLoader())->setType('class')->setLibrary($test['library'])->setModule($test['module'])->setAncestorClass('ArcanistPhutilTestCase')->selectAndLoadSymbols();
         foreach ($symbols as $symbol) {
             $run_tests[$symbol['name']] = true;
         }
     }
     $run_tests = array_keys($run_tests);
     if (!$run_tests) {
         throw new ArcanistNoEffectException("No tests to run. You may need to rebuild the phutil library map.");
     }
     $enable_coverage = $this->getEnableCoverage();
     if ($enable_coverage !== false) {
         if (!function_exists('xdebug_start_code_coverage')) {
             if ($enable_coverage === true) {
                 throw new ArcanistUsageException("You specified --coverage but xdebug is not available, so " . "coverage can not be enabled for PhutilUnitTestEngine.");
             }
         } else {
             $enable_coverage = true;
         }
     }
     $results = array();
     foreach ($run_tests as $test_class) {
         PhutilSymbolLoader::loadClass($test_class);
         $test_case = newv($test_class, array());
         $test_case->setEnableCoverage($enable_coverage);
         $test_case->setProjectRoot($this->getWorkingCopy()->getProjectRoot());
         $test_case->setPaths($this->getPaths());
         $results[] = $test_case->run();
     }
     if ($results) {
         $results = call_user_func_array('array_merge', $results);
     }
     return $results;
 }
/**
 * @group library
 */
function __phutil_autoload($class)
{
    PhutilSymbolLoader::loadClass($class);
}
 private static function newMarkupEngine(array $options)
 {
     $options += self::getMarkupEngineDefaultConfiguration();
     $engine = new PhutilRemarkupEngine();
     $engine->setConfig('preserve-linebreaks', true);
     $engine->setConfig('pygments.enabled', $options['pygments']);
     $rules = array();
     $rules[] = new PhutilRemarkupRuleEscapeRemarkup();
     if ($options['fileproxy']) {
         $rules[] = new PhabricatorRemarkupRuleProxyImage();
     }
     if ($options['youtube']) {
         $rules[] = new PhabricatorRemarkupRuleYoutube();
     }
     $rules[] = new PhutilRemarkupRuleHyperlink();
     $rules[] = new PhabricatorRemarkupRuleDifferential();
     $rules[] = new PhabricatorRemarkupRuleDiffusion();
     $rules[] = new PhabricatorRemarkupRuleManiphest();
     $rules[] = new PhabricatorRemarkupRulePaste();
     if ($options['macros']) {
         $rules[] = new PhabricatorRemarkupRuleImageMacro();
     }
     $rules[] = new PhabricatorRemarkupRuleMention();
     $rules[] = new PhabricatorRemarkupRulePhriction();
     $custom_rule_classes = $options['custom-inline'];
     if ($custom_rule_classes) {
         foreach ($custom_rule_classes as $custom_rule_class) {
             PhutilSymbolLoader::loadClass($custom_rule_class);
             $rules[] = newv($custom_rule_class, array());
         }
     }
     $rules[] = new PhutilRemarkupRuleEscapeHTML();
     $rules[] = new PhutilRemarkupRuleMonospace();
     $rules[] = new PhutilRemarkupRuleBold();
     $rules[] = new PhutilRemarkupRuleItalic();
     $blocks = array();
     $blocks[] = new PhutilRemarkupEngineRemarkupQuotesBlockRule();
     $blocks[] = new PhutilRemarkupEngineRemarkupHeaderBlockRule();
     $blocks[] = new PhutilRemarkupEngineRemarkupListBlockRule();
     $blocks[] = new PhutilRemarkupEngineRemarkupCodeBlockRule();
     $blocks[] = new PhutilRemarkupEngineRemarkupDefaultBlockRule();
     $custom_block_rule_classes = $options['custom-block'];
     if ($custom_block_rule_classes) {
         foreach ($custom_block_rule_classes as $custom_block_rule_class) {
             PhutilSymbolLoader::loadClass($custom_block_rule_class);
             $blocks[] = newv($custom_block_rule_class, array());
         }
     }
     foreach ($blocks as $block) {
         if (!$block instanceof PhutilRemarkupEngineRemarkupCodeBlockRule) {
             $block->setMarkupRules($rules);
         }
     }
     $engine->setBlockRules($blocks);
     return $engine;
 }
 $pass_argv = array_slice($argv, 3);
 $n = 1;
 if (!$is_debug) {
     if (is_numeric($daemon)) {
         $n = $daemon;
         if ($n < 1) {
             throw new Exception("Count must be at least 1!");
         }
         $daemon = idx($argv, 3);
         if (!$daemon) {
             throw new Exception("Daemon name required!");
         }
         $pass_argv = array_slice($argv, 4);
     }
 }
 $loader = new PhutilSymbolLoader();
 $symbols = $loader->setAncestorClass('PhutilDaemon')->selectSymbolsWithoutLoading();
 $symbols = ipull($symbols, 'name');
 $match = array();
 foreach ($symbols as $symbol) {
     if (stripos($symbol, $daemon) !== false) {
         if (strtolower($symbol) == strtolower($daemon)) {
             $match = array($symbol);
             break;
         } else {
             $match[] = $symbol;
         }
     }
 }
 if (count($match) == 0) {
     throw new Exception("No daemons match! Use 'phd list' for a list of daemons.");