From 1f1d74371e616ddb7dad8eb6a9dbfec1064a0707 Mon Sep 17 00:00:00 2001
From: Hazel <hazel@farfrom.earth>
Date: Mon, 29 Jan 2024 15:54:16 +0000
Subject: [PATCH] clean-submodules

---
 __test__/git-auth-helper.test.ts |  1 +
 __test__/input-helper.test.ts    |  1 +
 action.yml                       |  3 +++
 src/git-directory-helper.ts      | 33 ++++++++++++++++++++------------
 src/git-source-provider.ts       |  5 +++++
 src/git-source-settings.ts       |  7 ++++++-
 src/input-helper.ts              |  4 ++++
 7 files changed, 41 insertions(+), 13 deletions(-)

diff --git a/__test__/git-auth-helper.test.ts b/__test__/git-auth-helper.test.ts
index 0fd9262..9afe461 100644
--- a/__test__/git-auth-helper.test.ts
+++ b/__test__/git-auth-helper.test.ts
@@ -801,6 +801,7 @@ async function setup(testName: string): Promise<void> {
   settings = {
     authToken: 'some auth token',
     clean: true,
+    cleanSubmodules: true,
     commit: '',
     filter: undefined,
     sparseCheckout: [],
diff --git a/__test__/input-helper.test.ts b/__test__/input-helper.test.ts
index e57da83..fffff4d 100644
--- a/__test__/input-helper.test.ts
+++ b/__test__/input-helper.test.ts
@@ -77,6 +77,7 @@ describe('input-helper tests', () => {
     expect(settings).toBeTruthy()
     expect(settings.authToken).toBeFalsy()
     expect(settings.clean).toBe(true)
+    expect(settings.cleanSubmodules).toBe(true)
     expect(settings.commit).toBeTruthy()
     expect(settings.commit).toBe('1234567890123456789012345678901234567890')
     expect(settings.filter).toBe(undefined)
diff --git a/action.yml b/action.yml
index 5aa90a7..cd8dc5c 100644
--- a/action.yml
+++ b/action.yml
@@ -53,6 +53,9 @@ inputs:
   clean:
     description: 'Whether to execute `git clean -ffdx && git reset --hard HEAD` before fetching'
     default: true
+  clean-submodules:
+    description: 'Whether to execute clean task again before fetching submodules'
+    default: true
   filter:
     description: >
       Partially clone against a given filter.
diff --git a/src/git-directory-helper.ts b/src/git-directory-helper.ts
index 9a0085f..6bfb063 100644
--- a/src/git-directory-helper.ts
+++ b/src/git-directory-helper.ts
@@ -89,21 +89,11 @@ export async function prepareExistingDirectory(
 
       // Clean
       if (clean) {
-        core.startGroup('Cleaning the repository')
-        if (!(await git.tryClean())) {
-          core.debug(
-            `The clean command failed. This might be caused by: 1) path too long, 2) permission issue, or 3) file in use. For further investigation, manually run 'git clean -ffdx' on the directory '${repositoryPath}'.`
-          )
-          remove = true
-        } else if (!(await git.tryReset())) {
-          remove = true
-        }
-        core.endGroup()
-
-        if (remove) {
+        if (!(await cleanExistingDirectory(git, repositoryPath))) {
           core.warning(
             `Unable to clean or reset the repository. The repository will be recreated instead.`
           )
+          remove = true
         }
       }
     } catch (error) {
@@ -123,3 +113,22 @@ export async function prepareExistingDirectory(
     }
   }
 }
+
+export async function cleanExistingDirectory(git: IGitCommandManager, repositoryPath: string) {
+  core.startGroup('Cleaning the repository')
+
+  if (!(await git.tryClean())) {
+    core.debug(
+      `The clean command failed. This might be caused by: 1) path too long, 2) permission issue, or 3) file in use. For further investigation, manually run 'git clean -ffdx --recurse-submodules' on the directory '${repositoryPath}'.`
+    )
+    return false
+  }
+  
+  if (!(await git.tryReset())) {
+    return false
+  }
+
+  core.endGroup()
+
+  return true
+}
\ No newline at end of file
diff --git a/src/git-source-provider.ts b/src/git-source-provider.ts
index 5c98e9f..5c1d93e 100644
--- a/src/git-source-provider.ts
+++ b/src/git-source-provider.ts
@@ -230,6 +230,11 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> {
       await authHelper.configureGlobalAuth()
       core.endGroup()
 
+      if (settings.cleanSubmodules) {
+        core.info('Cleaning the repository again before fetching submodules')
+        await gitDirectoryHelper.cleanExistingDirectory(git, settings.repositoryPath)
+      }
+
       // Checkout submodules
       core.startGroup('Fetching submodules')
       await git.submoduleSync(settings.nestedSubmodules)
diff --git a/src/git-source-settings.ts b/src/git-source-settings.ts
index 629350b..460d2ea 100644
--- a/src/git-source-settings.ts
+++ b/src/git-source-settings.ts
@@ -25,10 +25,15 @@ export interface IGitSourceSettings {
   commit: string
 
   /**
-   * Indicates whether to clean the repository
+   * Indicates whether to clean the repository before fetching
    */
   clean: boolean
 
+  /**
+   * Indicates whether to clean the repository before fetching submodules
+   */
+  cleanSubmodules: boolean
+
   /**
    * The filter determining which objects to include
    */
diff --git a/src/input-helper.ts b/src/input-helper.ts
index e546c19..60de137 100644
--- a/src/input-helper.ts
+++ b/src/input-helper.ts
@@ -82,6 +82,10 @@ export async function getInputs(): Promise<IGitSourceSettings> {
   result.clean = (core.getInput('clean') || 'true').toUpperCase() === 'TRUE'
   core.debug(`clean = ${result.clean}`)
 
+  // Clean
+  result.cleanSubmodules = (core.getInput('clean-submodules') || core.getInput('clean') || 'true').toUpperCase() === 'TRUE'
+  core.debug(`clean-submodules = ${result.clean}`)
+
   // Filter
   const filter = core.getInput('filter')
   if (filter) {