diff --git a/src/unit/engine/ArcanistBaseUnitTestEngine.php b/src/unit/engine/ArcanistBaseUnitTestEngine.php index 2f7473ee..b9aa9ca4 100644 --- a/src/unit/engine/ArcanistBaseUnitTestEngine.php +++ b/src/unit/engine/ArcanistBaseUnitTestEngine.php @@ -25,6 +25,7 @@ abstract class ArcanistBaseUnitTestEngine { private $workingCopy; private $paths; + private $skipFiles; private $arguments = array(); protected $diffID; private $enableAsyncTests; @@ -54,6 +55,15 @@ abstract class ArcanistBaseUnitTestEngine { return $this->paths; } + final public function setSkipFiles(array $paths) { + $this->skipFiles = $paths; + return $this; + } + + final public function getSkipFiles() { + return $this->skipFiles; + } + final public function setArguments(array $arguments) { $this->arguments = $arguments; return $this; diff --git a/src/unit/engine/PhutilUnitTestEngine.php b/src/unit/engine/PhutilUnitTestEngine.php index 3027ca46..4cfa28e6 100644 --- a/src/unit/engine/PhutilUnitTestEngine.php +++ b/src/unit/engine/PhutilUnitTestEngine.php @@ -77,6 +77,13 @@ final class PhutilUnitTestEngine extends ArcanistBaseUnitTestEngine { } while ($library_path != '.'); } + $skip = array(); + foreach ($this->getSkipFiles() as $skip_path) { + $skip_path = Filesystem::resolvePath($skip_path); + $skip_path = Filesystem::readablePath($skip_path, $library_root); + $skip[$skip_path] = true; + } + // Look for any class that extends ArcanistPhutilTestCase inside a // __tests__ directory in any parent directory of every affected file. // @@ -100,6 +107,9 @@ final class PhutilUnitTestEngine extends ArcanistBaseUnitTestEngine { ->selectAndLoadSymbols(); foreach ($symbols as $symbol) { + if (isset($skip[$symbol['where']])) { + continue; + } $run_tests[$symbol['name']] = true; } } diff --git a/src/workflow/ArcanistBaseWorkflow.php b/src/workflow/ArcanistBaseWorkflow.php index 19841126..e1776129 100644 --- a/src/workflow/ArcanistBaseWorkflow.php +++ b/src/workflow/ArcanistBaseWorkflow.php @@ -532,11 +532,7 @@ abstract class ArcanistBaseWorkflow { } public function getArgument($key, $default = null) { - $args = $this->arguments; - if (!array_key_exists($key, $args)) { - return $default; - } - return $args[$key]; + return idx($this->arguments, $key, $default); } final public function getCompleteArgumentSpecification() { @@ -567,6 +563,12 @@ abstract class ArcanistBaseWorkflow { } } + foreach ($spec as $long => $options) { + if (!empty($options['repeat'])) { + $dict[$long] = array(); + } + } + $more = array(); for ($ii = 0; $ii < count($args); $ii++) { $arg = $args[$ii]; @@ -603,7 +605,11 @@ abstract class ArcanistBaseWorkflow { throw new ArcanistUsageException( "Option '{$arg}' requires a parameter."); } - $dict[$arg_key] = $args[$ii + 1]; + if (!empty($options['repeat'])) { + $dict[$arg_key][] = $args[$ii + 1]; + } else { + $dict[$arg_key] = $args[$ii + 1]; + } $ii++; } } diff --git a/src/workflow/ArcanistUnitWorkflow.php b/src/workflow/ArcanistUnitWorkflow.php index 4dcc44de..d6d7cf82 100644 --- a/src/workflow/ArcanistUnitWorkflow.php +++ b/src/workflow/ArcanistUnitWorkflow.php @@ -68,6 +68,11 @@ EOTEXT 'help' => "Override configured unit engine for this project." ), + 'skip' => array( + 'param' => 'path', + 'help' => "Specify file paths that will be ignored.", + 'repeat' => true, + ), 'coverage' => array( 'help' => 'Always enable coverage information.', 'conflicts' => array( @@ -127,6 +132,7 @@ EOTEXT $this->engine = newv($engine_class, array()); $this->engine->setWorkingCopy($working_copy); $this->engine->setPaths($paths); + $this->engine->setSkipFiles($this->getArgument('skip')); $this->engine->setArguments($this->getPassthruArgumentsAsMap('unit')); $enable_coverage = null; // Means "default".