From 64460a75f0aade72fc8f0c2fd8f034ff59ea549c Mon Sep 17 00:00:00 2001
From: Gabriel-Ladzaretti
 <97394622+Gabriel-Ladzaretti@users.noreply.github.com>
Date: Wed, 9 Feb 2022 11:38:37 +0200
Subject: [PATCH] fix(gomod): Now ignoring multi-line replace directive inside
 go.mod files. (#14033)

---
 lib/manager/gomod/artifacts.spec.ts |  3 +++
 lib/manager/gomod/artifacts.ts      | 33 ++++++++++++++++++++++++++---
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/lib/manager/gomod/artifacts.spec.ts b/lib/manager/gomod/artifacts.spec.ts
index f37a32da15..a23498384b 100644
--- a/lib/manager/gomod/artifacts.spec.ts
+++ b/lib/manager/gomod/artifacts.spec.ts
@@ -29,6 +29,9 @@ require github.com/rarkins/foo abcdef1
 require gopkg.in/russross/blackfriday.v1 v1.0.0
 
 replace github.com/pkg/errors => ../errors
+
+replace (golang.org/x/foo => github.com/pravesht/gocql v0.0.0)
+
 `;
 
 const adminConfig: RepoGlobalConfig = {
diff --git a/lib/manager/gomod/artifacts.ts b/lib/manager/gomod/artifacts.ts
index bc589081fa..5776242fcc 100644
--- a/lib/manager/gomod/artifacts.ts
+++ b/lib/manager/gomod/artifacts.ts
@@ -152,10 +152,37 @@ export async function updateArtifacts({
   const useVendor = (await readLocalFile(vendorModulesFileName)) !== null;
 
   try {
-    const massagedGoMod = newGoModContent.replace(
-      regEx(/\n(replace\s+[^\s]+\s+=>\s+\.\.\/.*)/g),
-      '\n// renovate-replace $1'
+    // Regex match inline replace directive, example:
+    // replace golang.org/x/net v1.2.3 => example.com/fork/net v1.4.5
+    // https://go.dev/ref/mod#go-mod-file-replace
+    const inlineReplaceRegEx = regEx(
+      /(\r?\n)(replace\s+[^\s]+\s+=>\s+\.\.\/.*)/g
     );
+
+    // $1 will be matched with the (\r?n) group
+    // $2 will be matched with the inline replace match, example
+    // "// renovate-replace replace golang.org/x/net v1.2.3 => example.com/fork/net v1.4.5"
+    const inlineCommentOut = '$1// renovate-replace $2';
+
+    // Regex match replace directive block, example:
+    // replace (
+    //     golang.org/x/net v1.2.3 => example.com/fork/net v1.4.5
+    // )
+    const blockReplaceRegEx = regEx(/(\r?\n)replace\s*\([^)]+\s*\)/g);
+
+    /**
+     * replacerFunction for commenting out replace blocks
+     * @param match A string representing a golang replace directive block
+     * @returns A commented out block with // renovate-replace
+     */
+    const blockCommentOut = (match): string =>
+      match.replace(/(\r?\n)/g, '$1// renovate-replace ');
+
+    // Comment out golang replace directives
+    const massagedGoMod = newGoModContent
+      .replace(inlineReplaceRegEx, inlineCommentOut)
+      .replace(blockReplaceRegEx, blockCommentOut);
+
     if (massagedGoMod !== newGoModContent) {
       logger.debug('Removed some relative replace statements from go.mod');
     }
-- 
GitLab