Skip to content

Commit

Permalink
Feature/deptrac (#337)
Browse files Browse the repository at this point in the history
* basic setup deptrac

* added config options and documentation

* updated readme

* updated task option configuration
  • Loading branch information
lykciv authored and veewee committed Apr 12, 2017
1 parent c0b29df commit 55ffb2b
Show file tree
Hide file tree
Showing 6 changed files with 273 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ parameters:
codeception: ~
composer: ~
composer_script: ~
deptrac: ~
doctrine_orm: ~
gherkin: ~
git_blacklist: ~
Expand Down
2 changes: 2 additions & 0 deletions doc/tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ parameters:
clover_coverage: ~
codeception: ~
composer: ~
deptrac: ~
composer_script: ~
doctrine_orm: ~
gherkin: ~
Expand Down Expand Up @@ -61,6 +62,7 @@ Every task has it's own default configuration. It is possible to overwrite the p
- [Composer](tasks/composer.md)
- [Composer Script](tasks/composer_script.md)
- [Doctrine ORM](tasks/doctrine_orm.md)
- [Deptrac](tasks/deptrac.md)
- [Gherkin](tasks/gherkin.md)
- [Git blacklist](tasks/git_blacklist.md)
- [Git branch name](tasks/git_branch_name.md)
Expand Down
57 changes: 57 additions & 0 deletions doc/tasks/deptrac.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Deptrac

Follow the [installation instructions](https://github.com/sensiolabs-de/deptrac#installation) to add deptrac to your
project.

The Deptrac task will check for dependencies between the software layers of your project. It lives under the `deptrac`
namespace and has following configurable parameters:


```yaml
# grumphp.yml
parameters:
tasks:
deptrac:
depfile: ~
formatter_graphviz: ~
formatter_graphviz_display: ~
formatter_graphviz_dump_image: ~
formatter_graphviz_dump_dot: ~
formatter_graphviz_dump_html: ~
```
**depfile**
*Default: null*
Set path to deptrac configuration file. Example: `/var/www/src/depfile.yml`

**formatter_graphviz**

*Default: false*

Set to `true` to enable the graphviz formatter.

**formatter_graphviz_display**

*Default: false*

Open the generated graphviz image. Set to `true` to activate.

**formatter_graphviz_dump_image**

*Default: null*

Set path to a dumped png file.

**formatter_graphviz_dump_dot**

*Default: null*

Set path to a dumped dot file.

**formatter_graphviz_dump_html**

*Default: null*

Set path to a dumped html file.
9 changes: 9 additions & 0 deletions resources/config/tasks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ services:
tags:
- {name: grumphp.task, config: composer_script}

task.deptrac:
class: GrumPHP\Task\Deptrac
arguments:
- '@config'
- '@process_builder'
- '@formatter.raw_process'
tags:
- {name: grumphp.task, config: deptrac}

task.doctrine_orm:
class: GrumPHP\Task\DoctrineOrm
arguments:
Expand Down
110 changes: 110 additions & 0 deletions spec/Task/DeptracSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<?php

namespace spec\GrumPHP\Task;

use GrumPHP\Collection\FilesCollection;
use GrumPHP\Collection\ProcessArgumentsCollection;
use GrumPHP\Configuration\GrumPHP;
use GrumPHP\Formatter\ProcessFormatterInterface;
use GrumPHP\Process\ProcessBuilder;
use GrumPHP\Runner\TaskResult;
use GrumPHP\Runner\TaskResultInterface;
use GrumPHP\Task\Context\ContextInterface;
use GrumPHP\Task\Context\GitPreCommitContext;
use GrumPHP\Task\Context\RunContext;
use GrumPHP\Task\Deptrac;
use PhpSpec\ObjectBehavior;
use Symfony\Component\Finder\SplFileInfo;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Process\Process;

class DeptracSpec extends ObjectBehavior
{
function let(GrumPHP $grumPHP, ProcessBuilder $processBuilder, ProcessFormatterInterface $formatter)
{
$grumPHP->getTaskConfiguration('deptrac')->willReturn([]);
$this->beConstructedWith($grumPHP, $processBuilder, $formatter);
}

function it_is_initializable()
{
$this->shouldHaveType(Deptrac::class);
}

function it_should_have_a_name()
{
$this->getName()->shouldBe('deptrac');
}

function it_should_have_configurable_options()
{
$options = $this->getConfigurableOptions();
$options->shouldBeAnInstanceOf(OptionsResolver::class);
$options->getDefinedOptions()->shouldContain('depfile');
$options->getDefinedOptions()->shouldContain('formatter_graphviz');
$options->getDefinedOptions()->shouldContain('formatter_graphviz_display');
$options->getDefinedOptions()->shouldContain('formatter_graphviz_dump_image');
$options->getDefinedOptions()->shouldContain('formatter_graphviz_dump_dot');
$options->getDefinedOptions()->shouldContain('formatter_graphviz_dump_html');
}

function it_should_run_in_git_pre_commit_context(GitPreCommitContext $context)
{
$this->canRunInContext($context)->shouldReturn(true);
}

function it_should_run_in_run_context(RunContext $context)
{
$this->canRunInContext($context)->shouldReturn(true);
}

function it_does_not_do_anything_if_there_are_no_files(ProcessBuilder $processBuilder, ContextInterface $context)
{
$processBuilder->createArgumentsForCommand('deptrac')->shouldNotBeCalled();
$processBuilder->buildProcess()->shouldNotBeCalled();
$context->getFiles()->willReturn(new FilesCollection());

$result = $this->run($context);
$result->shouldBeAnInstanceOf(TaskResultInterface::class);
$result->getResultCode()->shouldBe(TaskResult::SKIPPED);
}

function it_runs_the_suite(ProcessBuilder $processBuilder, Process $process, ContextInterface $context)
{
$arguments = new ProcessArgumentsCollection();
$processBuilder->createArgumentsForCommand('deptrac')->willReturn($arguments);
$processBuilder->buildProcess($arguments)->willReturn($process);

$process->run()->shouldBeCalled();
$process->isSuccessful()->willReturn(true);

$context->getFiles()->willReturn(new FilesCollection([
new SplFileInfo('test1.php', '.', 'test2.php')
]));

$result = $this->run($context);
$result->shouldBeAnInstanceOf(TaskResultInterface::class);
$result->isPassed()->shouldBe(true);
}

function it_throws_an_exception_if_the_process_fails(
ProcessBuilder $processBuilder,
Process $process,
ContextInterface $context
) {
$arguments = new ProcessArgumentsCollection();
$processBuilder->createArgumentsForCommand('deptrac')->willReturn($arguments);
$processBuilder->buildProcess($arguments)->willReturn($process);

$process->run()->shouldBeCalled();
$process->isSuccessful()->willReturn(false);

$context->getFiles()->willReturn(new FilesCollection([
new SplFileInfo('test1.php', '.', 'test2.php')
]));

$result = $this->run($context);
$result->shouldBeAnInstanceOf(TaskResultInterface::class);
$result->isPassed()->shouldBe(false);
}
}
94 changes: 94 additions & 0 deletions src/Task/Deptrac.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

namespace GrumPHP\Task;

use GrumPHP\Runner\TaskResult;
use GrumPHP\Runner\TaskResultInterface;
use GrumPHP\Task\Context\ContextInterface;
use GrumPHP\Task\Context\GitPreCommitContext;
use GrumPHP\Task\Context\RunContext;
use Symfony\Component\OptionsResolver\OptionsResolver;

/**
* Deptrac task
*/
class Deptrac extends AbstractExternalTask
{
/**
* @return string
*/
public function getName()
{
return 'deptrac';
}

/**
* @return OptionsResolver
*/
public function getConfigurableOptions()
{
$resolver = new OptionsResolver();
$resolver->setDefaults([
'depfile' => null,
'formatter_graphviz' => false,
'formatter_graphviz_display' => false,
'formatter_graphviz_dump_image' => null,
'formatter_graphviz_dump_dot' => null,
'formatter_graphviz_dump_html' => null,
]);

$resolver->addAllowedTypes('depfile', ['null', 'string']);
$resolver->addAllowedTypes('formatter_graphviz', ['bool']);
$resolver->addAllowedTypes('formatter_graphviz_display', ['bool']);
$resolver->addAllowedTypes('formatter_graphviz_dump_image', ['null', 'string']);
$resolver->addAllowedTypes('formatter_graphviz_dump_dot', ['null', 'string']);
$resolver->addAllowedTypes('formatter_graphviz_dump_html', ['null', 'string']);

return $resolver;
}

/**
* This methods specifies if a task can run in a specific context.
*
* @param ContextInterface $context
*
* @return bool
*/
public function canRunInContext(ContextInterface $context)
{
return ($context instanceof GitPreCommitContext || $context instanceof RunContext);
}

/**
* @param ContextInterface $context
*
* @return TaskResultInterface
*/
public function run(ContextInterface $context)
{
$config = $this->getConfiguration();

$files = $context->getFiles()->name('*.php');
if (0 === count($files)) {
return TaskResult::createSkipped($this, $context);
}

$arguments = $this->processBuilder->createArgumentsForCommand('deptrac');
$arguments->add('analyze');
$arguments->add('--formatter-graphviz=' . (int)$config['formatter_graphviz']);
$arguments->addOptionalArgument('--formatter-graphviz-display=%s', $config['formatter_graphviz_display']);
$arguments->addOptionalArgument('--formatter-graphviz-dump-image=%s', $config['formatter_graphviz_dump_image']);
$arguments->addOptionalArgument('--formatter-graphviz-dump-dot=%s', $config['formatter_graphviz_dump_dot']);
$arguments->addOptionalArgument('--formatter-graphviz-dump-html=%s', $config['formatter_graphviz_dump_html']);
$arguments->addOptionalArgument('%s', $config['depfile']);

$process = $this->processBuilder->buildProcess($arguments);
$process->run();

if (!$process->isSuccessful()) {
return TaskResult::createFailed($this, $context, $this->formatter->format($process));
}

return TaskResult::createPassed($this, $context);
}
}

0 comments on commit 55ffb2b

Please sign in to comment.