From ef174ceba555e0f0b93c5e98412de9f23667fdc7 Mon Sep 17 00:00:00 2001
From: Sergei Zharinov <zharinov@users.noreply.github.com>
Date: Tue, 17 Jan 2023 13:04:50 +0300
Subject: [PATCH] feat(packagist): Extract PHP constraints (#19875)

Co-authored-by: Rhys Arkins <rhys@arkins.net>
---
 .../datasource/packagist/schema.spec.ts       | 42 ++++++++++++++++++-
 lib/modules/datasource/packagist/schema.ts    | 10 +++++
 2 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/lib/modules/datasource/packagist/schema.spec.ts b/lib/modules/datasource/packagist/schema.spec.ts
index c673fa7281..4a4cca0390 100644
--- a/lib/modules/datasource/packagist/schema.spec.ts
+++ b/lib/modules/datasource/packagist/schema.spec.ts
@@ -144,6 +144,32 @@ describe('modules/datasource/packagist/schema', () => {
         })
       ).toEqual([{ version: '1.2.3' }]);
     });
+
+    it('expands minified fields', () => {
+      expect(
+        parsePackagesResponse('foo/bar', {
+          packages: {
+            'foo/bar': [
+              { version: '3.3.3', require: { php: '^8.0' } },
+              { version: '2.2.2' },
+              { version: '1.1.1' },
+              { version: '0.0.4', require: { php: '^7.0' } },
+              { version: '0.0.3' },
+              { version: '0.0.2', require: '__unset' },
+              { version: '0.0.1' },
+            ],
+          },
+        })
+      ).toEqual([
+        { version: '3.3.3', require: { php: '^8.0' } },
+        { version: '2.2.2', require: { php: '^8.0' } },
+        { version: '1.1.1', require: { php: '^8.0' } },
+        { version: '0.0.4', require: { php: '^7.0' } },
+        { version: '0.0.3', require: { php: '^7.0' } },
+        { version: '0.0.2' },
+        { version: '0.0.1' },
+      ] satisfies ComposerRelease[]);
+    });
   });
 
   describe('parsePackagesResponses', () => {
@@ -164,6 +190,7 @@ describe('modules/datasource/packagist/schema', () => {
                   time: '111',
                   homepage: 'https://example.com/1',
                   source: { url: 'git@example.com:foo/bar-1' },
+                  require: { php: '^8.0' },
                 },
               ],
               'baz/qux': [
@@ -184,6 +211,7 @@ describe('modules/datasource/packagist/schema', () => {
                   time: '333',
                   homepage: 'https://example.com/3',
                   source: { url: 'git@example.com:foo/bar-3' },
+                  require: { php: '^7.0' },
                 },
               ],
               'baz/qux': [
@@ -201,8 +229,18 @@ describe('modules/datasource/packagist/schema', () => {
         homepage: 'https://example.com/1',
         sourceUrl: 'git@example.com:foo/bar-1',
         releases: [
-          { version: '1.1.1', gitRef: 'v1.1.1', releaseTimestamp: '111' },
-          { version: '3.3.3', gitRef: 'v3.3.3', releaseTimestamp: '333' },
+          {
+            version: '1.1.1',
+            gitRef: 'v1.1.1',
+            releaseTimestamp: '111',
+            constraints: { php: ['^8.0'] },
+          },
+          {
+            version: '3.3.3',
+            gitRef: 'v3.3.3',
+            releaseTimestamp: '333',
+            constraints: { php: ['^7.0'] },
+          },
         ],
       } satisfies ReleaseResult);
     });
diff --git a/lib/modules/datasource/packagist/schema.ts b/lib/modules/datasource/packagist/schema.ts
index 3a998becb6..4a5f379e12 100644
--- a/lib/modules/datasource/packagist/schema.ts
+++ b/lib/modules/datasource/packagist/schema.ts
@@ -54,6 +54,12 @@ export const ComposerRelease = z
           .nullable()
           .catch(null),
         time: z.string().nullable().catch(null),
+        require: z
+          .object({
+            php: z.string(),
+          })
+          .nullable()
+          .catch(null),
       })
       .partial()
   );
@@ -106,6 +112,10 @@ export function parsePackagesResponses(
         dep.releaseTimestamp = composerRelease.time;
       }
 
+      if (composerRelease.require?.php) {
+        dep.constraints = { php: [composerRelease.require.php] };
+      }
+
       releases.push(dep);
 
       if (!homepage && composerRelease.homepage) {
-- 
GitLab