mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-12-25 15:00:57 +01:00
Parse 'hg status -C' to show file move/copy sources
Summary: For Mercurial parsing in Diffusion, it looks like the only command we can use to get move/copy information is "hg status -C --rev <rev>", so add a parser for it. Test Plan: Ran unit tests. Reviewers: Makinde, jungejason, nh, tuomaspelkonen, aran Reviewed By: Makinde CC: aran, Makinde Differential Revision: 958
This commit is contained in:
parent
752ef65020
commit
ef0a9cbb79
4 changed files with 65 additions and 7 deletions
|
@ -30,13 +30,15 @@ final class ArcanistMercurialParser {
|
|||
|
||||
|
||||
/**
|
||||
* Parse the output of "hg status".
|
||||
* Parse the output of "hg status". This provides detailed information, you
|
||||
* can get less detailed information with @{method:parseMercurialStatus}. In
|
||||
* particular, this will parse copy sources as per "hg status -C".
|
||||
*
|
||||
* @param string The stdout from running an "hg status" command.
|
||||
* @return dict Map of paths to ArcanistRepositoryAPI status flags.
|
||||
* @return dict Map of paths to status dictionaries.
|
||||
* @task parse
|
||||
*/
|
||||
public static function parseMercurialStatus($stdout) {
|
||||
public static function parseMercurialStatusDetails($stdout) {
|
||||
$result = array();
|
||||
|
||||
$stdout = trim($stdout);
|
||||
|
@ -44,16 +46,21 @@ final class ArcanistMercurialParser {
|
|||
return $result;
|
||||
}
|
||||
|
||||
$last_path = null;
|
||||
$lines = explode("\n", $stdout);
|
||||
foreach ($lines as $line) {
|
||||
$flags = 0;
|
||||
list($code, $path) = explode(' ', $line, 2);
|
||||
if ($line[1] !== ' ') {
|
||||
throw new Exception("Unparsable Mercurial status line '{$line}'.");
|
||||
}
|
||||
$code = $line[0];
|
||||
$path = substr($line, 2);
|
||||
switch ($code) {
|
||||
case 'A':
|
||||
$flags |= ArcanistRepositoryAPI::FLAG_ADDED;
|
||||
break;
|
||||
case 'R':
|
||||
$flags |= ArcanistRepositoryAPI::FLAG_REMOVED;
|
||||
$flags |= ArcanistRepositoryAPI::FLAG_DELETED;
|
||||
break;
|
||||
case 'M':
|
||||
$flags |= ArcanistRepositoryAPI::FLAG_MODIFIED;
|
||||
|
@ -71,17 +78,45 @@ final class ArcanistMercurialParser {
|
|||
case 'I':
|
||||
// This is "ignored" and included only for completeness.
|
||||
break;
|
||||
case ' ':
|
||||
// This shows the source of a file move, so update the last file we
|
||||
// parsed to set its source.
|
||||
if ($last_path === null) {
|
||||
throw new Exception(
|
||||
"Unexpected copy source in hg status, '{$line}'.");
|
||||
}
|
||||
$result[$last_path]['from'] = $path;
|
||||
continue 2;
|
||||
default:
|
||||
throw new Exception("Unknown Mercurial status '{$code}'.");
|
||||
}
|
||||
|
||||
$result[$path] = $flags;
|
||||
$result[$path] = array(
|
||||
'flags' => $flags,
|
||||
'from' => null,
|
||||
);
|
||||
$last_path = $path;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse the output of "hg status". This provides only basic information, you
|
||||
* can get more detailed information by invoking
|
||||
* @{method:parseMercurialStatusDetails}.
|
||||
*
|
||||
* @param string The stdout from running an "hg status" command.
|
||||
* @return dict Map of paths to ArcanistRepositoryAPI status flags.
|
||||
* @task parse
|
||||
*/
|
||||
public static function parseMercurialStatus($stdout) {
|
||||
$result = self::parseMercurialStatusDetails($stdout);
|
||||
return ipull($result, 'flags');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse the output of "hg log". This also parses "hg outgoing", "hg parents",
|
||||
* and other similar commands. This assumes "--style default".
|
||||
|
|
|
@ -8,5 +8,7 @@
|
|||
|
||||
phutil_require_module('arcanist', 'repository/api/base');
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('ArcanistMercurialParser.php');
|
||||
|
|
|
@ -20,7 +20,7 @@ final class ArcanistMercurialParserTestCase extends ArcanistPhutilTestCase {
|
|||
|
||||
public function testParseAll() {
|
||||
$root = dirname(__FILE__).'/data/';
|
||||
foreach (Filesystem::listDirectory($root) as $file) {
|
||||
foreach (Filesystem::listDirectory($root, $hidden = false) as $file) {
|
||||
$this->parseData(
|
||||
basename($file),
|
||||
Filesystem::readFile($root.'/'.$file));
|
||||
|
@ -64,6 +64,21 @@ final class ArcanistMercurialParserTestCase extends ArcanistPhutilTestCase {
|
|||
array('changed', 'added', 'removed', 'untracked'),
|
||||
array_keys($output));
|
||||
break;
|
||||
case 'status-moves.txt':
|
||||
$output = ArcanistMercurialParser::parseMercurialStatusDetails($data);
|
||||
$this->assertEqual(
|
||||
'move_source',
|
||||
$output['moved_file']['from']);
|
||||
$this->assertEqual(
|
||||
null,
|
||||
$output['changed_file']['from']);
|
||||
$this->assertEqual(
|
||||
'copy_source',
|
||||
$output['copied_file']['from']);
|
||||
$this->assertEqual(
|
||||
null,
|
||||
idx($output, 'copy_source'));
|
||||
break;
|
||||
default:
|
||||
throw new Exception("No test information for test data '{$name}'!");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
M changed_file
|
||||
A moved_file
|
||||
move_source
|
||||
R moved_source
|
||||
A copied_file
|
||||
copy_source
|
Loading…
Reference in a new issue