diff --git a/Tasks/DeleteFilesV1/deletefiles.ts b/Tasks/DeleteFilesV1/deletefiles.ts index 9c3308bc25b5..623eeb44e814 100644 --- a/Tasks/DeleteFilesV1/deletefiles.ts +++ b/Tasks/DeleteFilesV1/deletefiles.ts @@ -1,6 +1,9 @@ import path = require('path'); import os = require('os'); +import fs = require('fs'); import tl = require('azure-pipelines-task-lib/task'); +import fastGlob = require('fast-glob'); + tl.setResourcePath(path.join(__dirname, 'task.json')); (() => { @@ -30,15 +33,8 @@ tl.setResourcePath(path.join(__dirname, 'task.json')); return; } - // find all files - let foundPaths: string[] = tl.find(sourceFolder, { - allowBrokenSymbolicLinks: true, - followSpecifiedSymbolicLink: true, - followSymbolicLinks: true - }); - // short-circuit if not exists - if (!foundPaths.length) { + if (!tl.exist(sourceFolder)) { tl.debug('source folder not found. nothing to delete.'); tl.setResult(tl.TaskResult.Succeeded, tl.loc("NoFiles")); return; @@ -55,9 +51,7 @@ tl.setResourcePath(path.join(__dirname, 'task.json')); // a normalization function that could be trusted 100% to match the format produced by tl.find(). // For example if the input contains "\\\share", it would need to be normalized as "\\share". To // avoid worrying about catching every normalization edge case, checking the item name suffices instead. - if (buildCleanup && - foundPaths.some((itemPath: string) => path.basename(itemPath).toLowerCase() == '000admin')) { - + if (buildCleanup && fastGlob.globSync('000admin.*', { cwd: sourceFolder, caseSensitiveMatch: false, }).length) { tl.warning(tl.loc('SkippingSymbolStore', sourceFolder)) return; } @@ -73,7 +67,7 @@ tl.setResourcePath(path.join(__dirname, 'task.json')); } // apply the match patterns - let matches: string[] = matchPatterns(foundPaths, patterns, matchOptions); + let matches: string[] = matchPatterns(sourceFolder, patterns, matchOptions); // sort by length (descending) so files are deleted before folders matches = matches.sort((a: string, b: string) => { @@ -99,9 +93,9 @@ tl.setResourcePath(path.join(__dirname, 'task.json')); // if there wasn't an error, check if there's anything in the folder tree other than folders // if not, delete the root as well if (removeSourceFolder && !errorHappened) { - foundPaths = tl.find(sourceFolder); + const foundPaths = fs.readdirSync(sourceFolder); - if (foundPaths.length === 1) { + if (foundPaths.length === 0) { try { tl.rmRF(sourceFolder); } @@ -152,19 +146,19 @@ function joinPattern(sourcePath: string, pattern: string): string { * @param {Object} options - Match options * @return {string[]} Result matches */ -function matchPatterns(paths: string[], patterns: string[], options: any): string[] { - const allMatches = tl.match(paths, patterns, null, options); - - const hasExcludePatterns = patterns.find(pattern => { - const negateMarkIndex = pattern.indexOf('!'); - return negateMarkIndex > -1 && getNegateMarksNumber(pattern, negateMarkIndex) % 2 === 1; - }) - if(!hasExcludePatterns){ - return allMatches; - } +function matchPatterns(sourceFolder: string, patterns: string[], options: any): string[] { + const isFilePattern = patterns.some(pattern => pattern.includes('.')) + + const result = fastGlob.globSync(patterns, { + cwd: sourceFolder, + caseSensitiveMatch: !options.nocase, + dot: options.dot, + onlyFiles: isFilePattern, + absolute: true + }); + + const sourceFolderAbs = path.resolve(sourceFolder); + const resultsInSourceFolder = result.filter(item => path.resolve(item).startsWith(sourceFolderAbs)); - const excludedPaths = paths.filter(path => !~allMatches.indexOf(path)); - return allMatches.filter(match => { - return !excludedPaths.find(excludedPath => excludedPath.indexOf(match) === 0); - }) + return resultsInSourceFolder; } \ No newline at end of file diff --git a/Tasks/DeleteFilesV1/package-lock.json b/Tasks/DeleteFilesV1/package-lock.json index 32612dc235d5..bb70c9557434 100644 --- a/Tasks/DeleteFilesV1/package-lock.json +++ b/Tasks/DeleteFilesV1/package-lock.json @@ -11,12 +11,48 @@ "dependencies": { "@types/mocha": "^5.2.7", "@types/node": "^20.11.0", - "azure-pipelines-task-lib": "^4.16.0" + "azure-pipelines-task-lib": "^4.16.0", + "fast-glob": "^3.3.2" }, "devDependencies": { "typescript": "5.1.6" } }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha1-dhnC6yGyVIP20WdUi0z9WnSIw9U=", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha1-W9Jir5Tp0lvR5xsF3u1Eh2oiLos=", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha1-6Vc36LtnRt3t9pxVaVNJTxlv5po=", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@types/mocha": { "version": "5.2.7", "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/@types/mocha/-/mocha-5.2.7.tgz", @@ -77,6 +113,18 @@ "concat-map": "0.0.1" } }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/braces/-/braces-3.0.3.tgz", + "integrity": "sha1-SQMy9AkZRSJy1VqEgK3AxEE1h4k=", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/concat-map/-/concat-map-0.0.1.tgz", @@ -98,6 +146,43 @@ } } }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha1-0G1YXOjbqQoWsFBcVDw8z7OuuBg=", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha1-1Q6rqAPIhGqIPBZJKCHrzSzaVfU=", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha1-RCZdPKwH4+p9wkdRY4BkN1SgUpI=", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/follow-redirects": { "version": "1.15.6", "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/follow-redirects/-/follow-redirects-1.15.6.tgz", @@ -150,6 +235,18 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha1-hpgyxYA0/mikCTwX3BXoNA2EAcQ=", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/glob/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/minimatch/-/minimatch-3.1.2.tgz", @@ -221,6 +318,58 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha1-ZPYeQsu7LuwgcanawLKLoeZdUIQ=", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss=", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha1-Q2iJL4hekHRVpv19xVwMnUBJkK4=", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha1-1m+hjzpHB2eJMgubGvMr2G2fogI=", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/mime-db/-/mime-db-1.52.0.tgz", @@ -288,6 +437,18 @@ "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha1-O6ODNzNkbZ0+SZWUbBNlpn+wekI=", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/q": { "version": "1.5.1", "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/q/-/q-1.5.1.tgz", @@ -298,6 +459,26 @@ "teleport": ">=0.2.0" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha1-SSkii7xyTfrEPg77BYyve2z7YkM=", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/rechoir": { "version": "0.6.2", "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/rechoir/-/rechoir-0.6.2.tgz", @@ -325,6 +506,39 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha1-D+E7lSLhRz9RtVjueW4I8R+bSJ8=", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha1-ZtE2jae9+SHrnZW9GpIp5/IaQ+4=", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/sanitize-filename": { "version": "1.6.3", "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/sanitize-filename/-/sanitize-filename-1.6.3.tgz", @@ -368,6 +582,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ=", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/truncate-utf8-bytes": { "version": "1.0.2", "resolved": "https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", diff --git a/Tasks/DeleteFilesV1/package.json b/Tasks/DeleteFilesV1/package.json index 901b28553622..1e6c270c6f99 100644 --- a/Tasks/DeleteFilesV1/package.json +++ b/Tasks/DeleteFilesV1/package.json @@ -21,7 +21,8 @@ "dependencies": { "@types/mocha": "^5.2.7", "@types/node": "^20.11.0", - "azure-pipelines-task-lib": "^4.16.0" + "azure-pipelines-task-lib": "^4.16.0", + "fast-glob": "^3.3.2" }, "devDependencies": { "typescript": "5.1.6" diff --git a/Tasks/DeleteFilesV1/task.json b/Tasks/DeleteFilesV1/task.json index 199415ac5913..9e535cebaef9 100644 --- a/Tasks/DeleteFilesV1/task.json +++ b/Tasks/DeleteFilesV1/task.json @@ -16,7 +16,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 255, + "Minor": 256, "Patch": 0 }, "demands": [],