Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,14 @@ Tactix provides a Symfony Console command `tactix:report` that creates a static
bin/console tactix:report <folder>
# or, when installed as a dependency with optional output directory
vendor/bin/console tactix:report <folder> --out-dir=<out-dir>
# Exclude specific namespaces from the report (can be used multiple times)
vendor/bin/console tactix:report <folder> --exclude-namespace="App\\CLI\\" --exclude-namespace="App\\Infrastructure\\"
```

Options:
- `--out-dir`: Base output directory for reports (defaults to project root)
- `--exclude-namespace`: Namespace prefix to exclude from the report (can be used multiple times). By default, `Doctrine\\`, `Symfony\\`, and `Psr\\` namespaces are excluded. When you provide your own exclusions, you replace these defaults.

Notes:
- the output files index.html, report.js, chart.js, styles.css are created
- the command prints discovered classes and forbidden relations and finishes with `Report written to: ./report/index.html`.
Expand Down
43 changes: 17 additions & 26 deletions src/Command/ReportCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,9 @@ public function __construct(private readonly SerializerInterface $serializer)
protected function configure(): void
{
$this
->addArgument(
'folder',
InputArgument::REQUIRED,
'The source code folder to be checked'
)
->addOption(
'out-dir',
null, InputOption::VALUE_REQUIRED,
'Base output directory for reports (defaults to project root)'
)
->addArgument('folder', InputArgument::REQUIRED, 'The source code folder to be checked')
->addOption('out-dir', null, InputOption::VALUE_REQUIRED, 'Base output directory for reports (defaults to project root)')
->addOption('exclude-namespace', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Namespace prefix to exclude from the report (can be used multiple times)')
;
}

Expand Down Expand Up @@ -91,27 +84,25 @@ private function doExecute(InputInterface $input, OutputInterface $output): void
$io = new SymfonyStyle($input, $output);
$io->title(sprintf('Report for "%s"', $folder));

// Get user-provided namespace exclusions or use sensible defaults
/** @var string[] $excludeNamespaces */
$excludeNamespaces = $input->getOption('exclude-namespace');

// If no exclusions provided, use common vendor/framework namespaces as defaults
if (empty($excludeNamespaces)) {
$excludeNamespaces = [
'Doctrine\\',
'Symfony\\',
'Psr\\',
];
}

/** @var Node[] */
$nodes = array_reduce(
iterator_to_array(YieldNodes::from($folder)),
new NodeReducer(
ignoreTypes: IgnoreableTypes::VALUES,
shouldNotStartWith: [
'App\\Kernel',
'App\\CLI\\',
'App\\DDD\\',
'Doctrine\\',
'Symfony\\',
'Psr\\',
'PhpParser\\',
'phpDocumentor\\',
'Monolog\\',
'OpenTelemetry\\',
'Rx\\',
'React\\',
'InfluxDB2\\',
'EasyCorp\\Bundle\\EasyAdminBundle\\',
],
shouldNotStartWith: $excludeNamespaces,
shouldNotContain: [
'array<',
'array{',
Expand Down