mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-26 08:42:40 +01:00
Use a temporary file to execute arc patch
Summary: Piping data around on Windows doesn't work well when it contains zany characters like "null" and "newline". Fixes T3266. Instead of piping data into `git apply`, write to a temporary file. Test Plan: Ran `arc patch`, got good results. >>> [17] <exec> $ git apply --index --reject -- '/private/var/folders/8k/c3vkmjy5335gcxdzxkhwq82w0000gn/T/7z9iea6srikoo0sc/4266-ZEyvz9' Reviewers: btrahan, hach-que Reviewed By: hach-que CC: aran Maniphest Tasks: T3266 Differential Revision: https://secure.phabricator.com/D6070
This commit is contained in:
parent
50419e584d
commit
ae66d4caa9
4 changed files with 38 additions and 24 deletions
|
@ -101,12 +101,7 @@ final class ArcanistJSHintLinter extends ArcanistLinter {
|
||||||
return $bin;
|
return $bin;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look for globally installed JSHint
|
if (!Filesystem::binaryExists($bin)) {
|
||||||
list($err) = (phutil_is_windows()
|
|
||||||
? exec_manual('where %s', $bin)
|
|
||||||
: exec_manual('which %s', $bin));
|
|
||||||
|
|
||||||
if ($err) {
|
|
||||||
throw new ArcanistUsageException(
|
throw new ArcanistUsageException(
|
||||||
"JSHint does not appear to be installed on this system. Install it ".
|
"JSHint does not appear to be installed on this system. Install it ".
|
||||||
"(e.g., with 'npm install jshint -g') or configure ".
|
"(e.g., with 'npm install jshint -g') or configure ".
|
||||||
|
|
|
@ -29,6 +29,27 @@ final class ArcanistGitAPI extends ArcanistRepositoryAPI {
|
||||||
return $future;
|
return $future;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function execPassthru($pattern /* , ... */) {
|
||||||
|
$args = func_get_args();
|
||||||
|
|
||||||
|
static $git = null;
|
||||||
|
if ($git === null) {
|
||||||
|
if (phutil_is_windows()) {
|
||||||
|
// NOTE: On Windows, phutil_passthru() uses 'bypass_shell' because
|
||||||
|
// everything goes to hell if we don't. We must provide an absolute
|
||||||
|
// path to Git for this to work properly.
|
||||||
|
$git = Filesystem::resolveBinary('git');
|
||||||
|
$git = csprintf('%s', $git);
|
||||||
|
} else {
|
||||||
|
$git = 'git';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$args[0] = $git.' '.$args[0];
|
||||||
|
|
||||||
|
return call_user_func_array('phutil_passthru', $args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getSourceControlSystemName() {
|
public function getSourceControlSystemName() {
|
||||||
return 'git';
|
return 'git';
|
||||||
|
|
|
@ -45,7 +45,7 @@ final class ArcanistMercurialAPI extends ArcanistRepositoryAPI {
|
||||||
$args[0] = 'HGPLAIN=1 hg '.$args[0];
|
$args[0] = 'HGPLAIN=1 hg '.$args[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
return call_user_func_array("phutil_passthru", $args);
|
return call_user_func_array('phutil_passthru', $args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSourceControlSystemName() {
|
public function getSourceControlSystemName() {
|
||||||
|
|
|
@ -672,26 +672,24 @@ EOTEXT
|
||||||
|
|
||||||
return $patch_err;
|
return $patch_err;
|
||||||
} else if ($repository_api instanceof ArcanistGitAPI) {
|
} else if ($repository_api instanceof ArcanistGitAPI) {
|
||||||
$future = $repository_api->execFutureLocal(
|
|
||||||
'apply --index --reject');
|
|
||||||
$future->write($bundle->toGitPatch());
|
|
||||||
|
|
||||||
try {
|
$patchfile = new TempFile();
|
||||||
$future->resolvex();
|
Filesystem::writeFile($patchfile, $bundle->toGitPatch());
|
||||||
} catch (CommandException $ex) {
|
|
||||||
|
$err = $repository_api->execPassthru(
|
||||||
|
'apply --index --reject -- %s',
|
||||||
|
$patchfile);
|
||||||
|
|
||||||
|
if ($err) {
|
||||||
echo phutil_console_format(
|
echo phutil_console_format(
|
||||||
"\n<bg:red>** Patch Failed! **</bg>\n");
|
"\n<bg:red>** Patch Failed! **</bg>\n");
|
||||||
$stderr = $ex->getStdErr();
|
|
||||||
if (preg_match('/already exists in working directory/', $stderr)) {
|
// NOTE: Git patches may fail if they change the case of a filename
|
||||||
echo phutil_console_wrap(
|
// (for instance, from 'example.c' to 'Example.c'). As of now, Git
|
||||||
phutil_console_format(
|
// can not apply these patches on case-insensitive filesystems and
|
||||||
"\n<bg:yellow>** WARNING **</bg> This patch may have failed ".
|
// there is no way to build a patch which works.
|
||||||
"because it attempts to change the case of a filename (for ".
|
|
||||||
"instance, from 'example.c' to 'Example.c'). Git cannot apply ".
|
throw new ArcanistUsageException("Unable to apply patch!");
|
||||||
"patches like this on case-insensitive filesystems. You must ".
|
|
||||||
"apply this patch manually.\n"));
|
|
||||||
}
|
|
||||||
throw $ex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->shouldCommit()) {
|
if ($this->shouldCommit()) {
|
||||||
|
|
Loading…
Reference in a new issue