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
2 changes: 1 addition & 1 deletion src/Util/Path.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public static function isAnalysableFile(string $path, string $basePath): bool
*/
public static function relativeTo(string $path, string $normalisedBasePath): string
{
$normalisedPath = self::normalise($path, canonicalise: true);
$normalisedPath = self::normalise(self::resolve($path, $normalisedBasePath), canonicalise: true);

if ($normalisedPath === $normalisedBasePath) {
return '';
Expand Down
87 changes: 87 additions & 0 deletions tests/Cli/StructArmedApplicationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@
use PHPUnit\Framework\TestCase;

use function bin2hex;
use function chdir;
use function file_exists;
use function file_get_contents;
use function file_put_contents;
use function getcwd;
use function glob;
use function is_dir;
use function json_decode;
Expand Down Expand Up @@ -1448,6 +1450,91 @@ public function testAnalyseCommandGeneratesBaseline(): void
}
}

/**
* A baseline entry stores its file relative to the base path. Running from
* a monorepo root that holds a file at the same relative path must not
* resolve the entry to that file instead.
*/
public function testAnalyseCommandAppliesBaselineFromOtherWorkingDirectoryWithBasePathOption(): void
{
$rootPath = (string) realpath($this->createTempDirectory());
$packagePath = $rootPath . '/packages/app';

mkdir($rootPath . '/src');
mkdir($packagePath . '/src', 0777, true);

$source = <<<'PHP'
<?php

namespace App;

class Foo
{
}
PHP;
file_put_contents($rootPath . '/src/Foo.php', $source);
file_put_contents($packagePath . '/src/Foo.php', $source);
file_put_contents($packagePath . '/structarmed.php', <<<'PHP'
<?php

declare(strict_types=1);

use Boundwize\StructArmed\Architecture;
use Boundwize\StructArmed\Rule\Rules\Class_\MustBeFinalRule;

return Architecture::define()
->layer('Source', 'src/')
->rule('source.must_be_final', new MustBeFinalRule('Source'))
->baseline('structarmed-baseline.php');
PHP);

$originalWorkingDirectory = getcwd();
$this->assertNotFalse($originalWorkingDirectory);

try {
[$generateExitCode, $generateOutput] = $this->runApplication(
[
'structarmed',
'analyse',
'--no-progress',
'--no-cache',
'--generate-baseline=structarmed-baseline.php',
],
$packagePath
);

$this->assertSame(0, $generateExitCode, $generateOutput);
$this->assertStringContainsString(
"'file' => 'src/Foo.php'",
(string) file_get_contents($packagePath . '/structarmed-baseline.php')
);

chdir($rootPath);

[$exitCode, $output] = $this->runApplication(
[
'structarmed',
'analyse',
'--basepath=packages/app',
'--config=packages/app/structarmed.php',
'--no-progress',
'--no-cache',
],
$rootPath
);

$this->assertSame(0, $exitCode, $output);
$this->assertStringContainsString('No violations found.', $output);
} finally {
chdir($originalWorkingDirectory);
$this->removeTempDirectory($packagePath);
unlink($rootPath . '/src/Foo.php');
rmdir($rootPath . '/src');
rmdir($rootPath . '/packages');
rmdir($rootPath);
}
}

public function testAnalyseCommandGeneratesBaselineWithSeparateOptionValue(): void
{
$basePath = $this->createProjectDirectoryWithViolation();
Expand Down
3 changes: 3 additions & 0 deletions tests/Util/PathTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ public static function provideRelativeTo(): Iterator
yield 'base itself' => ['/project', '/project', ''];
yield 'sibling of base' => ['/shared/src/Foo.php', '/project', '../shared/src/Foo.php'];
yield 'no common ancestor' => ['C:/other/Foo.php', '/project', 'C:/other/Foo.php'];
// resolved against the base path, never the working directory
yield 'relative to base' => ['src/Foo.php', '/project', 'src/Foo.php'];
yield 'empty is the base' => ['', '/project', ''];
}

#[DataProvider('provideRelativeTo')]
Expand Down
Loading