From 586683f725600f40f8984186b709e640628fa1d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Z=C3=BClke?= Date: Fri, 17 Jan 2025 12:59:24 +0100 Subject: [PATCH] Minor cleanup for platform repo priorities tests and docs (#773) Fix the repos (and the build docs examples) to have objects with version arrays for each package, as Composer prefers it (and how all the tooling has been generating it for a while). No big thing, as the 'old way' still works (but throws a warning, which doesn't affect the tests though). Also restructure the corresponding test to have a sub-group that describes which test case ran. GUS-W-17622481 --- support/build/README.md | 30 ++-- .../repository/futurepaks/packages.json | 170 +++++++++++++----- .../priorities/packages-custom.json | 10 +- .../repository/priorities/packages.json | 10 +- test/spec/platform_spec.rb | 29 +-- 5 files changed, 174 insertions(+), 75 deletions(-) diff --git a/support/build/README.md b/support/build/README.md index 1176363fd..16e2e2d62 100644 --- a/support/build/README.md +++ b/support/build/README.md @@ -446,22 +446,32 @@ As package of type `heroku-sys-php` may come bundled with a bunch of extensions, The repository is a `packages.json` of all manifests, which can be used by Composer as a `packagist` repository type. See [Usage in Applications](#usage-in-applications) for instructions on how to use such a repository with an application. -The structure of a `packagist` type repository is a struct with a single key "`packages`", which is an array containing another array (!) which is a list of all the manifest structs: +The structure of a `packagist` type repository is a struct with a single key "`packages`", which is a hash of package names containing arrays of all the individual manifest structs for that package (in different versions): { - "packages": [ - [ + "packages": { + "heroku-sys/php": [ + { + "name": "heroku-sys/php", + "version": "8.4.1", + … + }, { - "name": "heroku-sys/php" + "name": "heroku-sys/php", + "version": "8.4.2", … }, … + ], + "heroku-sys/ext-foobar": [ { - "name": "heroku-sys/ext-foobar" + "name": "heroku-sys/ext-foobar", + "version": "1.0.0", … - } + }, + … ] - ] + } } @@ -802,8 +812,8 @@ Name this tarball `ext-myext-1.2.3_php-7.3.tar.gz` and make it available at `htt Assuming that the extension has no stack-specific requirements (meaning it can run on any stack), you can then have a repository at `https://download.example.com/heroku/packages.json` with the following contents: { - "packages": [ - [ + "packages": { + "heroku-sys/ext-myext": [ { "name": "heroku-sys/ext-myext", "version": "1.2.3", @@ -819,7 +829,7 @@ Assuming that the extension has no stack-specific requirements (meaning it can r "time": "WHEN DID MCFLY COME BACK FROM THE FUTURE", } ] - ] + } } **Remember the warning above about version ordering: the PHP 7.3 variant of `ext-myext` version 1.2.3 must be listed before the PHP 7.2 variant, and so forth, to ensure Composer picks the highest possible PHP version.** diff --git a/test/fixtures/platform/repository/futurepaks/packages.json b/test/fixtures/platform/repository/futurepaks/packages.json index 847e3209a..d36f975c3 100644 --- a/test/fixtures/platform/repository/futurepaks/packages.json +++ b/test/fixtures/platform/repository/futurepaks/packages.json @@ -1,6 +1,6 @@ { - "packages": [ - [ + "packages": { + "heroku-sys/ext-bcmath": [ { "conflict": {}, "dist": { @@ -19,7 +19,9 @@ "time": "2021-07-29 20:07:21", "type": "heroku-sys-php-extension", "version": "8.0.9" - }, + } + ], + "heroku-sys/ext-calendar": [ { "conflict": {}, "dist": { @@ -38,7 +40,9 @@ "time": "2021-07-29 20:07:21", "type": "heroku-sys-php-extension", "version": "8.0.9" - }, + } + ], + "heroku-sys/ext-exif": [ { "conflict": {}, "dist": { @@ -57,7 +61,9 @@ "time": "2021-07-29 20:07:21", "type": "heroku-sys-php-extension", "version": "8.0.9" - }, + } + ], + "heroku-sys/ext-ftp": [ { "conflict": {}, "dist": { @@ -76,7 +82,9 @@ "time": "2021-07-29 20:07:21", "type": "heroku-sys-php-extension", "version": "8.0.9" - }, + } + ], + "heroku-sys/ext-gd": [ { "conflict": {}, "dist": { @@ -95,7 +103,9 @@ "time": "2021-07-29 20:07:21", "type": "heroku-sys-php-extension", "version": "8.0.9" - }, + } + ], + "heroku-sys/ext-gettext": [ { "conflict": {}, "dist": { @@ -114,7 +124,9 @@ "time": "2021-07-29 20:07:21", "type": "heroku-sys-php-extension", "version": "8.0.9" - }, + } + ], + "heroku-sys/ext-gmp": [ { "conflict": {}, "dist": { @@ -133,7 +145,9 @@ "time": "2021-07-29 20:07:21", "type": "heroku-sys-php-extension", "version": "8.0.9" - }, + } + ], + "heroku-sys/ext-imap": [ { "conflict": {}, "dist": { @@ -152,7 +166,9 @@ "time": "2021-07-29 20:07:21", "type": "heroku-sys-php-extension", "version": "8.0.9" - }, + } + ], + "heroku-sys/ext-intl": [ { "conflict": {}, "dist": { @@ -171,7 +187,9 @@ "time": "2021-07-29 20:07:21", "type": "heroku-sys-php-extension", "version": "8.0.9" - }, + } + ], + "heroku-sys/ext-ldap": [ { "conflict": {}, "dist": { @@ -190,7 +208,9 @@ "time": "2021-07-29 20:07:21", "type": "heroku-sys-php-extension", "version": "8.0.9" - }, + } + ], + "heroku-sys/ext-mbstring": [ { "conflict": {}, "dist": { @@ -209,7 +229,9 @@ "time": "2021-07-29 20:07:21", "type": "heroku-sys-php-extension", "version": "8.0.9" - }, + } + ], + "heroku-sys/ext-pcntl": [ { "conflict": {}, "dist": { @@ -228,7 +250,9 @@ "time": "2021-07-29 20:07:21", "type": "heroku-sys-php-extension", "version": "8.0.9" - }, + } + ], + "heroku-sys/ext-pdo_sqlite": [ { "conflict": {}, "dist": { @@ -247,7 +271,9 @@ "time": "2021-07-29 20:07:21", "type": "heroku-sys-php-extension", "version": "8.0.9" - }, + } + ], + "heroku-sys/ext-shmop": [ { "conflict": {}, "dist": { @@ -266,7 +292,9 @@ "time": "2021-07-29 20:07:21", "type": "heroku-sys-php-extension", "version": "8.0.9" - }, + } + ], + "heroku-sys/ext-soap": [ { "conflict": {}, "dist": { @@ -285,7 +313,9 @@ "time": "2021-07-29 20:07:21", "type": "heroku-sys-php-extension", "version": "8.0.9" - }, + } + ], + "heroku-sys/ext-sodium": [ { "conflict": {}, "dist": { @@ -304,7 +334,9 @@ "time": "2021-07-29 20:07:21", "type": "heroku-sys-php-extension", "version": "8.0.9" - }, + } + ], + "heroku-sys/ext-sqlite3": [ { "conflict": {}, "dist": { @@ -323,7 +355,9 @@ "time": "2021-07-29 20:07:21", "type": "heroku-sys-php-extension", "version": "8.0.9" - }, + } + ], + "heroku-sys/ext-xsl": [ { "conflict": {}, "dist": { @@ -342,7 +376,9 @@ "time": "2021-07-29 20:07:21", "type": "heroku-sys-php-extension", "version": "8.0.9" - }, + } + ], + "heroku-sys/ext-amqp": [ { "conflict": {}, "dist": { @@ -361,7 +397,9 @@ "time": "2021-04-15 18:00:03", "type": "heroku-sys-php-extension", "version": "1.11.0beta" - }, + } + ], + "heroku-sys/ext-apcu": [ { "conflict": {}, "dist": { @@ -382,7 +420,9 @@ "time": "2021-06-07 14:51:08", "type": "heroku-sys-php-extension", "version": "5.1.20" - }, + } + ], + "heroku-sys/ext-blackfire": [ { "conflict": {}, "dist": { @@ -402,7 +442,9 @@ "time": "2021-07-29 20:08:12", "type": "heroku-sys-php-extension", "version": "1.64.0" - }, + } + ], + "heroku-sys/ext-ev": [ { "conflict": {}, "dist": { @@ -421,7 +463,9 @@ "time": "2021-07-29 20:08:43", "type": "heroku-sys-php-extension", "version": "1.1.4" - }, + } + ], + "heroku-sys/ext-event": [ { "conflict": {}, "dist": { @@ -440,7 +484,9 @@ "time": "2021-06-07 14:50:42", "type": "heroku-sys-php-extension", "version": "3.0.4" - }, + } + ], + "heroku-sys/ext-imagick": [ { "conflict": {}, "dist": { @@ -459,7 +505,9 @@ "time": "2021-07-29 20:08:29", "type": "heroku-sys-php-extension", "version": "3.5.1" - }, + } + ], + "heroku-sys/ext-memcached": [ { "conflict": { "heroku-sys/hhvm": "*" @@ -482,7 +530,9 @@ "time": "2020-10-29 03:10:43", "type": "heroku-sys-php-extension", "version": "3.1.5" - }, + } + ], + "heroku-sys/ext-mongodb": [ { "conflict": {}, "dist": { @@ -501,7 +551,9 @@ "time": "2021-06-07 14:50:26", "type": "heroku-sys-php-extension", "version": "1.9.1" - }, + } + ], + "heroku-sys/ext-newrelic": [ { "conflict": {}, "dist": { @@ -524,7 +576,9 @@ "time": "2021-06-07 15:39:55", "type": "heroku-sys-php-extension", "version": "9.17.1.301" - }, + } + ], + "heroku-sys/ext-oauth": [ { "conflict": { "heroku-sys/hhvm": "*" @@ -545,7 +599,9 @@ "time": "2020-10-29 03:11:59", "type": "heroku-sys-php-extension", "version": "2.0.7" - }, + } + ], + "heroku-sys/ext-pcov": [ { "conflict": {}, "dist": { @@ -564,7 +620,9 @@ "time": "2021-06-07 14:49:42", "type": "heroku-sys-php-extension", "version": "1.0.9" - }, + } + ], + "heroku-sys/ext-pq": [ { "conflict": { "heroku-sys/hhvm": "*" @@ -588,7 +646,9 @@ "time": "2020-10-29 03:19:28", "type": "heroku-sys-php-extension", "version": "2.1.8" - }, + } + ], + "heroku-sys/ext-psr": [ { "conflict": { "heroku-sys/hhvm": "*" @@ -609,7 +669,9 @@ "time": "2020-11-13 08:39:02", "type": "heroku-sys-php-extension", "version": "1.0.1" - }, + } + ], + "heroku-sys/ext-raphf": [ { "conflict": { "heroku-sys/hhvm": "*" @@ -630,7 +692,9 @@ "time": "2020-10-29 03:08:15", "type": "heroku-sys-php-extension", "version": "2.0.1" - }, + } + ], + "heroku-sys/ext-rdkafka": [ { "conflict": {}, "dist": { @@ -651,7 +715,9 @@ "time": "2021-02-04 21:44:34", "type": "heroku-sys-php-extension", "version": "5.0.0" - }, + } + ], + "heroku-sys/ext-redis": [ { "conflict": {}, "dist": { @@ -670,7 +736,9 @@ "time": "2021-04-15 18:01:17", "type": "heroku-sys-php-extension", "version": "5.3.4" - }, + } + ], + "heroku-sys/ext-uuid": [ { "conflict": { "heroku-sys/hhvm": "*" @@ -691,7 +759,9 @@ "time": "2020-11-12 18:09:42", "type": "heroku-sys-php-extension", "version": "1.2.0" - }, + } + ], + "heroku-sys/composer": [ { "conflict": {}, "dist": { @@ -753,7 +823,9 @@ "time": "2021-07-29 20:07:48", "type": "heroku-sys-program", "version": "2.1.5" - }, + } + ], + "heroku-sys/apache": [ { "conflict": {}, "dist": { @@ -774,7 +846,9 @@ "time": "2021-07-01 11:58:42", "type": "heroku-sys-webserver", "version": "2.4.48" - }, + } + ], + "heroku-sys/blackfire": [ { "conflict": {}, "dist": { @@ -795,7 +869,9 @@ "time": "2021-07-29 20:07:58", "type": "heroku-sys-program", "version": "2.4.3" - }, + } + ], + "heroku-sys/libcassandra": [ { "conflict": {}, "dist": { @@ -815,7 +891,9 @@ "time": "2021-04-15 17:47:55", "type": "heroku-sys-library", "version": "2.16.0" - }, + } + ], + "heroku-sys/librdkafka": [ { "conflict": {}, "dist": { @@ -835,7 +913,9 @@ "time": "2021-06-07 14:49:26", "type": "heroku-sys-library", "version": "1.7.0" - }, + } + ], + "heroku-sys/nginx": [ { "conflict": {}, "dist": { @@ -856,7 +936,9 @@ "time": "2021-06-07 16:00:06", "type": "heroku-sys-webserver", "version": "1.20.1" - }, + } + ], + "heroku-sys/php": [ { "conflict": {}, "dist": { @@ -1010,5 +1092,5 @@ "version": "8.0.9" } ] - ] + } } diff --git a/test/fixtures/platform/repository/priorities/packages-custom.json b/test/fixtures/platform/repository/priorities/packages-custom.json index 3e464e092..81dc916e5 100644 --- a/test/fixtures/platform/repository/priorities/packages-custom.json +++ b/test/fixtures/platform/repository/priorities/packages-custom.json @@ -1,6 +1,6 @@ { - "packages": [ - [ + "packages": { + "heroku-sys/ext-redis": [ { "conflict": {}, "dist": { @@ -19,7 +19,9 @@ "time": "2022-01-14 18:01:17", "type": "heroku-sys-php-extension", "version": "5.3.4" - }, + } + ], + "heroku-sys/ext-igbinary": [ { "conflict": {}, "dist": { @@ -40,5 +42,5 @@ "version": "3.2.7" } ] - ] + } } diff --git a/test/fixtures/platform/repository/priorities/packages.json b/test/fixtures/platform/repository/priorities/packages.json index 27aff32b2..7d653c292 100644 --- a/test/fixtures/platform/repository/priorities/packages.json +++ b/test/fixtures/platform/repository/priorities/packages.json @@ -1,6 +1,6 @@ { - "packages": [ - [ + "packages": { + "heroku-sys/ext-redis": [ { "conflict": {}, "dist": { @@ -19,7 +19,9 @@ "time": "2021-04-15 18:01:17", "type": "heroku-sys-php-extension", "version": "5.3.5" - }, + } + ], + "heroku-sys/php": [ { "conflict": {}, "dist": { @@ -116,5 +118,5 @@ "version": "8.0.8" } ] - ] + } } diff --git a/test/spec/platform_spec.rb b/test/spec/platform_spec.rb index f9f74791b..f162642fa 100644 --- a/test/spec/platform_spec.rb +++ b/test/spec/platform_spec.rb @@ -9,6 +9,7 @@ generator_fixtures_subdir = "test/fixtures/platform/generator" manifest_fixtures_subdir = "test/fixtures/platform/builder/manifest" mkrepo_fixtures_subdir = "test/fixtures/platform/builder/mkrepo" +priorities_fixtures_subdir = "test/fixtures/platform/repository/priorities" sync_fixtures_subdir = "test/fixtures/platform/builder/sync" describe "The PHP Platform Installer" do @@ -154,19 +155,21 @@ end end - it "combined with a custom repository installs packages from that repo according to the priority given" do - Dir.chdir("test/fixtures/platform/repository/priorities") do |cwd| - Dir.glob("composer-*.json") do |testcase| - cmd = "COMPOSER=#{testcase} composer install --dry-run" - stdout, stderr, status = Open3.capture3("bash -c #{Shellwords.escape(cmd)}") - expect(status.exitstatus).to eq(0), "dry run install failed for case #{testcase}, stderr: #{stderr}, stdout: #{stdout}" - - expect(stderr).to include("heroku-sys/php (8.0.8)") - expect(stderr).to include("heroku-sys/ext-igbinary (3.2.7)") - if ["composer-default.json"].include? testcase - expect(stderr).to include("heroku-sys/ext-redis (5.3.4)") # packages from the custom repo (listed first) are authoritative; the newer package version from the default repo is not selected - else - expect(stderr).to include("heroku-sys/ext-redis (5.3.5)") # canonical=false or an appropriate only/exclude setting on the custom repo means the newer version from the default repo is selected + describe "combined with a custom repository installs packages from that repo according to the priority given", :focused => true do + Dir.glob("composer-*.json", base: priorities_fixtures_subdir) do |testcase| + it "in case #{testcase}" do + Dir.chdir(priorities_fixtures_subdir) do |cwd| + cmd = "COMPOSER=#{testcase} composer install --dry-run" + stdout, stderr, status = Open3.capture3("bash -c #{Shellwords.escape(cmd)}") + expect(status.exitstatus).to eq(0), "dry run install failed, stderr: #{stderr}, stdout: #{stdout}" + + expect(stderr).to include("heroku-sys/php (8.0.8)") + expect(stderr).to include("heroku-sys/ext-igbinary (3.2.7)") + if ["composer-default.json"].include? testcase + expect(stderr).to include("heroku-sys/ext-redis (5.3.4)") # packages from the custom repo (listed first) are authoritative; the newer package version from the default repo is not selected + else + expect(stderr).to include("heroku-sys/ext-redis (5.3.5)") # canonical=false or an appropriate only/exclude setting on the custom repo means the newer version from the default repo is selected + end end end end