Page MenuHomestyx hydra

No OneTemporary

diff --git a/scripts/repository/save_lint.php b/scripts/repository/save_lint.php
index 6cd0664133..d9bf921e9c 100755
--- a/scripts/repository/save_lint.php
+++ b/scripts/repository/save_lint.php
@@ -1,58 +1,61 @@
#!/usr/bin/env php
<?php
require_once dirname(__FILE__).'/../__init_script__.php';
$synopsis = <<<EOT
**save_lint.php**
Discover lint problems and save them to database so that they can
be displayed in Diffusion.
EOT;
$args = id(new PhutilArgumentParser($argv))
->setTagline('save lint errors to database')
->setSynopsis($synopsis)
->parseStandardArguments()
->parse(array(
array(
'name' => 'all',
- 'help' =>
+ 'help' => pht(
'Discover problems in the whole repository instead of just changes '.
- 'since the last run.',
+ 'since the last run.'),
),
array(
'name' => 'arc',
'param' => 'path',
'default' => 'arc',
- 'help' => 'Path to Arcanist executable.',
+ 'help' => pht('Path to Arcanist executable.'),
),
array(
'name' => 'severity',
'param' => 'string',
'default' => ArcanistLintSeverity::SEVERITY_ADVICE,
- 'help' => 'Minimum severity, one of ArcanistLintSeverity constants.',
+ 'help' => pht(
+ 'Minimum severity, one of %s constants.',
+ 'ArcanistLintSeverity'),
),
array(
'name' => 'chunk-size',
'param' => 'number',
'default' => 256,
- 'help' => 'Number of paths passed to `arc` at once.',
+ 'help' => pht('Number of paths passed to `%s` at once.', 'arc'),
),
array(
'name' => 'blame',
- 'help' => 'Assign lint errors to authors who last modified the line.',
+ 'help' => pht(
+ 'Assign lint errors to authors who last modified the line.'),
),
));
-echo "Saving lint errors to database...\n";
+echo pht('Saving lint errors to database...')."\n";
$count = id(new DiffusionLintSaveRunner())
->setAll($args->getArg('all', false))
->setArc($args->getArg('arc'))
->setSeverity($args->getArg('severity'))
->setChunkSize($args->getArg('chunk-size'))
->setNeedsBlame($args->getArg('blame'))
->run('.');
-echo "\nProcessed {$count} files.\n";
+echo "\n".pht('Processed %d files.', $count)."\n";
diff --git a/src/applications/diffusion/DiffusionLintSaveRunner.php b/src/applications/diffusion/DiffusionLintSaveRunner.php
index 26a98a0232..629c887924 100644
--- a/src/applications/diffusion/DiffusionLintSaveRunner.php
+++ b/src/applications/diffusion/DiffusionLintSaveRunner.php
@@ -1,292 +1,306 @@
<?php
final class DiffusionLintSaveRunner {
private $arc = 'arc';
private $severity = ArcanistLintSeverity::SEVERITY_ADVICE;
private $all = false;
private $chunkSize = 256;
private $needsBlame = false;
private $svnRoot;
private $lintCommit;
private $branch;
private $conn;
private $deletes = array();
private $inserts = array();
private $blame = array();
public function setArc($path) {
$this->arc = $path;
return $this;
}
public function setSeverity($string) {
$this->severity = $string;
return $this;
}
public function setAll($bool) {
$this->all = $bool;
return $this;
}
public function setChunkSize($number) {
$this->chunkSize = $number;
return $this;
}
public function setNeedsBlame($boolean) {
$this->needsBlame = $boolean;
return $this;
}
public function run($dir) {
$working_copy = ArcanistWorkingCopyIdentity::newFromPath($dir);
$configuration_manager = new ArcanistConfigurationManager();
$configuration_manager->setWorkingCopyIdentity($working_copy);
$api = ArcanistRepositoryAPI::newAPIFromConfigurationManager(
$configuration_manager);
$this->svnRoot = id(new PhutilURI($api->getSourceControlPath()))->getPath();
if ($api instanceof ArcanistGitAPI) {
$svn_fetch = $api->getGitConfig('svn-remote.svn.fetch');
list($this->svnRoot) = explode(':', $svn_fetch);
if ($this->svnRoot != '') {
$this->svnRoot = '/'.$this->svnRoot;
}
}
- $project_id = $working_copy->getProjectID();
- $project = id(new PhabricatorRepositoryArcanistProject())
- ->loadOneWhere('name = %s', $project_id);
- if (!$project || !$project->getRepositoryID()) {
- throw new Exception("Couldn't find repository for {$project_id}.");
+ $callsign = $configuration_manager->getConfigFromAnySource(
+ 'repository.callsign');
+ $uuid = $api->getRepositoryUUID();
+ $remote_uri = $api->getRemoteURI();
+
+ $repository_query = id(new PhabricatorRepositoryQuery())
+ ->setViewer(PhabricatorUser::getOmnipotentUser());
+
+ if ($callsign) {
+ $repository_query->withCallsigns(array($callsign));
+ } else if ($uuid) {
+ $repository_query->withUUIDs(array($uuid));
+ } else if ($remote_uri) {
+ $repository_query->withRemoteURIs(array($remote_uri));
}
+ $repository = $repository_query->executeOne();
$branch_name = $api->getBranchName();
+ if (!$repository) {
+ throw new Exception(pht('No repository was found.'));
+ }
+
$this->branch = PhabricatorRepositoryBranch::loadOrCreateBranch(
- $project->getRepositoryID(),
+ $repository->getID(),
$branch_name);
$this->conn = $this->branch->establishConnection('w');
$this->lintCommit = null;
if (!$this->all) {
$this->lintCommit = $this->branch->getLintCommit();
}
if ($this->lintCommit) {
try {
$commit = $this->lintCommit;
if ($this->svnRoot) {
$commit = $api->getCanonicalRevisionName('@'.$commit);
}
$all_files = $api->getChangedFiles($commit);
} catch (ArcanistCapabilityNotSupportedException $ex) {
$this->lintCommit = null;
}
}
if (!$this->lintCommit) {
$where = ($this->svnRoot
? qsprintf($this->conn, 'AND path LIKE %>', $this->svnRoot.'/')
: '');
queryfx(
$this->conn,
'DELETE FROM %T WHERE branchID = %d %Q',
PhabricatorRepository::TABLE_LINTMESSAGE,
$this->branch->getID(),
$where);
$all_files = $api->getAllFiles();
}
$count = 0;
$files = array();
foreach ($all_files as $file => $val) {
$count++;
if (!$this->lintCommit) {
$file = $val;
} else {
$this->deletes[] = $this->svnRoot.'/'.$file;
if ($val & ArcanistRepositoryAPI::FLAG_DELETED) {
continue;
}
}
$files[$file] = $file;
if (count($files) >= $this->chunkSize) {
$this->runArcLint($files);
$files = array();
}
}
$this->runArcLint($files);
$this->saveLintMessages();
$this->lintCommit = $api->getUnderlyingWorkingCopyRevision();
$this->branch->setLintCommit($this->lintCommit);
$this->branch->save();
if ($this->blame) {
$this->blameAuthors();
$this->blame = array();
}
return $count;
}
private function runArcLint(array $files) {
if (!$files) {
return;
}
echo '.';
try {
$future = new ExecFuture(
'%C lint --severity %s --output json %Ls',
$this->arc,
$this->severity,
$files);
foreach (new LinesOfALargeExecFuture($future) as $json) {
$paths = null;
try {
$paths = phutil_json_decode($json);
} catch (PhutilJSONParserException $ex) {
fprintf(STDERR, pht("Invalid JSON: %s\n", $json));
continue;
}
foreach ($paths as $path => $messages) {
if (!isset($files[$path])) {
continue;
}
foreach ($messages as $message) {
$line = idx($message, 'line', 0);
$this->inserts[] = qsprintf(
$this->conn,
'(%d, %s, %d, %s, %s, %s, %s)',
$this->branch->getID(),
$this->svnRoot.'/'.$path,
$line,
idx($message, 'code', ''),
idx($message, 'severity', ''),
idx($message, 'name', ''),
idx($message, 'description', ''));
if ($line && $this->needsBlame) {
$this->blame[$path][$line] = true;
}
}
if (count($this->deletes) >= 1024 || count($this->inserts) >= 256) {
$this->saveLintMessages();
}
}
}
} catch (Exception $ex) {
fprintf(STDERR, $ex->getMessage()."\n");
}
}
private function saveLintMessages() {
$this->conn->openTransaction();
foreach (array_chunk($this->deletes, 1024) as $paths) {
queryfx(
$this->conn,
'DELETE FROM %T WHERE branchID = %d AND path IN (%Ls)',
PhabricatorRepository::TABLE_LINTMESSAGE,
$this->branch->getID(),
$paths);
}
foreach (array_chunk($this->inserts, 256) as $values) {
queryfx(
$this->conn,
'INSERT INTO %T
(branchID, path, line, code, severity, name, description)
VALUES %Q',
PhabricatorRepository::TABLE_LINTMESSAGE,
implode(', ', $values));
}
$this->conn->saveTransaction();
$this->deletes = array();
$this->inserts = array();
}
private function blameAuthors() {
$repository = id(new PhabricatorRepositoryQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withIDs(array($this->branch->getRepositoryID()))
->executeOne();
$queries = array();
$futures = array();
foreach ($this->blame as $path => $lines) {
$drequest = DiffusionRequest::newFromDictionary(array(
'user' => PhabricatorUser::getOmnipotentUser(),
'repository' => $repository,
'branch' => $this->branch->getName(),
'path' => $path,
'commit' => $this->lintCommit,
));
$query = DiffusionFileContentQuery::newFromDiffusionRequest($drequest)
->setNeedsBlame(true);
$queries[$path] = $query;
$futures[$path] = $query->getFileContentFuture();
}
$authors = array();
$futures = id(new FutureIterator($futures))
->limit(8);
foreach ($futures as $path => $future) {
$queries[$path]->loadFileContentFromFuture($future);
list(, $rev_list, $blame_dict) = $queries[$path]->getBlameData();
foreach (array_keys($this->blame[$path]) as $line) {
$commit_identifier = $rev_list[$line - 1];
$author = idx($blame_dict[$commit_identifier], 'authorPHID');
if ($author) {
$authors[$author][$path][] = $line;
}
}
}
if ($authors) {
$this->conn->openTransaction();
foreach ($authors as $author => $paths) {
$where = array();
foreach ($paths as $path => $lines) {
$where[] = qsprintf(
$this->conn,
'(path = %s AND line IN (%Ld))',
$this->svnRoot.'/'.$path,
$lines);
}
queryfx(
$this->conn,
'UPDATE %T SET authorPHID = %s WHERE %Q',
PhabricatorRepository::TABLE_LINTMESSAGE,
$author,
implode(' OR ', $where));
}
$this->conn->saveTransaction();
}
}
}
diff --git a/src/applications/diffusion/conduit/DiffusionGetLintMessagesConduitAPIMethod.php b/src/applications/diffusion/conduit/DiffusionGetLintMessagesConduitAPIMethod.php
index d73213b148..cc7cb4a095 100644
--- a/src/applications/diffusion/conduit/DiffusionGetLintMessagesConduitAPIMethod.php
+++ b/src/applications/diffusion/conduit/DiffusionGetLintMessagesConduitAPIMethod.php
@@ -1,69 +1,75 @@
<?php
final class DiffusionGetLintMessagesConduitAPIMethod
extends DiffusionConduitAPIMethod {
public function getAPIMethodName() {
return 'diffusion.getlintmessages';
}
public function getMethodStatus() {
return self::METHOD_STATUS_UNSTABLE;
}
public function getMethodDescription() {
- return 'Get lint messages for existing code.';
+ return pht('Get lint messages for existing code.');
}
protected function defineParamTypes() {
return array(
- 'arcanistProject' => 'required string',
- 'branch' => 'optional string',
- 'commit' => 'optional string',
- 'files' => 'required list<string>',
+ 'repositoryPHID' => 'required phid',
+ 'branch' => 'required string',
+ 'commit' => 'optional string',
+ 'files' => 'required list<string>',
);
}
protected function defineReturnType() {
return 'list<dict>';
}
protected function execute(ConduitAPIRequest $request) {
- $project = id(new PhabricatorRepositoryArcanistProject())->loadOneWhere(
- 'name = %s',
- $request->getValue('arcanistProject'));
- if (!$project || !$project->getRepositoryID()) {
- return array();
+ $viewer = $request->getUser();
+
+ $repository_phid = $request->getValue('repositoryPHID');
+ $repository = id(new PhabricatorRepositoryQuery())
+ ->setViewer($viewer)
+ ->withPHIDs(array($repository_phid))
+ ->executeOne();
+
+ if (!$repository) {
+ throw new Exception(
+ pht('No repository exists with PHID "%s".', $repository_phid));
}
$branch_name = $request->getValue('branch');
if ($branch_name == '') {
$repository = id(new PhabricatorRepositoryQuery())
->setViewer($request->getUser())
- ->withIDs(array($project->getRepositoryID()))
+ ->withIDs(array($repository->getID()))
->executeOne();
$branch_name = $repository->getDefaultArcanistBranch();
}
$branch = id(new PhabricatorRepositoryBranch())->loadOneWhere(
'repositoryID = %d AND name = %s',
- $project->getRepositoryID(),
+ $repository->getID(),
$branch_name);
if (!$branch || !$branch->getLintCommit()) {
return array();
}
$lint_messages = queryfx_all(
$branch->establishConnection('r'),
'SELECT path, line, code FROM %T WHERE branchID = %d AND path IN (%Ls)',
PhabricatorRepository::TABLE_LINTMESSAGE,
$branch->getID(),
$request->getValue('files'));
// TODO: Compare commit identifiers of individual files like in
// DiffusionBrowseFileController::loadLintMessages().
return $lint_messages;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Wed, Dec 3, 2:13 PM (9 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
433561
Default Alt Text
(14 KB)

Event Timeline