diff --git a/app/Extensions/FileRestrictionsMapFileGeneratorExtension.php b/app/Extensions/FileRestrictionsMapFileGeneratorExtension.php index b536fb6..49d9c76 100644 --- a/app/Extensions/FileRestrictionsMapFileGeneratorExtension.php +++ b/app/Extensions/FileRestrictionsMapFileGeneratorExtension.php @@ -6,8 +6,13 @@ use App\Extensions\Internals\BuildHook; use App\Extensions\Internals\BuildHooks; use App\Extensions\Internals\BuildStateInterface; +use App\Extensions\Internals\JsonFileModifier; +use App\Extensions\Internals\PluginConfig; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Storage; +use Illuminate\Support\Stringable; +use LaravelZero\Framework\Commands\Command; +use Symfony\Component\Console\Output\OutputInterface; #[BuildExtension(name: 'File Restrictions Map File Generator', key: 'file-restrictions-map-generator')] class FileRestrictionsMapFileGeneratorExtension @@ -16,61 +21,86 @@ class FileRestrictionsMapFileGeneratorExtension * Prepare file restrictions map file */ #[BuildHook(BuildHooks::AFTER_BUILD_SATIS_REPOSITORY)] - public function hook(BuildStateInterface $buildState): void + public function hook(PluginConfig $pluginConfig, Command $command, BuildStateInterface $buildState, JsonFileModifier $jsonFileModifier): void { $url_host = $buildState->getConfig() ->get('archive', collect()) ->get('prefix-url', $buildState->getConfig()->get('homepage')); - $packages = json_decode(Storage::disk('temp')->get(str('packages.json')->start('/')->start($buildState->getTempPrefix())), true); - $packages = collect($packages['available-packages']) - ->map(fn ($package) => [ - str($packages['metadata-url'])->replace('%package%', $package), - str($packages['metadata-url'])->replace('%package%', $package.'~dev'), - ]) - ->flatten() - ->map(fn ($path) => json_decode(Storage::disk('temp')->get($path->start('/')->start($buildState->getTempPrefix())), true)) - ->pluck('packages') - ->map(function ($packages) { - return collect($packages) - ->map(function ($versions, $package) { - return collect($versions) - ->filter(fn ($version) => isset($version['dist']['url'])) - ->map(fn ($version) => [ - 'package' => $package, - 'url' => $version['dist']['url'], - 'version' => $version['version_normalized'], - ]); - }) - ->flatten(1); - }) - ->flatten(1) - ->map(function ($package) use ($url_host) { - $package['url'] = str($package['url'])->replace($url_host, '')->ltrim('/')->toString(); + $tagged_versions = collect(); - return $package; - }) - ->map(function ($package) { - $package['tags'][] = "{$package['package']}:{$package['version']}"; + $jsonFileModifier->modifyVersions(function (Collection $version, string $package_name, Stringable $json_path) use ($pluginConfig, $tagged_versions, $url_host, $command) { + if ($version->has('dist') === false) { + $command->line("Version {$package_name}:{$version['version']} does not have a dist - skipping.", verbosity: OutputInterface::VERBOSITY_DEBUG); + return; + } - if (preg_match('/^(\\d)\\.(\\d)\\.(\\d)\\.(\\d)$/u', $package['version'], $matches)) { - $package['tags'][] = "{$package['package']}:{$matches[1]}.{$matches[2]}.{$matches[3]}.x"; - $package['tags'][] = "{$package['package']}:{$matches[1]}.{$matches[2]}.x"; - $package['tags'][] = "{$package['package']}:{$matches[1]}.x"; - } + $dist = $version->get('dist', collect()); - return $package; - }) + if ($dist->has('url') === false) { + $command->line("Version {$package_name}:{$version['version']} does not have a url - skipping.", verbosity: OutputInterface::VERBOSITY_DEBUG); + return; + } + + $url = $dist->get('url'); + $path = str($url)->replace($url_host, '')->ltrim('/')->toString(); + $tags = $this->getTagsForVersion($package_name, $version); + + if (!str($path)->startsWith(['http://', 'https://'])) { + $tagged_versions->push([ + 'package' => $package_name, + 'url' => $path, + 'version' => $version['version_normalized'], + 'tags' => $tags, + ]); + } else { + $command->line("Version {$package_name}:{$version['version']} has a remote url - skipping.", verbosity: OutputInterface::VERBOSITY_DEBUG); + } + + $command->line("Version {$package_name}:{$version['version']} has been tagged with the following tags: ".implode(', ', $tags->toArray()), verbosity: OutputInterface::VERBOSITY_DEBUG); + + if(!$pluginConfig->get('extra-json', false)){ + return; + } + + if(!$json_path->start('/')->startsWith('/p2/')) { + $command->line("Version {$package_name}:{$version['version']} is not in a Composer 2 package file - skipping modification of json file.", verbosity: OutputInterface::VERBOSITY_DEBUG); + return; + } + + if($version->has('extra')) { + $extra = $version->get('extra'); + } else { + $extra = collect(); + $version->put('extra', $extra); + } + + $extra->put('s3-satis-file-restrictions', $tags); + }); + + Storage::disk('temp')->deleteDirectory('.tags'); + $tagged_versions ->groupBy('url') ->map(function (Collection $packages) { - return $packages->pluck('tags')->flatten(); + return $packages->pluck('tags')->unique()->flatten(); }) - ->filter(fn (Collection $tags, string $url) => ! str($url)->startsWith(['http://', 'https://'])); + ->each(function (Collection $tags, string $url) use ($buildState) { + $path = str('.tags')->append('/')->append($url)->append('.json')->start('/')->start($buildState->getTempPrefix()); + Storage::disk('temp')->put($path, $tags->toJson(JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); + }); + } - Storage::disk('temp')->deleteDirectory('.tags'); - $packages->each(function (Collection $tags, string $url) use ($buildState) { - $path = str('.tags')->append('/')->append($url)->append('.json')->start('/')->start($buildState->getTempPrefix()); - Storage::disk('temp')->put($path, $tags->toJson(JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); - }); + protected function getTagsForVersion(string $package_name, Collection $version): Collection + { + $version_normalized = $version->get('version_normalized'); + + $tags = collect(["{$package_name}:{$version_normalized}"]); + if (preg_match('/^(\\d)\\.(\\d)\\.(\\d)\\.(\\d)$/u', $version_normalized, $matches)) { + $tags->push("{$package_name}:{$matches[1]}.{$matches[2]}.{$matches[3]}.x"); + $tags->push("{$package_name}:{$matches[1]}.{$matches[2]}.x"); + $tags->push("{$package_name}:{$matches[1]}.x"); + } + + return $tags; } } diff --git a/workspace/sample_satis_config.json b/workspace/sample_satis_config.json index c602ebe..736976b 100644 --- a/workspace/sample_satis_config.json +++ b/workspace/sample_satis_config.json @@ -29,10 +29,13 @@ "path": "temp", "copy": false }, - "skip-remote-versions": true, - "file-restrictions-map-generator": true, + "skip-remote-versions": false, + "file-restrictions-map-generator": { + "enabled": false, + "extra-json": false + }, "remove-fields-from-json": { - "enabled": true, + "enabled": false, "remove": [ "source", "authors",