From 2b7ab400f9d6ee811d56ae71fda569a85f147f95 Mon Sep 17 00:00:00 2001
From: Bernardo <37117272+bernardo-martinez@users.noreply.github.com>
Date: Tue, 10 Dec 2024 19:08:35 +0100
Subject: [PATCH] feat(mix): handle hex package aliases (#32984)

Co-authored-by: Rhys Arkins <rhys@arkins.net>
Co-authored-by: Michael Kriese <michael.kriese@gmx.de>
---
 lib/modules/manager/mix/__fixtures__/mix.exs  |  2 ++
 lib/modules/manager/mix/__fixtures__/mix.lock |  4 ++-
 lib/modules/manager/mix/extract.spec.ts       | 26 +++++++++++++++++++
 lib/modules/manager/mix/extract.ts            | 11 +++++++-
 4 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/lib/modules/manager/mix/__fixtures__/mix.exs b/lib/modules/manager/mix/__fixtures__/mix.exs
index a6c88af298..9a20acf18c 100644
--- a/lib/modules/manager/mix/__fixtures__/mix.exs
+++ b/lib/modules/manager/mix/__fixtures__/mix.exs
@@ -32,6 +32,8 @@ defmodule MyProject.MixProject do
         optional: true},
       {:hammer_backend_redis, "~> 6.1"},
       {:public, "== 1.6.14"},
+      {:gun, "~> 2.0.0", hex: "grpc_gun"},
+      {:another_gun, "~> 1.0.0", hex: :gun_atom},
     ]
   end
 end
diff --git a/lib/modules/manager/mix/__fixtures__/mix.lock b/lib/modules/manager/mix/__fixtures__/mix.lock
index c1b5eacc42..050f556d97 100644
--- a/lib/modules/manager/mix/__fixtures__/mix.lock
+++ b/lib/modules/manager/mix/__fixtures__/mix.lock
@@ -12,5 +12,7 @@
   "mason": {:hex, :mason, "1.1.0", "344dbbf6610d205760ec37e2848bff2aab5a2de182bb5cdaa72cc2fd19d74535", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "19c205c8de0e2e5817f2250100281c58e717cb11ff1bb410bf661ee78c24e79b"},
   "hammer_backend_redis": {:hex, :hammer_backend_redis, "6.1.5", "344dbbf6610d205760ec37e2848bff2aab5a2de182bb5cdaa72cc2fd19d74535", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "19c205c8de0e2e5817f2250100281c58e717cb11ff1bb410bf661ee78c24e79b"},
   "public": {:hex, :public, "1.6.14", "344dbbf6610d205760ec37e2848bff2aab5a2de182bb5cdaa72cc2fd19d74535", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "19c205c8de0e2e5817f2250100281c58e717cb11ff1bb410bf661ee78c24e79b"},
-  "a_transient_dependency": {:hex, :a_transient_dependency, "1.6.14", "344dbbf6610d205760ec37e2848bff2aab5a2de182bb5cdaa72cc2fd19d74535", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "19c205c8de0e2e5817f2250100281c58e717cb11ff1bb410bf661ee78c24e79b"}
+  "a_transient_dependency": {:hex, :a_transient_dependency, "1.6.14", "344dbbf6610d205760ec37e2848bff2aab5a2de182bb5cdaa72cc2fd19d74535", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "19c205c8de0e2e5817f2250100281c58e717cb11ff1bb410bf661ee78c24e79b"},
+  "gun": {:hex, :grpc_gun, "2.0.0", "f99678a2ab975e74372a756c86ec30a8384d3ac8a8b86c7ed6243ef4e61d2729", [:rebar3], [{:cowlib, "~> 2.8.0", [hex: :cowlib, repo: "hexpm", optional: false]}], "hexpm", "03dbbca1a9c604a0267a40ea1d69986225091acb822de0b2dbea21d5815e410b"},
+  "another_gun": {:hex, :gun_atom, "1.0.0", "344dbbf6610d205760ec37e2848bff2aab5a2de182bb5cdaa72cc2fd19d74535", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "19c205c8de0e2e5817f2250100281c58e717cb11ff1bb410bf661ee78c24e79b"}
 }
diff --git a/lib/modules/manager/mix/extract.spec.ts b/lib/modules/manager/mix/extract.spec.ts
index da6ffc1fbb..128ba680e3 100644
--- a/lib/modules/manager/mix/extract.spec.ts
+++ b/lib/modules/manager/mix/extract.spec.ts
@@ -92,6 +92,18 @@ describe('modules/manager/mix/extract', () => {
           depName: 'public',
           packageName: 'public',
         },
+        {
+          currentValue: '~> 2.0.0',
+          datasource: 'hex',
+          depName: 'gun',
+          packageName: 'grpc_gun',
+        },
+        {
+          currentValue: '~> 1.0.0',
+          datasource: 'hex',
+          depName: 'another_gun',
+          packageName: 'gun_atom',
+        },
       ]);
     });
 
@@ -188,6 +200,20 @@ describe('modules/manager/mix/extract', () => {
           packageName: 'public',
           lockedVersion: '1.6.14',
         },
+        {
+          currentValue: '~> 2.0.0',
+          datasource: 'hex',
+          depName: 'gun',
+          packageName: 'grpc_gun',
+          lockedVersion: '2.0.0',
+        },
+        {
+          currentValue: '~> 1.0.0',
+          datasource: 'hex',
+          depName: 'another_gun',
+          packageName: 'gun_atom',
+          lockedVersion: '1.0.0',
+        },
       ]);
     });
   });
diff --git a/lib/modules/manager/mix/extract.ts b/lib/modules/manager/mix/extract.ts
index e8cc5eb8ff..3d9c45e00d 100644
--- a/lib/modules/manager/mix/extract.ts
+++ b/lib/modules/manager/mix/extract.ts
@@ -19,6 +19,7 @@ const commentMatchRegExp = regEx(/#.*$/);
 const lockedVersionRegExp = regEx(
   /^\s+"(?<app>\w+)".*?"(?<lockedVersion>\d+\.\d+\.\d+)"/,
 );
+const hexRegexp = regEx(/hex:\s*(?:"(?<strValue>[^"]+)"|:(?<atomValue>\w+))/);
 
 export async function extractPackageFile(
   content: string,
@@ -44,6 +45,8 @@ export async function extractPackageFile(
         const ref = refRegexp.exec(opts)?.groups?.value;
         const branchOrTag = branchOrTagRegexp.exec(opts)?.groups?.value;
         const organization = organizationRegexp.exec(opts)?.groups?.value;
+        const hexGroups = hexRegexp.exec(opts)?.groups;
+        const hex = hexGroups?.strValue ?? hexGroups?.atomValue;
 
         let dep: PackageDependency;
 
@@ -60,8 +63,14 @@ export async function extractPackageFile(
             depName: app,
             currentValue: requirement,
             datasource: HexDatasource.id,
-            packageName: organization ? `${app}:${organization}` : app,
           };
+          if (organization) {
+            dep.packageName = `${app}:${organization}`;
+          } else if (hex) {
+            dep.packageName = hex;
+          } else {
+            dep.packageName = app;
+          }
           if (requirement?.startsWith('==')) {
             dep.currentVersion = requirement.replace(regEx(/^==\s*/), '');
           }
-- 
GitLab