Page MenuHomePhabricator

D14957.diff
No OneTemporary

D14957.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -528,6 +528,8 @@
'DiffusionAuditorsAddAuditorsHeraldAction' => 'applications/diffusion/herald/DiffusionAuditorsAddAuditorsHeraldAction.php',
'DiffusionAuditorsAddSelfHeraldAction' => 'applications/diffusion/herald/DiffusionAuditorsAddSelfHeraldAction.php',
'DiffusionAuditorsHeraldAction' => 'applications/diffusion/herald/DiffusionAuditorsHeraldAction.php',
+ 'DiffusionBlameConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionBlameConduitAPIMethod.php',
+ 'DiffusionBlameQuery' => 'applications/diffusion/query/blame/DiffusionBlameQuery.php',
'DiffusionBlockHeraldAction' => 'applications/diffusion/herald/DiffusionBlockHeraldAction.php',
'DiffusionBranchQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionBranchQueryConduitAPIMethod.php',
'DiffusionBranchTableController' => 'applications/diffusion/controller/DiffusionBranchTableController.php',
@@ -601,6 +603,7 @@
'DiffusionFindSymbolsConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionFindSymbolsConduitAPIMethod.php',
'DiffusionGetLintMessagesConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionGetLintMessagesConduitAPIMethod.php',
'DiffusionGetRecentCommitsByPathConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionGetRecentCommitsByPathConduitAPIMethod.php',
+ 'DiffusionGitBlameQuery' => 'applications/diffusion/query/blame/DiffusionGitBlameQuery.php',
'DiffusionGitBranch' => 'applications/diffusion/data/DiffusionGitBranch.php',
'DiffusionGitBranchTestCase' => 'applications/diffusion/data/__tests__/DiffusionGitBranchTestCase.php',
'DiffusionGitFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionGitFileContentQuery.php',
@@ -632,6 +635,7 @@
'DiffusionLowLevelParentsQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelParentsQuery.php',
'DiffusionLowLevelQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelQuery.php',
'DiffusionLowLevelResolveRefsQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelResolveRefsQuery.php',
+ 'DiffusionMercurialBlameQuery' => 'applications/diffusion/query/blame/DiffusionMercurialBlameQuery.php',
'DiffusionMercurialFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionMercurialFileContentQuery.php',
'DiffusionMercurialRawDiffQuery' => 'applications/diffusion/query/rawdiff/DiffusionMercurialRawDiffQuery.php',
'DiffusionMercurialRequest' => 'applications/diffusion/request/DiffusionMercurialRequest.php',
@@ -743,6 +747,7 @@
'DiffusionSubversionServeSSHWorkflow' => 'applications/diffusion/ssh/DiffusionSubversionServeSSHWorkflow.php',
'DiffusionSubversionWireProtocol' => 'applications/diffusion/protocol/DiffusionSubversionWireProtocol.php',
'DiffusionSubversionWireProtocolTestCase' => 'applications/diffusion/protocol/__tests__/DiffusionSubversionWireProtocolTestCase.php',
+ 'DiffusionSvnBlameQuery' => 'applications/diffusion/query/blame/DiffusionSvnBlameQuery.php',
'DiffusionSvnFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionSvnFileContentQuery.php',
'DiffusionSvnRawDiffQuery' => 'applications/diffusion/query/rawdiff/DiffusionSvnRawDiffQuery.php',
'DiffusionSvnRequest' => 'applications/diffusion/request/DiffusionSvnRequest.php',
@@ -4493,6 +4498,8 @@
'DiffusionAuditorsAddAuditorsHeraldAction' => 'DiffusionAuditorsHeraldAction',
'DiffusionAuditorsAddSelfHeraldAction' => 'DiffusionAuditorsHeraldAction',
'DiffusionAuditorsHeraldAction' => 'HeraldAction',
+ 'DiffusionBlameConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
+ 'DiffusionBlameQuery' => 'DiffusionQuery',
'DiffusionBlockHeraldAction' => 'HeraldAction',
'DiffusionBranchQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
'DiffusionBranchTableController' => 'DiffusionController',
@@ -4566,6 +4573,7 @@
'DiffusionFindSymbolsConduitAPIMethod' => 'DiffusionConduitAPIMethod',
'DiffusionGetLintMessagesConduitAPIMethod' => 'DiffusionConduitAPIMethod',
'DiffusionGetRecentCommitsByPathConduitAPIMethod' => 'DiffusionConduitAPIMethod',
+ 'DiffusionGitBlameQuery' => 'DiffusionBlameQuery',
'DiffusionGitBranch' => 'Phobject',
'DiffusionGitBranchTestCase' => 'PhabricatorTestCase',
'DiffusionGitFileContentQuery' => 'DiffusionFileContentQuery',
@@ -4597,6 +4605,7 @@
'DiffusionLowLevelParentsQuery' => 'DiffusionLowLevelQuery',
'DiffusionLowLevelQuery' => 'Phobject',
'DiffusionLowLevelResolveRefsQuery' => 'DiffusionLowLevelQuery',
+ 'DiffusionMercurialBlameQuery' => 'DiffusionBlameQuery',
'DiffusionMercurialFileContentQuery' => 'DiffusionFileContentQuery',
'DiffusionMercurialRawDiffQuery' => 'DiffusionRawDiffQuery',
'DiffusionMercurialRequest' => 'DiffusionRequest',
@@ -4708,6 +4717,7 @@
'DiffusionSubversionServeSSHWorkflow' => 'DiffusionSubversionSSHWorkflow',
'DiffusionSubversionWireProtocol' => 'Phobject',
'DiffusionSubversionWireProtocolTestCase' => 'PhabricatorTestCase',
+ 'DiffusionSvnBlameQuery' => 'DiffusionBlameQuery',
'DiffusionSvnFileContentQuery' => 'DiffusionFileContentQuery',
'DiffusionSvnRawDiffQuery' => 'DiffusionRawDiffQuery',
'DiffusionSvnRequest' => 'DiffusionRequest',
diff --git a/src/applications/diffusion/conduit/DiffusionBlameConduitAPIMethod.php b/src/applications/diffusion/conduit/DiffusionBlameConduitAPIMethod.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diffusion/conduit/DiffusionBlameConduitAPIMethod.php
@@ -0,0 +1,44 @@
+<?php
+
+final class DiffusionBlameConduitAPIMethod
+ extends DiffusionQueryConduitAPIMethod {
+
+ public function getAPIMethodName() {
+ return 'diffusion.blame';
+ }
+
+ public function getMethodDescription() {
+ return pht('Get blame information for a list of paths.');
+ }
+
+ protected function defineReturnType() {
+ return 'map<string, wild>';
+ }
+
+ protected function defineCustomParamTypes() {
+ return array(
+ 'paths' => 'required list<string>',
+ 'commit' => 'required string',
+ 'timeout' => 'optional int',
+ );
+ }
+
+ protected function getResult(ConduitAPIRequest $request) {
+ $drequest = $this->getDiffusionRequest();
+
+ $paths = $request->getValue('paths');
+
+ $blame_query = DiffusionBlameQuery::newFromDiffusionRequest($drequest)
+ ->setPaths($paths);
+
+ $timeout = $request->getValue('timeout');
+ if ($timeout) {
+ $blame_query->setTimeout($timeout);
+ }
+
+ $blame = $blame_query->execute();
+
+ return $blame;
+ }
+
+}
diff --git a/src/applications/diffusion/conduit/DiffusionQueryConduitAPIMethod.php b/src/applications/diffusion/conduit/DiffusionQueryConduitAPIMethod.php
--- a/src/applications/diffusion/conduit/DiffusionQueryConduitAPIMethod.php
+++ b/src/applications/diffusion/conduit/DiffusionQueryConduitAPIMethod.php
@@ -110,6 +110,13 @@
'commit' => $request->getValue('commit'),
));
+ if (!$drequest) {
+ throw new Exception(
+ pht(
+ 'Repository "%s" is not a valid repository.',
+ $identifier));
+ }
+
// Figure out whether we're going to handle this request on this device,
// or proxy it to another node in the cluster.
diff --git a/src/applications/diffusion/query/blame/DiffusionBlameQuery.php b/src/applications/diffusion/query/blame/DiffusionBlameQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diffusion/query/blame/DiffusionBlameQuery.php
@@ -0,0 +1,69 @@
+<?php
+
+abstract class DiffusionBlameQuery extends DiffusionQuery {
+
+ private $timeout;
+ private $paths;
+
+ public function setTimeout($timeout) {
+ $this->timeout = $timeout;
+ return $this;
+ }
+
+ public function getTimeout() {
+ return $this->timeout;
+ }
+
+ public function setPaths(array $paths) {
+ $this->paths = $paths;
+ return $this;
+ }
+
+ public function getPaths() {
+ return $this->paths;
+ }
+
+ abstract protected function newBlameFuture(DiffusionRequest $request, $path);
+
+ abstract protected function resolveBlameFuture(ExecFuture $future);
+
+ final public static function newFromDiffusionRequest(
+ DiffusionRequest $request) {
+ return parent::newQueryObject(__CLASS__, $request);
+ }
+
+ final protected function executeQuery() {
+ $paths = $this->getPaths();
+ $request = $this->getRequest();
+ $timeout = $this->getTimeout();
+
+ $futures = array();
+ foreach ($paths as $path) {
+ $future = $this->newBlameFuture($request, $path);
+
+ if ($timeout) {
+ $future->setTimeout($timeout);
+ }
+
+ $futures[$path] = $future;
+ }
+
+
+ $blame = array();
+
+ if ($futures) {
+ $futures = id(new FutureIterator($futures))
+ ->limit(4);
+
+ foreach ($futures as $path => $future) {
+ $path_blame = $this->resolveBlameFuture($future);
+ if ($path_blame !== null) {
+ $blame[$path] = $path_blame;
+ }
+ }
+ }
+
+ return $blame;
+ }
+
+}
diff --git a/src/applications/diffusion/query/blame/DiffusionGitBlameQuery.php b/src/applications/diffusion/query/blame/DiffusionGitBlameQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diffusion/query/blame/DiffusionGitBlameQuery.php
@@ -0,0 +1,34 @@
+<?php
+
+final class DiffusionGitBlameQuery extends DiffusionBlameQuery {
+
+ protected function newBlameFuture(DiffusionRequest $request, $path) {
+ $repository = $request->getRepository();
+
+ $commit = $request->getCommit();
+
+ return $repository->getLocalCommandFuture(
+ '--no-pager blame -s -l %s -- %s',
+ $commit,
+ $path);
+ }
+
+ protected function resolveBlameFuture(ExecFuture $future) {
+ list($err, $stdout) = $future->resolve();
+
+ if ($err) {
+ return null;
+ }
+
+ $result = array();
+
+ $lines = phutil_split_lines($stdout);
+ foreach ($lines as $line) {
+ list($commit) = explode(' ', $line, 2);
+ $result[] = $commit;
+ }
+
+ return $result;
+ }
+
+}
diff --git a/src/applications/diffusion/query/blame/DiffusionMercurialBlameQuery.php b/src/applications/diffusion/query/blame/DiffusionMercurialBlameQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diffusion/query/blame/DiffusionMercurialBlameQuery.php
@@ -0,0 +1,36 @@
+<?php
+
+final class DiffusionMercurialBlameQuery extends DiffusionBlameQuery {
+
+ protected function newBlameFuture(DiffusionRequest $request, $path) {
+ $repository = $request->getRepository();
+ $commit = $request->getCommit();
+
+ // NOTE: We're using "--debug" to make "--changeset" give us the full
+ // commit hashes.
+
+ return $repository->getLocalCommandFuture(
+ 'annotate --debug --changeset --rev %s -- %s',
+ $commit,
+ $path);
+ }
+
+ protected function resolveBlameFuture(ExecFuture $future) {
+ list($err, $stdout) = $future->resolve();
+
+ if ($err) {
+ return null;
+ }
+
+ $result = array();
+
+ $lines = phutil_split_lines($stdout);
+ foreach ($lines as $line) {
+ list($commit) = explode(':', $line, 2);
+ $result[] = $commit;
+ }
+
+ return $result;
+ }
+
+}
diff --git a/src/applications/diffusion/query/blame/DiffusionSvnBlameQuery.php b/src/applications/diffusion/query/blame/DiffusionSvnBlameQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diffusion/query/blame/DiffusionSvnBlameQuery.php
@@ -0,0 +1,36 @@
+<?php
+
+final class DiffusionSvnBlameQuery extends DiffusionBlameQuery {
+
+ protected function newBlameFuture(DiffusionRequest $request, $path) {
+ $repository = $request->getRepository();
+ $commit = $request->getCommit();
+
+ return $repository->getRemoteCommandFuture(
+ 'blame --force %s',
+ $repository->getSubversionPathURI($path, $commit));
+ }
+
+ protected function resolveBlameFuture(ExecFuture $future) {
+ list($err, $stdout) = $future->resolve();
+
+ if ($err) {
+ return null;
+ }
+
+ $result = array();
+ $matches = null;
+
+ $lines = phutil_split_lines($stdout);
+ foreach ($lines as $line) {
+ if (preg_match('/^\s*(\d+)/', $line, $matches)) {
+ $result[] = (int)$matches[1];
+ } else {
+ $result[] = null;
+ }
+ }
+
+ return $result;
+ }
+
+}

File Metadata

Mime Type
text/plain
Expires
Mon, Mar 31, 4:55 AM (5 d, 7 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7704276
Default Alt Text
D14957.diff (12 KB)

Event Timeline