From 0f6c54dea37b55c565fe82d08f9a9e108985cd51 Mon Sep 17 00:00:00 2001 From: Matthew Endsley <mendsley@gmail.com> Date: Fri, 28 Oct 2022 20:20:33 -0700 Subject: [PATCH] Add clean-exclude input This allows clients to ignore specific paths from the clean phase of the checkout. --- README.md | 4 ++++ action.yml | 3 +++ dist/index.js | 17 ++++++++++++----- src/git-command-manager.ts | 12 +++++++++--- src/git-directory-helper.ts | 3 ++- src/git-source-provider.ts | 1 + src/git-source-settings.ts | 5 +++++ src/input-helper.ts | 2 ++ 8 files changed, 38 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 66c2507..f6681ad 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,10 @@ When Git 2.18 or higher is not in your PATH, falls back to the REST API to downl # Default: true clean: '' + # Comma separated paths to exclude when executing `git clean -ffdx` + # Default: + clean-exclude: '' + # Number of commits to fetch. 0 indicates all history for all branches and tags. # Default: 1 fetch-depth: '' diff --git a/action.yml b/action.yml index 4500daf..8291861 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-exclude: + description: 'Comma separated paths to exclude when executing `git clean -ffdx`' + default: '' fetch-depth: description: 'Number of commits to fetch. 0 indicates all history for all branches and tags.' default: 1 diff --git a/dist/index.js b/dist/index.js index c9c90dd..0bf5810 100644 --- a/dist/index.js +++ b/dist/index.js @@ -7608,9 +7608,14 @@ class GitCommandManager { return !!output.stdout.trim(); }); } - tryClean() { + tryClean(exclude) { return __awaiter(this, void 0, void 0, function* () { - const output = yield this.execGit(['clean', '-ffdx'], true); + var cleanArgs = []; + for (const pattern of exclude) { + cleanArgs.push('-e'); + cleanArgs.push(pattern); + } + const output = yield this.execGit(['clean', '-ffdx', ...cleanArgs], true); return output.exitCode === 0; }); } @@ -9290,7 +9295,7 @@ const fs = __importStar(__webpack_require__(747)); const fsHelper = __importStar(__webpack_require__(618)); const io = __importStar(__webpack_require__(1)); const path = __importStar(__webpack_require__(622)); -function prepareExistingDirectory(git, repositoryPath, repositoryUrl, clean, ref) { +function prepareExistingDirectory(git, repositoryPath, repositoryUrl, clean, cleanExclude, ref) { var _a, _b; return __awaiter(this, void 0, void 0, function* () { assert.ok(repositoryPath, 'Expected repositoryPath to be defined'); @@ -9354,7 +9359,7 @@ function prepareExistingDirectory(git, repositoryPath, repositoryUrl, clean, ref // Clean if (clean) { core.startGroup('Cleaning the repository'); - if (!(yield git.tryClean())) { + if (!(yield git.tryClean(cleanExclude))) { core.debug(`The clean command failed. This might be caused by: 1) path too long, 2) permission issue, or 3) file in use. For futher investigation, manually run 'git clean -ffdx' on the directory '${repositoryPath}'.`); remove = true; } @@ -18447,6 +18452,8 @@ function getInputs() { // Clean result.clean = (core.getInput('clean') || 'true').toUpperCase() === 'TRUE'; core.debug(`clean = ${result.clean}`); + result.cleanExclude = (core.getInput('clean-exclude') || '').split(','); + core.debug(`cleanExclude = ${JSON.stringify(result.cleanExclude)}`); // Fetch depth result.fetchDepth = Math.floor(Number(core.getInput('fetch-depth') || '1')); if (isNaN(result.fetchDepth) || result.fetchDepth < 0) { @@ -31850,7 +31857,7 @@ function getSource(settings) { } // Prepare existing directory, otherwise recreate if (isExisting) { - yield gitDirectoryHelper.prepareExistingDirectory(git, settings.repositoryPath, repositoryUrl, settings.clean, settings.ref); + yield gitDirectoryHelper.prepareExistingDirectory(git, settings.repositoryPath, repositoryUrl, settings.clean, settings.cleanExclude, settings.ref); } if (!git) { // Downloading using REST API diff --git a/src/git-command-manager.ts b/src/git-command-manager.ts index 699a963..46c571e 100644 --- a/src/git-command-manager.ts +++ b/src/git-command-manager.ts @@ -42,7 +42,7 @@ export interface IGitCommandManager { submoduleSync(recursive: boolean): Promise<void> submoduleUpdate(fetchDepth: number, recursive: boolean): Promise<void> tagExists(pattern: string): Promise<boolean> - tryClean(): Promise<boolean> + tryClean(exclude: string[]): Promise<boolean> tryConfigUnset(configKey: string, globalConfig?: boolean): Promise<boolean> tryDisableAutomaticGarbageCollection(): Promise<boolean> tryGetFetchUrl(): Promise<string> @@ -331,8 +331,14 @@ class GitCommandManager { return !!output.stdout.trim() } - async tryClean(): Promise<boolean> { - const output = await this.execGit(['clean', '-ffdx'], true) + async tryClean(exclude: string[]): Promise<boolean> { + var cleanArgs: string[] = [] + for (const pattern of exclude) { + cleanArgs.push('-e') + cleanArgs.push(pattern) + } + + const output = await this.execGit(['clean', '-ffdx', ...cleanArgs], true) return output.exitCode === 0 } diff --git a/src/git-directory-helper.ts b/src/git-directory-helper.ts index 2979e97..7723789 100644 --- a/src/git-directory-helper.ts +++ b/src/git-directory-helper.ts @@ -11,6 +11,7 @@ export async function prepareExistingDirectory( repositoryPath: string, repositoryUrl: string, clean: boolean, + cleanExclude: string[], ref: string ): Promise<void> { assert.ok(repositoryPath, 'Expected repositoryPath to be defined') @@ -84,7 +85,7 @@ export async function prepareExistingDirectory( // Clean if (clean) { core.startGroup('Cleaning the repository') - if (!(await git.tryClean())) { + if (!(await git.tryClean(cleanExclude))) { core.debug( `The clean command failed. This might be caused by: 1) path too long, 2) permission issue, or 3) file in use. For futher investigation, manually run 'git clean -ffdx' on the directory '${repositoryPath}'.` ) diff --git a/src/git-source-provider.ts b/src/git-source-provider.ts index c4a913d..9c109ac 100644 --- a/src/git-source-provider.ts +++ b/src/git-source-provider.ts @@ -68,6 +68,7 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> { settings.repositoryPath, repositoryUrl, settings.clean, + settings.cleanExclude, settings.ref ) } diff --git a/src/git-source-settings.ts b/src/git-source-settings.ts index bde96e8..1c3a980 100644 --- a/src/git-source-settings.ts +++ b/src/git-source-settings.ts @@ -29,6 +29,11 @@ export interface IGitSourceSettings { */ clean: boolean + /** + * Paths to ignore when cleaning the repository + */ + cleanExclude: string[] + /** * The depth when fetching */ diff --git a/src/input-helper.ts b/src/input-helper.ts index c0c0b2c..dd558e0 100644 --- a/src/input-helper.ts +++ b/src/input-helper.ts @@ -81,6 +81,8 @@ export async function getInputs(): Promise<IGitSourceSettings> { // Clean result.clean = (core.getInput('clean') || 'true').toUpperCase() === 'TRUE' core.debug(`clean = ${result.clean}`) + result.cleanExclude = (core.getInput('clean-exclude') || '').split(',') + core.debug(`cleanExclude = ${JSON.stringify(result.cleanExclude)}`) // Fetch depth result.fetchDepth = Math.floor(Number(core.getInput('fetch-depth') || '1'))