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
29 changes: 29 additions & 0 deletions .github/workflows/cognitive-code-analysis.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Cognitive Code Analysis

on:
pull_request:
paths:
- '**/*.php'

permissions:
pull-requests: write
contents: read

jobs:
analyse:
name: Cognitive Code Analysis
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: Phauthentic/cognitive-code-analysis-github-action@v1
with:
install-mode: phar
config: phpcca.yaml
post-comment: true
upload-artifact: true
emit-annotations: true
upload-sarif: false
fail-on-threshold: false
2 changes: 1 addition & 1 deletion box.json.dist
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"KevinGH\\Box\\Compactor\\PhpScoper"
],
"files": [
"config.yml",
"phpcca.yaml",
"composer.json",
"readme.md",
"LICENSE"
Expand Down
10 changes: 5 additions & 5 deletions docs/CI-Integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ A typical CI integration follows these steps:
3. Run `bin/phpcca analyse` on those files only
4. Publish the report (Markdown comment, SARIF upload, or quality gate)

When `cca.yaml` exists in the project root, `analyse` loads it automatically. Use `--config=path/to/config.yaml` to override.
When `phpcca.yaml` exists in the project root, `analyse` loads it automatically. Use `--config=path/to/config.yaml` to override.

## Report formats for CI

Expand All @@ -38,7 +38,7 @@ See [Baseline Analysis](./Baseline-Analysis.md) to compare metrics against a pre

The workflow below runs on pull requests, analyses changed PHP files, posts a Markdown report as a PR comment, and uploads the report as an artifact.

Add `--config=cca.yaml` if your config file is not named `cca.yaml` or not in the working directory.
Add `--config=phpcca.yaml` if your config file is not named `phpcca.yaml` or not in the working directory.

```yaml
name: Code Metrics
Expand Down Expand Up @@ -142,7 +142,7 @@ Then upload `results.sarif` using the [GitHub Code Scanning upload action](https

The job below runs on merge requests, analyses changed PHP files, posts a Markdown report as an MR note, and stores the report as an artifact.

Use `--config=cca.yaml` when your config file is not auto-discovered from the project root.
Use `--config=phpcca.yaml` when your config file is not auto-discovered from the project root.

```yaml
Code-Metrics:
Expand All @@ -166,7 +166,7 @@ Code-Metrics:
CHANGED_FILES=$(find src/ -name "*.php" | tr '\n' ' ')
fi
if [ -n "$CHANGED_FILES" ]; then
bin/phpcca analyse $CHANGED_FILES --report-type=markdown --report-file=cca-report.md --config=cca.yaml
bin/phpcca analyse $CHANGED_FILES --report-type=markdown --report-file=cca-report.md --config=phpcca.yaml
if [ -f "cca-report.md" ] && [ -s "cca-report.md" ]; then
# Try with CI_JOB_TOKEN first, fallback to CI/CD variables
if [ -n "$VALIDATOR" ]; then
Expand Down Expand Up @@ -237,7 +237,7 @@ GitLab picks up the Code Quality report automatically when configured in your pi

## Related

- [Configuration](./Configuration.md) — project setup with `bin/phpcca init` and `cca.yaml`
- [Configuration](./Configuration.md) — project setup with `bin/phpcca init` and `phpcca.yaml`
- [Baseline Analysis](./Baseline-Analysis.md) — track complexity changes over time
- [Creating Custom Reporters](./Creating-Custom-Reporters.md) — extend report output for custom CI integrations
- [Issue #29](https://github.com/Phauthentic/cognitive-code-analysis/issues/29) — original feature discussion for GitHub Actions and branch comparison
8 changes: 4 additions & 4 deletions docs/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

## Creating a configuration file

Run `init` to create a `cca.yaml` in your project:
Run `init` to create a `phpcca.yaml` in your project:

```bash
bin/phpcca init
bin/phpcca init --silent
bin/phpcca init --path=/path/to/cca.yaml
bin/phpcca init --path=/path/to/phpcca.yaml
```

When `cca.yaml` exists in the working directory, `analyse` and `churn` pick it up automatically. You only need `--config` for a custom path or filename.
When `phpcca.yaml` exists in the working directory, `analyse` and `churn` pick it up automatically. You only need `--config` for a custom path or filename.

## Passing a configuration file

Expand All @@ -20,7 +20,7 @@ You can specify another configuration file by passing it to the config options:
bin/phpcca analyse <path-to-folder> --config=<path-to-config-file>
```

When both `cca.yaml` and `--config` are available, the explicit `--config` path takes precedence.
When both `phpcca.yaml` and `--config` are available, the explicit `--config` path takes precedence.

## Excluding Classes and Methods

Expand Down
2 changes: 1 addition & 1 deletion config.yml → phpcca.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ cognitive:
excludeFilePatterns:
excludePatterns:
scoreThreshold: 0.5
showOnlyMethodsExceedingThreshold: false
showOnlyMethodsExceedingThreshold: true
showHalsteadComplexity: false
showCyclomaticComplexity: false
showDetailedCognitiveMetrics: true
Expand Down
8 changes: 4 additions & 4 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ composer require --dev phauthentic/cognitive-code-analysis
Create a project configuration file:

```bash
bin/phpcca init # interactive setup → creates cca.yaml in current directory
bin/phpcca init # interactive setup → creates phpcca.yaml in current directory
bin/phpcca init --silent # non-interactive, all defaults
bin/phpcca init --path=/path/to/cca.yaml
bin/phpcca init --path=/path/to/phpcca.yaml
```

When `cca.yaml` exists in the current working directory, `analyse` and `churn` load it automatically. Use `--config` to specify a different file.
When `phpcca.yaml` exists in the current working directory, `analyse` and `churn` load it automatically. Use `--config` to specify a different file.

Cognitive Complexity Analysis

Expand Down Expand Up @@ -163,6 +163,6 @@ Especially the AST-parser used under the hood to analyse the code might have iss

## License ⚖️

Copyright Florian Krämer
Copyright [Florian Krämer](https://florian-kraemer.net/)

Licensed under the [GPL3 license](LICENSE).
2 changes: 1 addition & 1 deletion src/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ private function registerUtilityServices(): void
->setArguments([
new Reference(Processor::class),
new Reference(ConfigLoader::class),
__DIR__ . '/../config.yml',
__DIR__ . '/../phpcca.yaml',
])
->setPublic(true);

Expand Down
2 changes: 1 addition & 1 deletion src/Command/InitCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

#[AsCommand(
name: 'init',
description: 'Create a default cca.yaml for cognitive code analysis.'
description: 'Create a default phpcca.yaml for cognitive code analysis.'
)]
class InitCommand extends Command
{
Expand Down
2 changes: 1 addition & 1 deletion src/Config/ConfigFileResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

class ConfigFileResolver
{
public const DEFAULT_FILENAME = 'cca.yaml';
public const DEFAULT_FILENAME = 'phpcca.yaml';

public function resolve(?string $explicitConfigPath): ?string
{
Expand Down
4 changes: 2 additions & 2 deletions src/Config/ConfigService.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function __construct(
private function loadDefaultConfig(): void
{
$config = $this->processor->processConfiguration($this->configuration, [
Yaml::parseFile(__DIR__ . '/../../config.yml'),
Yaml::parseFile(__DIR__ . '/../../phpcca.yaml'),
]);

$this->config = (new ConfigFactory())->fromArray($config);
Expand All @@ -38,7 +38,7 @@ private function loadDefaultConfig(): void
*/
public function loadConfig(string $configFilePath): void
{
$defaultConfig = Yaml::parseFile(__DIR__ . '/../../config.yml');
$defaultConfig = Yaml::parseFile(__DIR__ . '/../../phpcca.yaml');
$providedConfig = Yaml::parseFile($configFilePath);

$config = $this->processor->processConfiguration($this->configuration, [
Expand Down
35 changes: 23 additions & 12 deletions tests/Unit/Command/CognitiveMetricsCommandCoverageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,17 @@
*/
class CognitiveMetricsCommandCoverageTest extends TestCase
{
private const TEST_CONFIG = __DIR__ . '/minimal-config.yml';

/**
* @param array<string, mixed> $input
* @return array<string, mixed>
*/
private function withTestConfig(array $input): array
{
return ['--config' => self::TEST_CONFIG] + $input;
}

#[Test]
#[DataProvider('coverageFormatProvider')]
public function testAnalyseWithCoverageFormats(string $option, string $file, string $format): void
Expand All @@ -25,10 +36,10 @@ public function testAnalyseWithCoverageFormats(string $option, string $file, str
$command = $application->getContainer()->get(CognitiveMetricsCommand::class);
$tester = new CommandTester($command);

$tester->execute([
$tester->execute($this->withTestConfig([
'path' => __DIR__ . '/../../TestCode/Paginator.php',
$option => __DIR__ . '/../../Fixtures/Coverage/' . $file,
]);
]));

$this->assertEquals(
Command::SUCCESS,
Expand All @@ -48,11 +59,11 @@ public function testAnalyseWithBothCoverageFormatsReturnsError(): void
$command = $application->getContainer()->get(CognitiveMetricsCommand::class);
$tester = new CommandTester($command);

$tester->execute([
$tester->execute($this->withTestConfig([
'path' => __DIR__ . '/../../TestCode/Paginator.php',
'--coverage-clover' => __DIR__ . '/../../Fixtures/Coverage/testcode-clover.xml',
'--coverage-cobertura' => __DIR__ . '/../../Fixtures/Coverage/testcode-cobertura.xml',
]);
]));

$this->assertEquals(
Command::FAILURE,
Expand All @@ -71,10 +82,10 @@ public function testAnalyseWithNonExistentCoverageFile(): void
$command = $application->getContainer()->get(CognitiveMetricsCommand::class);
$tester = new CommandTester($command);

$tester->execute([
$tester->execute($this->withTestConfig([
'path' => __DIR__ . '/../../TestCode/Paginator.php',
'--coverage-clover' => __DIR__ . '/../../Fixtures/Coverage/does-not-exist.xml',
]);
]));

$this->assertEquals(
Command::FAILURE,
Expand All @@ -93,9 +104,9 @@ public function testAnalyseWithoutCoverageDoesNotShowCoverageColumn(): void
$command = $application->getContainer()->get(CognitiveMetricsCommand::class);
$tester = new CommandTester($command);

$tester->execute([
$tester->execute($this->withTestConfig([
'path' => __DIR__ . '/../../TestCode/Paginator.php',
]);
]));

$this->assertEquals(Command::SUCCESS, $tester->getStatusCode());
$output = $tester->getDisplay();
Expand All @@ -119,10 +130,10 @@ public function testAnalyseShowsMethodLevelCoverage(
$command = $application->getContainer()->get(CognitiveMetricsCommand::class);
$tester = new CommandTester($command);

$tester->execute([
$tester->execute($this->withTestConfig([
'path' => __DIR__ . '/../../TestCode/Paginator.php',
"--coverage-{$format}" => __DIR__ . '/../../Fixtures/Coverage/' . $file,
]);
]));

$this->assertEquals(Command::SUCCESS, $tester->getStatusCode());
$output = $tester->getDisplay();
Expand All @@ -148,10 +159,10 @@ public function testAnalyseWithCoverageAndMultiplePaths(): void
$command = $application->getContainer()->get(CognitiveMetricsCommand::class);
$tester = new CommandTester($command);

$tester->execute([
$tester->execute($this->withTestConfig([
'path' => __DIR__ . '/../../TestCode/Paginator.php,' . __DIR__ . '/../../TestCode/FileWithTwoClasses.php',
'--coverage-clover' => __DIR__ . '/../../Fixtures/Coverage/testcode-clover.xml',
]);
]));

$this->assertEquals(
Command::SUCCESS,
Expand Down
4 changes: 2 additions & 2 deletions tests/Unit/Command/InitCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ protected function tearDown(): void
#[Test]
public function silentModeCreatesConfigWithDefaultsAtGivenPath(): void
{
$targetPath = $this->tempDir . '/cca.yaml';
$targetPath = $this->tempDir . '/phpcca.yaml';
$tester = $this->createCommandTester();

$statusCode = $tester->execute([
Expand Down Expand Up @@ -61,7 +61,7 @@ public function silentModeUsesDefaultPathInWorkingDirectory(): void
$statusCode = $tester->execute(['--silent' => true]);

$this->assertSame(Command::SUCCESS, $statusCode);
$this->assertFileExists($this->tempDir . '/cca.yaml');
$this->assertFileExists($this->tempDir . '/phpcca.yaml');
} finally {
chdir($originalWorkingDirectory);
}
Expand Down
3 changes: 3 additions & 0 deletions tests/Unit/Command/OutputWithAllMetrics.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
Config: ./tests/Unit/Command/../../../tests/Fixtures/all-metrics-config.yml
Cache: enabled

Class: \ClassOne
File: tests/TestCode/FileWithTwoClasses.php
┌─────────────┬───────┬───────────┬─────────┬───────────┬──────────┬───────┬────────────┬───────┬────────────┬──────────┬────────────┬──────────┬────────────┐
Expand Down
3 changes: 3 additions & 0 deletions tests/Unit/Command/OutputWithCyclomaticOnly.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
Config: ./tests/Unit/Command/../../../tests/Fixtures/cyclomatic-only-config.yml
Cache: enabled

Class: \ClassOne
File: tests/TestCode/FileWithTwoClasses.php
┌─────────────┬───────┬───────────┬─────────┬───────────┬──────────┬───────┬────────────┬───────┬────────────┬────────────┐
Expand Down
3 changes: 3 additions & 0 deletions tests/Unit/Command/OutputWithHalsteadOnly.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
Config: ./tests/Unit/Command/../../../tests/Fixtures/halstead-only-config.yml
Cache: enabled

Class: \ClassOne
File: tests/TestCode/FileWithTwoClasses.php
┌─────────────┬───────┬───────────┬─────────┬───────────┬──────────┬───────┬────────────┬───────┬────────────┬──────────┬────────────┬──────────┐
Expand Down
3 changes: 3 additions & 0 deletions tests/Unit/Command/OutputWithMinimalConfig.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
Config: ./tests/Unit/Command/../../../tests/Fixtures/minimal-config.yml
Cache: enabled

Class: \ClassOne
File: tests/TestCode/FileWithTwoClasses.php
┌─────────────┬────────────┐
Expand Down
3 changes: 3 additions & 0 deletions tests/Unit/Command/OutputWithSingleTable.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
Config: ./tests/Unit/Command/../../../tests/Fixtures/single-table-config.yml
Cache: enabled

All Methods (23 total)
┌──────────────────────────────────────────┬───────────────────────────────────────────┬──────────────┬───────────┬─────────┬─────────────┬────────────┬────────────┬────────────┬────────────┬────────────┬───────────┬────────────┬────────────┬─────────────────┐
│ Class │ Method Name │ Lines │ Arguments │ Returns │ Variables │ Property │ If │ If Nesting │ Else │ Cognitive │ Halstead │ Halstead │ Halstead │ Cyclomatic │
Expand Down
3 changes: 3 additions & 0 deletions tests/Unit/Command/OutputWithThreshold.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
Config: ./tests/Unit/Command/../../../tests/Fixtures/threshold-config.yml
Cache: enabled

Class: \Doctrine\ORM\Tools\Pagination\Paginator
File: tests/TestCode/Paginator.php
┌───────────────────────────────────────────┬────────┬───────────┬─────────┬───────────┬──────────┬───────┬────────────┬───────────┬────────────┬──────────┬────────────┬──────────┬────────────┐
Expand Down
3 changes: 3 additions & 0 deletions tests/Unit/Command/OutputWithoutDetailedMetrics.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
Config: ./tests/Unit/Command/../../../tests/Fixtures/no-detailed-metrics-config.yml
Cache: enabled

Class: \ClassOne
File: tests/TestCode/FileWithTwoClasses.php
┌─────────────┬────────────┬──────────┬────────────┬──────────┬────────────┐
Expand Down
3 changes: 3 additions & 0 deletions tests/Unit/Command/OutputWithoutOptions.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
Config: ./tests/Unit/Command/minimal-config.yml
Cache: disabled

Class: \ClassOne
File: tests/TestCode/FileWithTwoClasses.php
┌─────────────┬───────┬───────────┬─────────┬───────────┬──────────┬───────┬────────────┬───────┬────────────┐
Expand Down
4 changes: 2 additions & 2 deletions tests/Unit/Command/Presentation/RuntimeStatusRendererTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ public function renderShowsConfigPathAndDisabledCache(): void
$output = new BufferedOutput();
$renderer = new RuntimeStatusRenderer();

$renderer->render($output, $tempDir . '/cca.yaml', $this->createConfig(cacheEnabled: false));
$renderer->render($output, $tempDir . '/phpcca.yaml', $this->createConfig(cacheEnabled: false));

$this->assertSame(
"Config: ./cca.yaml\nCache: disabled\n\n",
"Config: ./phpcca.yaml\nCache: disabled\n\n",
$output->fetch()
);

Expand Down
4 changes: 2 additions & 2 deletions tests/Unit/Config/ConfigInitializerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public function writeConfigFileCreatesFileAndParentDirectory(): void
{
$initializer = $this->createInitializer();
$config = $initializer->createDefaultConfig();
$targetPath = $this->tempDir . '/nested/cca.yaml';
$targetPath = $this->tempDir . '/nested/phpcca.yaml';

$initializer->writeConfigFile($targetPath, $config);

Expand All @@ -73,7 +73,7 @@ private function createInitializer(): ConfigInitializer
return new ConfigInitializer(
new Processor(),
new ConfigLoader(),
__DIR__ . '/../../../config.yml',
__DIR__ . '/../../../phpcca.yaml',
);
}

Expand Down
Loading