From 51d9446ecd6e3e2a8cddb8dad53b75160a4d78ba Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sat, 20 Apr 2024 08:23:37 +1000 Subject: [PATCH 1/4] Fixed code formatting. --- .../scripts/composer/ScaffoldGeneralizer.php | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/scaffold/scripts/composer/ScaffoldGeneralizer.php b/scaffold/scripts/composer/ScaffoldGeneralizer.php index dec152c..617ddbc 100644 --- a/scaffold/scripts/composer/ScaffoldGeneralizer.php +++ b/scaffold/scripts/composer/ScaffoldGeneralizer.php @@ -156,12 +156,12 @@ public static function generalizeAndRemoveItselfAfterProjectCreate(Event $event) // Remove references to this script. // Remove event script used to invoke this script during the project // creation. - unset($json['scripts']['post-root-package-install'][array_search(__METHOD__, $json['scripts']['post-root-package-install'], true)]); + unset($json['scripts']['post-root-package-install'][array_search(__METHOD__, $json['scripts']['post-root-package-install'], TRUE)]); if (empty($json['scripts']['post-root-package-install'])) { unset($json['scripts']['post-root-package-install']); } // Remove the classmap for this script from the autoload section. - unset($json['autoload']['classmap'][array_search('scripts/composer/ScaffoldGeneralizer.php', $json['autoload']['classmap'], true)]); + unset($json['autoload']['classmap'][array_search('scripts/composer/ScaffoldGeneralizer.php', $json['autoload']['classmap'], TRUE)]); $json['autoload']['classmap'] = array_values($json['autoload']['classmap']); // Remove the script file. if (!$is_install) { @@ -195,14 +195,17 @@ public static function postCreateProjectCmd(Event $event): void { $fs->unlink(getcwd() . '/scripts/composer/ScaffoldGeneralizer.php'); } + /** + * Check if dependencies are being installed. + */ protected static function isInstall(Event $event): bool { $io = $event->getIO(); - $reflectionIo = new \ReflectionObject($io); - $inputProperty = $reflectionIo->getProperty('input'); - $inputProperty->setAccessible(TRUE); + $reflection = new \ReflectionObject($io); + $property = $reflection->getProperty('input'); + $property->setAccessible(TRUE); /** @var \Symfony\Component\Console\Input\StringInput $input */ - $input = $inputProperty->getValue($io); + $input = $property->getValue($io); return !$input->getOption('no-install'); } @@ -225,7 +228,7 @@ protected static function getVersion(): string { */ protected static function arrayUpsert(&$array, $after, $key, $value): void { if (array_key_exists($after, $array)) { - $position = array_search($after, array_keys($array), true) + 1; + $position = array_search($after, array_keys($array), TRUE) + 1; $array = array_slice($array, 0, $position, TRUE) + [$key => $value] + array_slice($array, $position, NULL, TRUE); From 9189e17436dfadfbef24bf89c233e491d45c41a3 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sat, 20 Apr 2024 08:53:21 +1000 Subject: [PATCH 2/4] Added verbose output of failures for requiring the scaffold as dev dep. --- scaffold/scripts/composer/ScaffoldGeneralizer.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/scaffold/scripts/composer/ScaffoldGeneralizer.php b/scaffold/scripts/composer/ScaffoldGeneralizer.php index 617ddbc..defb312 100644 --- a/scaffold/scripts/composer/ScaffoldGeneralizer.php +++ b/scaffold/scripts/composer/ScaffoldGeneralizer.php @@ -182,12 +182,14 @@ public static function generalizeAndRemoveItselfAfterProjectCreate(Event $event) * Require the DrevOps Scaffold package. */ public static function postCreateProjectCmd(Event $event): void { + $version = static::getVersion(); + $event->getIO()->write(sprintf('Adding the DrevOps Scaffold at version "%s" as a development dependency.', $version)); + $ansi = $event->getIO()->isDecorated() ? '--ansi' : '--no-ansi'; - $quiet = $event->getIO()->isVerbose() ? '' : '--quiet'; - $cmd = 'composer require --no-interaction --dev ' . $ansi . ' ' . $quiet . ' ' . static::DREVOPS_SCAFFOLD_NAME . ':' . static::getVersion(); - passthru($cmd, $status); - if ($status != 0) { - throw new \Exception('Command failed with exit code ' . $status); + $cmd = 'composer require --no-interaction --dev ' . $ansi . ' ' . static::DREVOPS_SCAFFOLD_NAME . ':' . $version . ' 2>&1'; + exec($cmd, $output, $result_code); + if ($result_code != 0) { + throw new \Exception(sprintf('Command failed with exit code %s and the following output: %s', $result_code, PHP_EOL . implode(PHP_EOL, $output))); } // Remove the script file. From 8f16916b03d09f09233b2a2238dbfe72ef35ce7f Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sat, 20 Apr 2024 09:00:31 +1000 Subject: [PATCH 3/4] Updated dev instructions. --- README.md | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 84bb280..c77e3ce 100644 --- a/README.md +++ b/README.md @@ -24,12 +24,37 @@ cd consumer composer create-project --prefer-dist drevops/scaffold="@dev" --repository '{"type": "path", "url": "../scaffold", "options": {"symlink": false}}' t1 ``` -## Maintenance +## Maintenance composer install composer lint composer test +### Debugging + +Run once: +```bash +cd scaffold +composer install + +export COMPOSER_ALLOW_XDEBUG=1 +export COMPOSER_DEBUG_EVENTS=1 +export DREVOPS_SCAFFOLD_VERSION=@dev +cd ../consumer +``` + +Run as needed (from `consumer`): +```bash +# No-install +rm -Rf t1 >/dev/null && php ../scaffold/vendor/composer/composer/bin/composer create-project --prefer-dist drevops/scaffold="@dev" --repository '{"type": "path", "url": "../scaffold", "options": {"symlink": false}}' --no-install t1 +``` + +or + +```bash +# Full +rm -Rf t1 >/dev/null && php ../scaffold/vendor/composer/composer/bin/composer create-project --prefer-dist drevops/scaffold="@dev" --repository '{"type": "path", "url": "../scaffold", "options": {"symlink": false}}' t1 +``` From 292bb252eac79b9574d1d9103eb33186a4415bb6 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Sat, 20 Apr 2024 09:12:52 +1000 Subject: [PATCH 4/4] Fixed more coding standards. --- scaffold/tests/phpunit/Dirs.php | 18 ++++++++++++++---- .../tests/phpunit/Traits/ComposerTrait.php | 18 ++++++++++++------ scaffold/tests/phpunit/Traits/EnvTrait.php | 2 +- scaffold/tests/phpunit/Traits/FileTrait.php | 4 ++-- .../tests/phpunit/Traits/JsonAssertTrait.php | 8 +++++--- 5 files changed, 34 insertions(+), 16 deletions(-) diff --git a/scaffold/tests/phpunit/Dirs.php b/scaffold/tests/phpunit/Dirs.php index 7f98684..15cb8ae 100644 --- a/scaffold/tests/phpunit/Dirs.php +++ b/scaffold/tests/phpunit/Dirs.php @@ -71,7 +71,7 @@ public function printInfo(): void { fwrite(STDERR, PHP_EOL . implode(PHP_EOL, $lines) . PHP_EOL); } - protected function prepareLocalRepo() { + protected function prepareLocalRepo(): void { $root = $this->fileFindDir('composer.json'); $this->fs->copy($root . '/composer.json', $this->repo . '/composer.json'); @@ -80,15 +80,25 @@ protected function prepareLocalRepo() { $this->fs->copy($root . '/myfile1.txt', $this->repo . '/myfile1.txt'); // Add the local repository to the composer.json file. - $dstJson = json_decode(file_get_contents($this->repo . '/composer.json'), TRUE); - $dstJson['repositories'][] = [ + $composerjson = file_get_contents($this->repo . '/composer.json'); + if ($composerjson === FALSE) { + throw new \Exception('Failed to read the local composer.json file.'); + } + + /** @var array $dst_json */ + $dst_json = json_decode($composerjson, TRUE); + if (!$dst_json) { + throw new \Exception('Failed to decode the local composer.json file.'); + } + + $dst_json['repositories'][] = [ 'type' => 'path', 'url' => $this->repo, 'options' => [ 'symlink' => FALSE, ], ]; - file_put_contents($this->repo . '/composer.json', json_encode($dstJson, JSON_PRETTY_PRINT)); + file_put_contents($this->repo . '/composer.json', json_encode($dst_json, JSON_PRETTY_PRINT)); } } diff --git a/scaffold/tests/phpunit/Traits/ComposerTrait.php b/scaffold/tests/phpunit/Traits/ComposerTrait.php index dadc3e2..cc705bd 100644 --- a/scaffold/tests/phpunit/Traits/ComposerTrait.php +++ b/scaffold/tests/phpunit/Traits/ComposerTrait.php @@ -25,7 +25,7 @@ protected function composerCreateProject(array|string $args = NULL): string { * * @param string $cmd * The Composer command to execute (escaped as required) - * @param null $cwd + * @param string|null $cwd * The current working directory to run the command from. * @param array $env * Environment variables to define for the subprocess. @@ -35,8 +35,8 @@ protected function composerCreateProject(array|string $args = NULL): string { * * @throws \Exception */ - public function composerRun($cmd, $cwd = NULL, $env = []): string { - $cwd = $cwd ?? $this->dirs->build; + public function composerRun(string $cmd, ?string $cwd = NULL, array $env = []): string { + $cwd = $cwd ?: $this->dirs->build; $env += [ 'DREVOPS_SCAFFOLD_VERSION' => '@dev', @@ -64,11 +64,17 @@ public function composerRun($cmd, $cwd = NULL, $env = []): string { return $output; } - protected function composerReadJson($path = NULL) { - $path = $path ?? $this->dirs->sut . '/composer.json'; + protected function composerReadJson(?string $path = NULL): array { + $path = $path ?: $this->dirs->sut . '/composer.json'; $this->assertFileExists($path); - return json_decode(file_get_contents($path), TRUE); + $composerjson = file_get_contents($path); + $this->assertIsString($composerjson); + + $data = json_decode($composerjson, TRUE); + $this->assertIsArray($data); + + return $data; } } diff --git a/scaffold/tests/phpunit/Traits/EnvTrait.php b/scaffold/tests/phpunit/Traits/EnvTrait.php index fd645f7..2a13507 100644 --- a/scaffold/tests/phpunit/Traits/EnvTrait.php +++ b/scaffold/tests/phpunit/Traits/EnvTrait.php @@ -63,7 +63,7 @@ public static function envIsSet(string $name): bool { /** * Check if an environment variable is not set. */ - public static function envIsUnset($name): bool { + public static function envIsUnset(string $name): bool { return getenv($name) === FALSE; } diff --git a/scaffold/tests/phpunit/Traits/FileTrait.php b/scaffold/tests/phpunit/Traits/FileTrait.php index c5cf776..02a409b 100644 --- a/scaffold/tests/phpunit/Traits/FileTrait.php +++ b/scaffold/tests/phpunit/Traits/FileTrait.php @@ -9,7 +9,7 @@ */ trait FileTrait { - public function fileFindDir(string $file, $start = NULL) { + public function fileFindDir(string $file, ?string $start = NULL): string { if (empty($start)) { $start = dirname(__FILE__); } @@ -23,7 +23,7 @@ public function fileFindDir(string $file, $start = NULL) { if ($fs->exists($path)) { return $current; } - $current = dirname((string) $current); + $current = dirname($current); } throw new \RuntimeException('File not found: ' . $file); diff --git a/scaffold/tests/phpunit/Traits/JsonAssertTrait.php b/scaffold/tests/phpunit/Traits/JsonAssertTrait.php index fbaea24..9d162ec 100644 --- a/scaffold/tests/phpunit/Traits/JsonAssertTrait.php +++ b/scaffold/tests/phpunit/Traits/JsonAssertTrait.php @@ -6,17 +6,19 @@ use Helmich\JsonAssert\JsonAssertions; /** + * Trait JsonAssertTrait. * + * This trait provides a method to assert JSON data. */ trait JsonAssertTrait { use JsonAssertions; - public function assertJsonHasNoKey($jsonDocument, string $jsonPath, $message = NULL): void { - $result = (new JSONPath($jsonDocument))->find($jsonPath); + public function assertJsonHasNoKey(array $json_data, string $path, ?string $message = NULL): void { + $result = (new JSONPath($json_data))->find($path); if (isset($result[0])) { - $this->fail($message ?: sprintf("The JSON path '%s' exists, but it was expected not to.", $jsonPath)); + $this->fail($message ?: sprintf("The JSON path '%s' exists, but it was expected not to.", $path)); } $this->addToAssertionCount(1);