Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14111260
D21697.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
10 KB
Referenced Files
None
Subscribers
None
D21697.diff
View Options
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
@@ -1160,8 +1160,9 @@
'prune --rev %s',
$rev_set);
} else {
- $api->execxLocal(
- '--config extensions.strip= strip --rev %s',
+ $api->execxLocalWithExtension(
+ 'strip',
+ 'strip --rev %s',
$rev_set);
}
}
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
@@ -5,6 +5,13 @@
*/
final class ArcanistMercurialAPI extends ArcanistRepositoryAPI {
+ /**
+ * Mercurial deceptively indicates that the default encoding is UTF-8 however
+ * however the actual default appears to be "something else", at least on
+ * Windows systems. Force all mercurial commands to use UTF-8 encoding.
+ */
+ const ROOT_HG_COMMAND = 'hg --encoding utf-8 ';
+
private $branch;
private $localCommitInfo;
private $rawDiffCache = array();
@@ -13,28 +20,24 @@
private $featureFutures = array();
protected function buildLocalFuture(array $argv) {
- $env = $this->getMercurialEnvironmentVariables();
+ $argv[0] = self::ROOT_HG_COMMAND.$argv[0];
- // Mercurial deceptively indicates that the default encoding is UTF-8
- // however the actual default appears to be "something else", at least on
- // Windows systems. Force all mercurial commands to use UTF-8 encoding.
- $argv[0] = 'hg --encoding utf-8 '.$argv[0];
+ return $this->newConfiguredFuture(newv('ExecFuture', $argv));
+ }
- $future = newv('ExecFuture', $argv)
- ->setEnv($env)
- ->setCWD($this->getPath());
+ public function newPassthru($pattern /* , ... */) {
+ $args = func_get_args();
+ $args[0] = self::ROOT_HG_COMMAND.$args[0];
- return $future;
+ return $this->newConfiguredFuture(newv('PhutilExecPassthru', $args));
}
- public function newPassthru($pattern /* , ... */) {
+ private function newConfiguredFuture(PhutilExecutableFuture $future) {
$args = func_get_args();
$env = $this->getMercurialEnvironmentVariables();
- $args[0] = 'hg '.$args[0];
-
- return newv('PhutilExecPassthru', $args)
+ return $future
->setEnv($env)
->setCWD($this->getPath());
}
@@ -730,14 +733,10 @@
'log --template %s --rev . --',
'{node}');
- $argv = array();
- foreach ($this->getMercurialExtensionArguments() as $arg) {
- $argv[] = $arg;
- }
- $argv[] = 'arc-amend';
- $argv[] = '--logfile';
- $argv[] = $tmp_file;
- $this->execxLocal('%Ls', $argv);
+ $this->execxLocalWithExtension(
+ 'arc-hg',
+ 'arc-amend --logfile %s',
+ $tmp_file);
list($new_commit) = $this->execxLocal(
'log --rev tip --template %s --',
@@ -753,13 +752,20 @@
$rebase_args[] = $child;
}
- $this->execxLocal('rebase %Ls --', $rebase_args);
+ $this->execxLocalWithExtension(
+ 'rebase',
+ 'rebase %Ls --',
+ $rebase_args);
} catch (CommandException $ex) {
- $this->execxLocal('rebase --abort --');
+ $this->execxLocalWithExtension(
+ 'rebase',
+ 'rebase --abort --');
throw $ex;
}
- $this->execxLocal('--config extensions.strip= strip --rev %s --',
+ $this->execxLocalWithExtension(
+ 'strip',
+ 'strip --rev %s --',
$current);
}
@@ -1034,6 +1040,115 @@
return $this->executeMercurialFeatureTest($feature, true);
}
+ /**
+ * Returns the necessary flag for using a Mercurial extension. This will
+ * enable Mercurial built-in extensions and the "arc-hg" extension that is
+ * included with Arcanist. This will not enable other extensions, e.g.
+ * "evolve".
+ *
+ * @param string The name of the extension to enable.
+ * @return string A new command pattern that includes the necessary flags to
+ * enable the specified extension.
+ */
+ private function getMercurialExtensionFlag($extension) {
+ switch ($extension) {
+ case 'arc-hg':
+ $path = phutil_get_library_root('arcanist');
+ $path = dirname($path);
+ $path = $path.'/support/hg/arc-hg.py';
+ $ext_config = 'extensions.arg-hg='.$path;
+ break;
+ case 'rebase':
+ $ext_config = 'extensions.rebase=';
+ break;
+ case 'shelve':
+ $ext_config = 'extensions.shelve=';
+ break;
+ case 'strip':
+ $ext_config = 'extensions.strip=';
+ break;
+ default:
+ throw new Exception(
+ pht('Unknown Mercurial Extension: "%s".', $extension));
+ }
+
+ return csprintf('--config %s', $ext_config);
+ }
+
+ /**
+ * Produces the arguments that should be passed to Mercurial command
+ * execution that enables a desired extension.
+ *
+ * @param string The name of the extension to enable.
+ * @param string The command pattern that will be run with the extension
+ * enabled.
+ * @param array Parameters for the command pattern argument.
+ * @return array An array where the first item is a Mercurial command
+ * pattern that includes the necessary flag for enabling the
+ * desired extension, and all remaining items are parameters
+ * to that command pattern.
+ */
+ private function buildMercurialExtensionCommand(
+ $extension,
+ $pattern /* , ... */) {
+
+ $args = func_get_args();
+
+ $pattern_args = array_slice($args, 2);
+
+ $ext_flag = $this->getMercurialExtensionFlag($extension);
+
+ $full_cmd = $ext_flag.' '.$pattern;
+
+ $args = array_merge(
+ array($full_cmd),
+ $pattern_args);
+
+ return $args;
+ }
+
+ public function execxLocalWithExtension(
+ $extension,
+ $pattern /* , ... */) {
+
+ $args = func_get_args();
+ $extended_args = call_user_func_array(
+ array($this, 'buildMercurialExtensionCommand'),
+ $args);
+
+ return call_user_func_array(
+ array($this, 'execxLocal'),
+ $extended_args);
+ }
+
+ public function execFutureLocalWithExtension(
+ $extension,
+ $pattern /* , ... */) {
+
+ $args = func_get_args();
+ $extended_args = call_user_func_array(
+ array($this, 'buildMercurialExtensionCommand'),
+ $args);
+
+ return call_user_func_array(
+ array($this, 'execFutureLocal'),
+ $extended_args);
+ }
+
+ public function execPassthruWithExtension(
+ $extension,
+ $pattern /* , ... */) {
+
+ $args = func_get_args();
+ $extended_args = call_user_func_array(
+ array($this, 'buildMercurialExtensionCommand'),
+ $args);
+
+ return call_user_func_array(
+ array($this, 'execPassthru'),
+ $extended_args);
+ }
+
private function executeMercurialFeatureTest($feature, $resolve) {
if (array_key_exists($feature, $this->featureResults)) {
return $this->featureResults[$feature];
@@ -1059,8 +1174,9 @@
private function newMercurialFeatureFuture($feature) {
switch ($feature) {
case 'shelve':
- return $this->execFutureLocal(
- '--config extensions.shelve= shelve --help --');
+ return $this->execFutureLocalWithExtension(
+ 'shelve',
+ 'shelve --help --');
case 'evolve':
return $this->execFutureLocal('prune --help --');
default:
@@ -1094,17 +1210,6 @@
return new ArcanistMercurialRepositoryRemoteQuery();
}
- public function getMercurialExtensionArguments() {
- $path = phutil_get_library_root('arcanist');
- $path = dirname($path);
- $path = $path.'/support/hg/arc-hg.py';
-
- return array(
- '--config',
- 'extensions.arc-hg='.$path,
- );
- }
-
protected function newNormalizedURI($uri) {
return new ArcanistRepositoryURINormalizer(
ArcanistRepositoryURINormalizer::TYPE_MERCURIAL,
diff --git a/src/repository/marker/ArcanistMercurialRepositoryMarkerQuery.php b/src/repository/marker/ArcanistMercurialRepositoryMarkerQuery.php
--- a/src/repository/marker/ArcanistMercurialRepositoryMarkerQuery.php
+++ b/src/repository/marker/ArcanistMercurialRepositoryMarkerQuery.php
@@ -19,12 +19,6 @@
// to provide a command which works like "git for-each-ref" locally and
// "git ls-remote" when given a remote.
- $argv = array();
- foreach ($api->getMercurialExtensionArguments() as $arg) {
- $argv[] = $arg;
- }
- $argv[] = 'arc-ls-markers';
-
// NOTE: In remote mode, we're using passthru and a tempfile on this
// because it's a remote command and may prompt the user to provide
// credentials interactively. In local mode, we can just read stdout.
@@ -33,20 +27,17 @@
$tmpfile = new TempFile();
Filesystem::remove($tmpfile);
+ $argv = array();
$argv[] = '--output';
$argv[] = phutil_string_cast($tmpfile);
- }
-
- $argv[] = '--';
-
- if ($remote !== null) {
+ $argv[] = '--';
$argv[] = $remote->getRemoteName();
- }
- if ($remote !== null) {
- $passthru = $api->newPassthru('%Ls', $argv);
+ $err = $api->execPassthruWithExtension(
+ 'arc-hg',
+ 'arc-ls-markers %Ls',
+ $argv);
- $err = $passthru->execute();
if ($err) {
throw new Exception(
pht(
@@ -57,8 +48,10 @@
$raw_data = Filesystem::readFile($tmpfile);
unset($tmpfile);
} else {
- $future = $api->newFuture('%Ls', $argv);
- list($raw_data) = $future->resolve();
+ $future = $api->execFutureLocalWithExtension(
+ 'arc-hg',
+ 'arc-ls-markers --');
+ list($err, $raw_data) = $future->resolve();
}
$items = phutil_json_decode($raw_data);
diff --git a/src/repository/state/ArcanistMercurialLocalState.php b/src/repository/state/ArcanistMercurialLocalState.php
--- a/src/repository/state/ArcanistMercurialLocalState.php
+++ b/src/repository/state/ArcanistMercurialLocalState.php
@@ -160,8 +160,9 @@
'arc-%s',
Filesystem::readRandomCharacters(12));
- $api->execxLocal(
- '--config extensions.shelve= shelve --unknown --name %s --',
+ $api->execxLocalWithExtension(
+ 'shelve',
+ 'shelve --unknown --name %s --',
$stash_ref);
$log->writeStatus(
@@ -179,16 +180,18 @@
pht('UNSHELVE'),
pht('Restoring uncommitted changes to working copy.'));
- $api->execxLocal(
- '--config extensions.shelve= unshelve --keep --name %s --',
+ $api->execxLocalWithExtension(
+ 'shelve',
+ 'unshelve --keep --name %s --',
$stash_ref);
}
protected function discardStash($stash_ref) {
$api = $this->getRepositoryAPI();
- $api->execxLocal(
- '--config extensions.shelve= shelve --delete %s --',
+ $api->execxLocalWithExtension(
+ 'shelve',
+ 'shelve --delete %s --',
$stash_ref);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Nov 28, 8:52 PM (13 h, 2 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6799122
Default Alt Text
D21697.diff (10 KB)
Attached To
Mode
D21697: Refactor how Mercurial runs commands that require extensions
Attached
Detach File
Event Timeline
Log In to Comment