Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14912525
D21342.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
12 KB
Referenced Files
None
Subscribers
None
D21342.diff
View Options
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
@@ -333,6 +333,7 @@
'ArcanistMercurialParser' => 'repository/parser/ArcanistMercurialParser.php',
'ArcanistMercurialParserTestCase' => 'repository/parser/__tests__/ArcanistMercurialParserTestCase.php',
'ArcanistMercurialRepositoryMarkerQuery' => 'repository/marker/ArcanistMercurialRepositoryMarkerQuery.php',
+ 'ArcanistMercurialRepositoryRemoteQuery' => 'repository/remote/ArcanistMercurialRepositoryRemoteQuery.php',
'ArcanistMercurialWorkEngine' => 'work/ArcanistMercurialWorkEngine.php',
'ArcanistMercurialWorkingCopy' => 'workingcopy/ArcanistMercurialWorkingCopy.php',
'ArcanistMercurialWorkingCopyRevisionHardpointQuery' => 'query/ArcanistMercurialWorkingCopyRevisionHardpointQuery.php',
@@ -414,12 +415,15 @@
'ArcanistRaggedClassTreeEdgeXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistRaggedClassTreeEdgeXHPASTLinterRuleTestCase.php',
'ArcanistRef' => 'ref/ArcanistRef.php',
'ArcanistRefInspector' => 'inspector/ArcanistRefInspector.php',
+ 'ArcanistRemoteRef' => 'repository/remote/ArcanistRemoteRef.php',
'ArcanistRepositoryAPI' => 'repository/api/ArcanistRepositoryAPI.php',
'ArcanistRepositoryAPIMiscTestCase' => 'repository/api/__tests__/ArcanistRepositoryAPIMiscTestCase.php',
'ArcanistRepositoryAPIStateTestCase' => 'repository/api/__tests__/ArcanistRepositoryAPIStateTestCase.php',
'ArcanistRepositoryLocalState' => 'repository/state/ArcanistRepositoryLocalState.php',
'ArcanistRepositoryMarkerQuery' => 'repository/marker/ArcanistRepositoryMarkerQuery.php',
+ 'ArcanistRepositoryQuery' => 'repository/query/ArcanistRepositoryQuery.php',
'ArcanistRepositoryRef' => 'ref/ArcanistRepositoryRef.php',
+ 'ArcanistRepositoryRemoteQuery' => 'repository/remote/ArcanistRepositoryRemoteQuery.php',
'ArcanistReusedAsIteratorXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistReusedAsIteratorXHPASTLinterRule.php',
'ArcanistReusedAsIteratorXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistReusedAsIteratorXHPASTLinterRuleTestCase.php',
'ArcanistReusedIteratorReferenceXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistReusedIteratorReferenceXHPASTLinterRule.php',
@@ -1365,6 +1369,7 @@
'ArcanistMercurialParser' => 'Phobject',
'ArcanistMercurialParserTestCase' => 'PhutilTestCase',
'ArcanistMercurialRepositoryMarkerQuery' => 'ArcanistRepositoryMarkerQuery',
+ 'ArcanistMercurialRepositoryRemoteQuery' => 'ArcanistRepositoryRemoteQuery',
'ArcanistMercurialWorkEngine' => 'ArcanistWorkEngine',
'ArcanistMercurialWorkingCopy' => 'ArcanistWorkingCopy',
'ArcanistMercurialWorkingCopyRevisionHardpointQuery' => 'ArcanistWorkflowMercurialHardpointQuery',
@@ -1449,12 +1454,15 @@
'ArcanistRaggedClassTreeEdgeXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistRef' => 'ArcanistHardpointObject',
'ArcanistRefInspector' => 'Phobject',
+ 'ArcanistRemoteRef' => 'ArcanistRef',
'ArcanistRepositoryAPI' => 'Phobject',
'ArcanistRepositoryAPIMiscTestCase' => 'PhutilTestCase',
'ArcanistRepositoryAPIStateTestCase' => 'PhutilTestCase',
'ArcanistRepositoryLocalState' => 'Phobject',
- 'ArcanistRepositoryMarkerQuery' => 'Phobject',
+ 'ArcanistRepositoryMarkerQuery' => 'ArcanistRepositoryQuery',
+ 'ArcanistRepositoryQuery' => 'Phobject',
'ArcanistRepositoryRef' => 'ArcanistRef',
+ 'ArcanistRepositoryRemoteQuery' => 'ArcanistRepositoryQuery',
'ArcanistReusedAsIteratorXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistReusedAsIteratorXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistReusedIteratorReferenceXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
diff --git a/src/land/engine/ArcanistMercurialLandEngine.php b/src/land/engine/ArcanistMercurialLandEngine.php
--- a/src/land/engine/ArcanistMercurialLandEngine.php
+++ b/src/land/engine/ArcanistMercurialLandEngine.php
@@ -48,6 +48,7 @@
}
$commit = $api->getCanonicalRevisionName('.');
+ $commit = $this->getDisplayHash($commit);
$log->writeStatus(
pht('SOURCE'),
@@ -124,9 +125,21 @@
protected function selectOntoRemote(array $symbols) {
assert_instances_of($symbols, 'ArcanistLandSymbol');
+ $api = $this->getRepositoryAPI();
+
$remote = $this->newOntoRemote($symbols);
- // TODO: Verify this remote actually exists.
+ $remote_ref = $api->newRemoteRefQuery()
+ ->withNames(array($remote))
+ ->executeOne();
+ if (!$remote_ref) {
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'No remote "%s" exists in this repository.',
+ $remote));
+ }
+
+ // TODO: Allow selection of a bare URI.
return $remote;
}
@@ -261,8 +274,17 @@
$into = $this->getIntoRemoteArgument();
if ($into !== null) {
- // TODO: Verify that this is a valid path.
- // TODO: Allow a raw URI?
+ $remote_ref = $api->newRemoteRefQuery()
+ ->withNames(array($into))
+ ->executeOne();
+ if (!$remote_ref) {
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'No remote "%s" exists in this repository.',
+ $into));
+ }
+
+ // TODO: Allow a raw URI.
$this->setIntoRemote($into);
diff --git a/src/repository/api/ArcanistMercurialAPI.php b/src/repository/api/ArcanistMercurialAPI.php
--- a/src/repository/api/ArcanistMercurialAPI.php
+++ b/src/repository/api/ArcanistMercurialAPI.php
@@ -902,6 +902,8 @@
}
public function getRemoteURI() {
+ // TODO: Remove this method in favor of RemoteRefQuery.
+
list($stdout) = $this->execxLocal('paths default');
$stdout = trim($stdout);
@@ -1006,4 +1008,8 @@
return new ArcanistMercurialRepositoryMarkerQuery();
}
+ protected function newRemoteRefQueryTemplate() {
+ return new ArcanistMercurialRepositoryRemoteQuery();
+ }
+
}
diff --git a/src/repository/api/ArcanistRepositoryAPI.php b/src/repository/api/ArcanistRepositoryAPI.php
--- a/src/repository/api/ArcanistRepositoryAPI.php
+++ b/src/repository/api/ArcanistRepositoryAPI.php
@@ -785,6 +785,15 @@
throw new PhutilMethodNotImplementedException();
}
+ final public function newRemoteRefQuery() {
+ return id($this->newRemoteRefQueryTemplate())
+ ->setRepositoryAPI($this);
+ }
+
+ protected function newRemoteRefQueryTemplate() {
+ throw new PhutilMethodNotImplementedException();
+ }
+
final public function getDisplayHash($hash) {
return substr($hash, 0, 12);
}
diff --git a/src/repository/marker/ArcanistRepositoryMarkerQuery.php b/src/repository/marker/ArcanistRepositoryMarkerQuery.php
--- a/src/repository/marker/ArcanistRepositoryMarkerQuery.php
+++ b/src/repository/marker/ArcanistRepositoryMarkerQuery.php
@@ -1,24 +1,14 @@
<?php
abstract class ArcanistRepositoryMarkerQuery
- extends Phobject {
+ extends ArcanistRepositoryQuery {
- private $repositoryAPI;
private $isActive;
private $markerTypes;
private $names;
private $commitHashes;
private $ancestorCommitHashes;
- final public function setRepositoryAPI(ArcanistRepositoryAPI $api) {
- $this->repositoryAPI = $api;
- return $this;
- }
-
- final public function getRepositoryAPI() {
- return $this->repositoryAPI;
- }
-
final public function withMarkerTypes(array $types) {
$this->markerTypes = array_fuse($types);
return $this;
@@ -34,22 +24,6 @@
return $this;
}
- final public function executeOne() {
- $markers = $this->execute();
-
- if (!$markers) {
- return null;
- }
-
- if (count($markers) > 1) {
- throw new Exception(
- pht(
- 'Query matched multiple markers, expected zero or one.'));
- }
-
- return head($markers);
- }
-
final public function execute() {
$markers = $this->newRefMarkers();
diff --git a/src/repository/query/ArcanistRepositoryQuery.php b/src/repository/query/ArcanistRepositoryQuery.php
new file mode 100644
--- /dev/null
+++ b/src/repository/query/ArcanistRepositoryQuery.php
@@ -0,0 +1,35 @@
+<?php
+
+abstract class ArcanistRepositoryQuery
+ extends Phobject {
+
+ private $repositoryAPI;
+
+ final public function setRepositoryAPI(ArcanistRepositoryAPI $api) {
+ $this->repositoryAPI = $api;
+ return $this;
+ }
+
+ final public function getRepositoryAPI() {
+ return $this->repositoryAPI;
+ }
+
+ abstract public function execute();
+
+ final public function executeOne() {
+ $refs = $this->execute();
+
+ if (!$refs) {
+ return null;
+ }
+
+ if (count($refs) > 1) {
+ throw new Exception(
+ pht(
+ 'Query matched multiple refs, expected zero or one.'));
+ }
+
+ return head($refs);
+ }
+
+}
diff --git a/src/repository/remote/ArcanistMercurialRepositoryRemoteQuery.php b/src/repository/remote/ArcanistMercurialRepositoryRemoteQuery.php
new file mode 100644
--- /dev/null
+++ b/src/repository/remote/ArcanistMercurialRepositoryRemoteQuery.php
@@ -0,0 +1,45 @@
+<?php
+
+final class ArcanistMercurialRepositoryRemoteQuery
+ extends ArcanistRepositoryRemoteQuery {
+
+ protected function newRemoteRefs() {
+ $api = $this->getRepositoryAPI();
+
+ $future = $api->newFuture('paths');
+ list($lines) = $future->resolve();
+
+ $refs = array();
+
+ $pattern = '(^(?P<name>.*?) = (?P<uri>.*)\z)';
+
+ $lines = phutil_split_lines($lines, false);
+ foreach ($lines as $line) {
+ $matches = null;
+ if (!preg_match($pattern, $line, $matches)) {
+ throw new Exception(
+ pht(
+ 'Failed to match remote pattern against line "%s".',
+ $line));
+ }
+
+ $name = $matches['name'];
+ $uri = $matches['uri'];
+
+ // NOTE: Mercurial gives some special behavior to "default" and
+ // "default-push", but these remotes are both fully-formed remotes that
+ // are fetchable and pushable, they just have rules around selection
+ // as default targets for operations.
+
+ $ref = id(new ArcanistRemoteRef())
+ ->setRemoteName($name)
+ ->setFetchURI($uri)
+ ->setPushURI($uri);
+
+ $refs[] = $ref;
+ }
+
+ return $refs;
+ }
+
+}
diff --git a/src/repository/remote/ArcanistRemoteRef.php b/src/repository/remote/ArcanistRemoteRef.php
new file mode 100644
--- /dev/null
+++ b/src/repository/remote/ArcanistRemoteRef.php
@@ -0,0 +1,41 @@
+<?php
+
+final class ArcanistRemoteRef
+ extends ArcanistRef {
+
+ private $remoteName;
+ private $fetchURI;
+ private $pushURI;
+
+ public function getRefDisplayName() {
+ return pht('Remote "%s"', $this->getRemoteName());
+ }
+
+ public function setRemoteName($remote_name) {
+ $this->remoteName = $remote_name;
+ return $this;
+ }
+
+ public function getRemoteName() {
+ return $this->remoteName;
+ }
+
+ public function setFetchURI($fetch_uri) {
+ $this->fetchURI = $fetch_uri;
+ return $this;
+ }
+
+ public function getFetchURI() {
+ return $this->fetchURI;
+ }
+
+ public function setPushURI($push_uri) {
+ $this->pushURI = $push_uri;
+ return $this;
+ }
+
+ public function getPushURI() {
+ return $this->pushURI;
+ }
+
+}
diff --git a/src/repository/remote/ArcanistRepositoryRemoteQuery.php b/src/repository/remote/ArcanistRepositoryRemoteQuery.php
new file mode 100644
--- /dev/null
+++ b/src/repository/remote/ArcanistRepositoryRemoteQuery.php
@@ -0,0 +1,31 @@
+<?php
+
+abstract class ArcanistRepositoryRemoteQuery
+ extends ArcanistRepositoryQuery {
+
+ private $names;
+
+ final public function withNames(array $names) {
+ $this->names = $names;
+ return $this;
+ }
+
+ final public function execute() {
+ $refs = $this->newRemoteRefs();
+
+ $names = $this->names;
+ if ($names !== null) {
+ $names = array_fuse($names);
+ foreach ($refs as $key => $ref) {
+ if (!isset($names[$ref->getRemoteName()])) {
+ unset($refs[$key]);
+ }
+ }
+ }
+
+ return $refs;
+ }
+
+ abstract protected function newRemoteRefs();
+
+}
diff --git a/src/workflow/ArcanistWorkflow.php b/src/workflow/ArcanistWorkflow.php
--- a/src/workflow/ArcanistWorkflow.php
+++ b/src/workflow/ArcanistWorkflow.php
@@ -2036,6 +2036,8 @@
'This repository has no VCS UUID (this is normal for git/hg).');
}
+ // TODO: Swap this for a RemoteRefQuery.
+
$remote_uri = $this->getRepositoryAPI()->getRemoteURI();
if ($remote_uri !== null) {
$query = array(
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Feb 13, 12:03 AM (2 h, 36 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7125633
Default Alt Text
D21342.diff (12 KB)
Attached To
Mode
D21342: Verify remotes ("paths") in Mercurial during "arc land"
Attached
Detach File
Event Timeline
Log In to Comment