diff --git a/.gitignore b/.gitignore index adca355..56908ae 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ vendor tests/monorepo/packages/A/composer.lock tests/monorepo/packages/B/composer.lock tests/monorepo/packages/C/composer.lock +tests/replace/composer.lock tests/monorepo/composer.lock diff --git a/src/Command/LinkCommand.php b/src/Command/LinkCommand.php index 7464fce..15e928a 100644 --- a/src/Command/LinkCommand.php +++ b/src/Command/LinkCommand.php @@ -68,10 +68,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int $monoRepositoryComposerFile = $this->getComposerFileAtPath($path); $monoRepositoryComposer = $this->readJsonFile($monoRepositoryComposerFile); $baseDir = dirname($monoRepositoryComposerFile); - $config = Config::createFromJson($monoRepositoryComposer, $baseDir); $composerFile = $this->getComposerFileAtPath($wd); - $repositories = $this->buildRepositories($config->composerFiles); $composer = static::$fileContents[$composerFile] = $this->readJsonFile($composerFile); + $config = Config::createFromJson($monoRepositoryComposer, $baseDir, $composer); + $repositories = $this->buildRepositories($config->composerFiles); $filesToWrite = []; $revert = []; diff --git a/src/Config.php b/src/Config.php index 4cb1a42..7151312 100644 --- a/src/Config.php +++ b/src/Config.php @@ -28,9 +28,10 @@ public function __construct(public readonly array $projects = [], public readonl } /** - * @param array{extra?: array{pmu?: array{projects?: string[], exclude?: string[]}}} $composer + * @param array{name?: string, replace?: array, extra?: array{pmu?: array{projects?: string[], exclude?: string[]}}} $composer + * @param array{name?: string, require?: array, 'require-dev'?: array} $projectComposer */ - public static function createFromJson($composer, string $baseDir = '.'): static + public static function createFromJson($composer, string $baseDir = '.', array $projectComposer = []): static { $extra = $composer['extra'] ?? []; if (!isset($extra['pmu'])) { @@ -48,12 +49,22 @@ public static function createFromJson($composer, string $baseDir = '.'): static } } } + + $composerFiles = []; + + // If the project requires the monorepository package, we add a repository for it. + // useful to work with `replace` + $name = $composer['name'] ?? null; + $hasMonorepositoryAsDependency = false; + if ($name && (array_key_exists($name, $projectComposer['require'] ?? []) || array_key_exists($name, $projectComposer['require-dev'] ?? []))) { + $hasMonorepositoryAsDependency = true; + $composerFiles[$name] = implode(DIRECTORY_SEPARATOR, [$baseDir, 'composer.json']); + } $files = self::toArrayString($extra['pmu']['projects'] ?? null); $projects = []; - $composerFiles = []; foreach ($files as $glob) { - $filenames = glob(join(DIRECTORY_SEPARATOR, [$baseDir, $glob])); + $filenames = glob(implode(DIRECTORY_SEPARATOR, [$baseDir, $glob])); if (!$filenames) { return new self(); } @@ -68,6 +79,10 @@ public static function createFromJson($composer, string $baseDir = '.'): static throw new \RuntimeException(sprintf('Malformed JSON at path %s.', $filename)); } + if ($hasMonorepositoryAsDependency && array_key_exists($json['name'], $composer['replace'])) { + continue; + } + $projects[] = $json['name']; $composerFiles[$json['name']] = $filename; } diff --git a/tests/functional/LinkCommandTest.php b/tests/functional/LinkCommandTest.php index c3653c0..1a16309 100644 --- a/tests/functional/LinkCommandTest.php +++ b/tests/functional/LinkCommandTest.php @@ -35,4 +35,12 @@ public function testLink(): void { $this->assertTrue(is_link("./tests/monorepo/vendor/test/b")); $this->assertTrue(is_link("./tests/monorepo/vendor/test/c")); } + + public function testLinkWithReplace(): void { + chdir(__DIR__ . '/../replace'); + $nullOutput = new NullOutput; + $this->application->run(new StringInput('link ../monorepo'), $nullOutput); + $this->assertTrue(is_link("./tests/monorepo/vendor/monorepo")); + $this->assertTrue(is_link("./tests/monorepo/vendor/test/d")); + } } diff --git a/tests/monorepo/composer.json b/tests/monorepo/composer.json index a90e79e..6576d89 100644 --- a/tests/monorepo/composer.json +++ b/tests/monorepo/composer.json @@ -14,6 +14,11 @@ "test/c": "^1.0.0 || @dev", "test/d": "^1.0.0 || @dev" }, + "replace": { + "test/a": "self.version", + "test/b": "self.version", + "test/c": "self.version" + }, "minimum-stability": "dev", "autoload": { "psr-4": { diff --git a/tests/replace/composer.json b/tests/replace/composer.json new file mode 100644 index 0000000..d7ad8e7 --- /dev/null +++ b/tests/replace/composer.json @@ -0,0 +1,39 @@ +{ + "type": "project", + "require": { + "test/a": "*", + "test/b": "*", + "test/c": "*", + "test/d": "*", + "test/monorepo": "*" + }, + "minimum-stability": "dev", + "autoload": { + "psr-4": { + "Replace\\": "." + } + }, + "require-dev": { + "soyuka/pmu": "*@dev" + }, + "repositories": [ + { + "type": "path", + "url": "../../", + "options": { + "symlink": true + } + } + ], + "extra": { + "branch-alias": { + "dev-main": "3.3.x-dev", + "dev-3.4": "3.4.x-dev" + } + }, + "config": { + "allow-plugins": { + "soyuka/pmu": true + } + } +}