diff --git a/src/lint/linter/ArcanistJSHintLinter.php b/src/lint/linter/ArcanistJSHintLinter.php index 9a066dae..849bb227 100644 --- a/src/lint/linter/ArcanistJSHintLinter.php +++ b/src/lint/linter/ArcanistJSHintLinter.php @@ -101,12 +101,7 @@ final class ArcanistJSHintLinter extends ArcanistLinter { return $bin; } - // Look for globally installed JSHint - list($err) = (phutil_is_windows() - ? exec_manual('where %s', $bin) - : exec_manual('which %s', $bin)); - - if ($err) { + if (!Filesystem::binaryExists($bin)) { throw new ArcanistUsageException( "JSHint does not appear to be installed on this system. Install it ". "(e.g., with 'npm install jshint -g') or configure ". diff --git a/src/repository/api/ArcanistGitAPI.php b/src/repository/api/ArcanistGitAPI.php index 17475884..da5bdcb2 100644 --- a/src/repository/api/ArcanistGitAPI.php +++ b/src/repository/api/ArcanistGitAPI.php @@ -29,6 +29,27 @@ final class ArcanistGitAPI extends ArcanistRepositoryAPI { 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() { return 'git'; diff --git a/src/repository/api/ArcanistMercurialAPI.php b/src/repository/api/ArcanistMercurialAPI.php index 1c80dc59..c6e6796f 100644 --- a/src/repository/api/ArcanistMercurialAPI.php +++ b/src/repository/api/ArcanistMercurialAPI.php @@ -45,7 +45,7 @@ final class ArcanistMercurialAPI extends ArcanistRepositoryAPI { $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() { diff --git a/src/workflow/ArcanistPatchWorkflow.php b/src/workflow/ArcanistPatchWorkflow.php index d353513b..36a32098 100644 --- a/src/workflow/ArcanistPatchWorkflow.php +++ b/src/workflow/ArcanistPatchWorkflow.php @@ -672,26 +672,24 @@ EOTEXT return $patch_err; } else if ($repository_api instanceof ArcanistGitAPI) { - $future = $repository_api->execFutureLocal( - 'apply --index --reject'); - $future->write($bundle->toGitPatch()); - try { - $future->resolvex(); - } catch (CommandException $ex) { + $patchfile = new TempFile(); + Filesystem::writeFile($patchfile, $bundle->toGitPatch()); + + $err = $repository_api->execPassthru( + 'apply --index --reject -- %s', + $patchfile); + + if ($err) { echo phutil_console_format( "\n** Patch Failed! **\n"); - $stderr = $ex->getStdErr(); - if (preg_match('/already exists in working directory/', $stderr)) { - echo phutil_console_wrap( - phutil_console_format( - "\n** WARNING ** This patch may have failed ". - "because it attempts to change the case of a filename (for ". - "instance, from 'example.c' to 'Example.c'). Git cannot apply ". - "patches like this on case-insensitive filesystems. You must ". - "apply this patch manually.\n")); - } - throw $ex; + + // NOTE: Git patches may fail if they change the case of a filename + // (for instance, from 'example.c' to 'Example.c'). As of now, Git + // can not apply these patches on case-insensitive filesystems and + // there is no way to build a patch which works. + + throw new ArcanistUsageException("Unable to apply patch!"); } if ($this->shouldCommit()) {