function it_should_be_possible_to_configure_the_process_timeout(GrumPHP $config, ExternalCommand $externalCommandLocator) { $config->getProcessTimeout()->willReturn(120); $arguments = new ProcessArgumentsCollection(array('/usr/bin/grumphp')); $process = $this->buildProcess($arguments); $process->getTimeout()->shouldBe(120.0); }
/** * @param ContextInterface $context * * @throws FailureException if any of the tasks fail */ public function run(ContextInterface $context) { $failures = false; $messages = array(); $tasks = $this->tasks->filterByContext($context)->sortByPriority($this->grumPHP); $this->eventDispatcher->dispatch(RunnerEvents::RUNNER_RUN, new RunnerEvent($tasks)); foreach ($tasks as $task) { try { $this->eventDispatcher->dispatch(TaskEvents::TASK_RUN, new TaskEvent($task)); $task->run($context); $this->eventDispatcher->dispatch(TaskEvents::TASK_COMPLETE, new TaskEvent($task)); } catch (RuntimeException $e) { $this->eventDispatcher->dispatch(TaskEvents::TASK_FAILED, new TaskFailedEvent($task, $e)); $messages[] = $e->getMessage(); $failures = true; if ($this->grumPHP->stopOnFailure()) { break; } } } if ($failures) { $this->eventDispatcher->dispatch(RunnerEvents::RUNNER_FAILED, new RunnerFailedEvent($tasks, $messages)); throw new FailureException(implode(PHP_EOL, $messages)); } $this->eventDispatcher->dispatch(RunnerEvents::RUNNER_COMPLETE, new RunnerEvent($tasks)); }
/** * @param InputInterface $input * @param OutputInterface $output * * @return int|void */ public function execute(InputInterface $input, OutputInterface $output) { $this->input = $input; $gitHooksPath = $this->paths()->getGitHooksDir(); $resourceHooksPath = $this->paths()->getGitHookTemplatesDir() . $this->grumPHP->getHooksPreset(); $resourceHooksPath = $this->paths()->getPathWithTrailingSlash($resourceHooksPath); $customHooksPath = $this->paths()->getPathWithTrailingSlash($this->grumPHP->getHooksDir()); // Some git clients do not automatically create a git hooks folder. if (!$this->filesystem->exists($gitHooksPath)) { $this->filesystem->mkdir($gitHooksPath); $output->writeln(sprintf('<fg=yellow>Created git hooks folder at: %s</fg=yellow>', $gitHooksPath)); } foreach (self::$hooks as $hook) { $gitHook = $gitHooksPath . $hook; $hookTemplate = new SplFileInfo($resourceHooksPath . $hook); if ($customHooksPath && $this->filesystem->exists($customHooksPath . $hook)) { $hookTemplate = new SplFileInfo($customHooksPath . $hook); } if (!$this->filesystem->exists($hookTemplate)) { throw new RuntimeException(sprintf('Could not find hook template for %s at %s.', $hook, $hookTemplate)); } $content = $this->parseHookBody($hook, $hookTemplate); $this->filesystem->dumpFile($gitHook, $content); $this->filesystem->chmod($gitHook, 0775); } $output->writeln('<fg=yellow>Watch out! GrumPHP is sniffing your commits!<fg=yellow>'); }
function it_should_not_run_when_disabled(GrumPHP $grumPHP, Repository $repository) { $event = new RunnerEvent(new TasksCollection(), new GitPreCommitContext(new FilesCollection()), new TaskResultCollection()); $grumPHP->ignoreUnstagedChanges()->willReturn(false); $this->saveStash($event); $this->popStash($event); $repository->run(Argument::cetera())->shouldNotBeCalled(); }
function it_runs_with_additional_modifiers(GrumPHP $grumPHP, GitCommitMsgContext $context) { $grumPHP->getTaskConfiguration('git_commit_message')->willReturn(['matchers' => ['/.*ümlaut/'], 'additional_modifiers' => 'u']); $context->getCommitMessage()->willReturn('message containing ümlaut'); $result = $this->run($context); $result->shouldBeAnInstanceOf(TaskResultInterface::class); $result->isPassed()->shouldBe(true); }
/** * @param ProcessArgumentsCollection $arguments * * @return Process * @throws \GrumPHP\Exception\PlatformException */ public function buildProcess(ProcessArgumentsCollection $arguments) { $builder = SymfonyProcessBuilder::create($arguments->getValues()); $builder->setTimeout($this->config->getProcessTimeout()); $process = $builder->getProcess(); $this->logProcessInVerboseMode($process); $this->guardWindowsCmdMaxInputStringLimitation($process); return $process; }
function it_runs_the_suite_but_not_reaching_coverage(GrumPHP $grumPHP, GitCommitMsgContext $context) { $filename = dirname(dirname(dirname(__DIR__))) . '/test/fixtures/clover_coverage/60-percent-coverage.xml'; $grumPHP->getTaskConfiguration('clover_coverage')->willReturn(['clover_file' => $filename, 'level' => 100]); $result = $this->run($context); $result->shouldBeAnInstanceOf(TaskResultInterface::class); $result->getResultCode()->shouldBe(TaskResult::FAILED); $result->getMessage()->shouldBe('Code coverage is 60%, which is below the accepted 100%' . PHP_EOL); }
/** * This method sorts the tasks by highest priority first. * * @param GrumPHP $grumPHP * * @return TasksCollection */ public function sortByPriority(GrumPHP $grumPHP) { $priorityQueue = new SplPriorityQueue(); $stableSortIndex = PHP_INT_MAX; foreach ($this->getIterator() as $task) { $metadata = $grumPHP->getTaskMetadata($task->getName()); $priorityQueue->insert($task, array($metadata['priority'], $stableSortIndex--)); } return new TasksCollection(array_values(iterator_to_array($priorityQueue))); }
function it_runs_the_suite_when_composer_has_changed_and_run_always_is_false(GrumPHP $grumPHP, ProcessBuilder $processBuilder, Process $process, ContextInterface $context) { $grumPHP->getTaskConfiguration('securitychecker')->willReturn(array('run_always' => false)); $arguments = new ProcessArgumentsCollection(); $processBuilder->createArgumentsForCommand('security-checker')->willReturn($arguments); $processBuilder->buildProcess($arguments)->willReturn($process); $process->run()->shouldBeCalled(); $process->isSuccessful()->willReturn(true); $context->getFiles()->willReturn(new FilesCollection(array(new SplFileInfo('composer.lock', '.', 'composer.lock')))); $this->run($context); }
function it_throws_exception_if_the_process_is_successfull(GrumPHP $grumPHP, ProcessBuilder $processBuilder, Process $process, ContextInterface $context) { $grumPHP->getTaskConfiguration('git_blacklist')->willReturn(array('keywords' => array('var_dump('))); $arguments = new ProcessArgumentsCollection(); $processBuilder->createArgumentsForCommand('git')->willReturn($arguments); $processBuilder->buildProcess($arguments)->willReturn($process); $process->run()->shouldBeCalled(); $process->isSuccessful()->willReturn(true); $process->getOutput()->shouldBeCalled(); $context->getFiles()->willReturn(new FilesCollection(array(new SplFileInfo('file1.php', '.', 'file1.php')))); $this->shouldThrow('GrumPHP\\Exception\\RuntimeException')->duringRun($context); }
function it_runs_if_there_are_no_files_but_always_execute_is_passed(GrumPHP $grumPHP, Process $process, ProcessBuilder $processBuilder, ContextInterface $context) { $grumPHP->getTaskConfiguration('phpunit')->willReturn(['always_execute' => true]); $arguments = new ProcessArgumentsCollection(); $processBuilder->createArgumentsForCommand('phpunit')->willReturn($arguments); $processBuilder->buildProcess($arguments)->willReturn($process); $process->run()->shouldBeCalled(); $process->isSuccessful()->willReturn(true); $context->getFiles()->willReturn(new FilesCollection()); $result = $this->run($context); $result->shouldBeAnInstanceOf(TaskResultInterface::class); $result->isPassed()->shouldBe(true); }
function it_throws_exception_if_the_process_is_successfull(GrumPHP $grumPHP, ProcessBuilder $processBuilder, Process $process, ContextInterface $context) { $grumPHP->getTaskConfiguration('git_blacklist')->willReturn(['keywords' => ['var_dump(']]); $arguments = new ProcessArgumentsCollection(); $processBuilder->createArgumentsForCommand('git')->willReturn($arguments); $processBuilder->buildProcess($arguments)->willReturn($process); $process->run()->shouldBeCalled(); $process->isSuccessful()->willReturn(true); $context->getFiles()->willReturn(new FilesCollection([new SplFileInfo('file1.php', '.', 'file1.php')])); $result = $this->run($context); $result->shouldBeAnInstanceOf(TaskResultInterface::class); $result->isPassed()->shouldBe(false); }
function it_runs_the_suite_for_all_files(GrumPHP $grumPHP, ProcessBuilder $processBuilder, Process $process, RunContext $context, PhpCsFixerFormatter $formatter) { $grumPHP->getTaskConfiguration('phpcsfixer')->willReturn(array('config_file' => '.php_cs')); $formatter->resetCounter()->shouldBeCalled(); $context->getFiles()->willReturn(new FilesCollection(array($file1 = new SplFileInfo('file1.php', '.', 'file1.php'), $file2 = new SplFileInfo('file2.php', '.', 'file2.php')))); $processBuilder->createArgumentsForCommand('php-cs-fixer')->willReturn(new ProcessArgumentsCollection()); $processBuilder->buildProcess(Argument::that(function (ProcessArgumentsCollection $args) use($file1, $file2) { return !($args->contains($file1) || $args->contains($file2)); }))->willReturn($process); $process->run()->shouldBeCalled(); $process->isSuccessful()->willReturn(true); $result = $this->run($context); $result->shouldBeAnInstanceOf('GrumPHP\\Runner\\TaskResultInterface'); $result->isPassed()->shouldBe(true); }
/** * @return bool */ private function handleProcess(Process $process) { if ($process->isStarted()) { if ($process->isTerminated()) { $this->running--; return true; } return false; } // Only start a new process if we haven't reached the limit yet. if ($this->running < $this->config->getProcessAsyncLimit()) { $process->start(); $this->running++; } return false; }
/** * Find the relative bin directory * * @return string */ public function getBinDir() { $binDir = $this->config->getBinDir(); if (!$this->fileSystem->exists($binDir)) { throw new RuntimeException('The configured BIN directory could not be found.'); } return $this->getRelativePath($binDir); }
function it_should_sort_on_priority(TaskInterface $task1, TaskInterface $task2, TaskInterface $task3, GrumPHP $grumPHP) { $this->beConstructedWith(array($task1, $task2, $task3)); $task1->getName()->willReturn('task1'); $task2->getName()->willReturn('task2'); $task3->getName()->willReturn('task3'); $grumPHP->getTaskMetadata('task1')->willReturn(array('priority' => 100)); $grumPHP->getTaskMetadata('task2')->willReturn(array('priority' => 200)); $grumPHP->getTaskMetadata('task3')->willReturn(array('priority' => 100)); $result = $this->sortByPriority($grumPHP); $result->shouldBeAnInstanceOf('GrumPHP\\Collection\\TasksCollection'); $result->count()->shouldBe(3); $tasks = $result->toArray(); $tasks[0]->shouldBe($task2); $tasks[1]->shouldBe($task1); $tasks[2]->shouldBe($task3); }
/** * @return string */ protected function guessGitDir() { $defaultGitDir = $this->config->getGitDir(); try { $topLevel = $this->repository->run('rev-parse', array('--show-toplevel')); } catch (Exception $e) { return $defaultGitDir; } return rtrim($this->paths()->getRelativePath($topLevel), '/'); }
/** * @param TaskInterface $task * @param ContextInterface $context * * @return TaskResultInterface * @throws RuntimeException */ private function runTask(TaskInterface $task, ContextInterface $context) { try { $this->eventDispatcher->dispatch(TaskEvents::TASK_RUN, new TaskEvent($task, $context)); $result = $task->run($context); } catch (RuntimeException $e) { $result = TaskResult::createFailed($task, $context, $e->getMessage()); } if (!$result instanceof TaskResultInterface) { throw RuntimeException::invalidTaskReturnType($task); } if (!$result->isPassed() && !$this->grumPHP->isBlockingTask($task->getName())) { $result = TaskResult::createNonBlockingFailed($result->getTask(), $result->getContext(), $result->getMessage()); } if (!$result->isPassed()) { $e = new RuntimeException($result->getMessage()); $this->eventDispatcher->dispatch(TaskEvents::TASK_FAILED, new TaskFailedEvent($task, $context, $e)); return $result; } $this->eventDispatcher->dispatch(TaskEvents::TASK_COMPLETE, new TaskEvent($task, $context)); return $result; }
function let(GrumPHP $grumPHP, ProcessBuilder $processBuilder, ProcessFormatterInterface $formatter) { $grumPHP->getTaskConfiguration('composer_script')->willReturn(['script' => 'test']); $this->beConstructedWith($grumPHP, $processBuilder, $formatter); }
/** * {@inheritdoc} */ public function getConfiguration() { return array_merge($this->getDefaultConfiguration(), $this->grumPHP->getTaskConfiguration($this->getName())); }
function let(GrumPHP $grumPHP, YamlLinter $linter) { $grumPHP->getTaskConfiguration('yamllint')->willReturn([]); $this->beConstructedWith($grumPHP, $linter); }
function let(GrumPHP $grumPHP, ProcessBuilder $processBuilder, ProcessFormatterInterface $formatter) { $grumPHP->getTaskConfiguration('shell')->willReturn(['scripts' => ['script.sh']]); $this->beConstructedWith($grumPHP, $processBuilder, $formatter); }
/** * Return a list of all available tasks * * @return array */ protected function getAvailableTasks(GrumPHP $config) { return $config->getRegisteredTasks(); }
function let(GrumPHP $grumPHP, JsonLinter $linter) { $grumPHP->getTaskConfiguration('jsonlint')->willReturn(array()); $this->beConstructedWith($grumPHP, $linter); }
function let(GrumPHP $grumPHP, ProcessBuilder $processBuilder) { $grumPHP->getTaskConfiguration('behat')->willReturn(array()); $this->beConstructedWith($grumPHP, $processBuilder); }
/** * {@inheritdoc} */ public function getConfiguration() { $configured = $this->grumPHP->getTaskConfiguration($this->getName()); return $this->getConfigurableOptions()->resolve($configured); }
function let(GrumPHP $grumPHP, ProcessBuilder $processBuilder, ProcessFormatterInterface $formatter) { $grumPHP->getTaskConfiguration('phing')->willReturn([]); $this->beConstructedWith($grumPHP, $processBuilder, $formatter); }
function let(GrumPHP $grumPHP, ProcessBuilder $processBuilder, ProcessFormatterInterface $formatter) { $grumPHP->getTaskConfiguration('npm_script')->willReturn(['script' => 'test', 'working_directory' => './']); $this->beConstructedWith($grumPHP, $processBuilder, $formatter); }
/** * @param ContextInterface $context * * @return bool */ private function isStashEnabled(ContextInterface $context) { return $this->grumPHP->ignoreUnstagedChanges() && $context instanceof GitPreCommitContext; }
/** * Return a list of all available tasks * * @return array */ protected function getAvailableTasks(GrumPHP $config) { $tasks = $config->getTasks(); return $tasks; }