From 79d81159607cb471de1f3eea5d6971ab1c37ce84 Mon Sep 17 00:00:00 2001 From: Denis Rumyantsev Date: Wed, 15 Jun 2022 08:55:18 +0200 Subject: [PATCH 01/11] stats function fixed --- Tasks/CopyFilesV2/copyfiles.ts | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/Tasks/CopyFilesV2/copyfiles.ts b/Tasks/CopyFilesV2/copyfiles.ts index 7c900aceb647..3b3224a94964 100644 --- a/Tasks/CopyFilesV2/copyfiles.ts +++ b/Tasks/CopyFilesV2/copyfiles.ts @@ -42,15 +42,19 @@ function makeDirP(targetFolder: string, ignoreErrors: boolean): void { * If ignoreEnoent is false ENOENT will be thrown from the function. * @param path path for which methid will try to get tl.FsStats. * @param ignoreEnoent ignore ENOENT error during check of path stats. - * @returns + * @returns `FsStats` or `undefined` */ -function stats(path: string, ignoreEnoent: boolean): tl.FsStats { +function stats(path: string, ignoreEnoent: boolean): tl.FsStats | undefined { try { return tl.stats(path); } catch (err) { - if (err.code != 'ENOENT' && ignoreEnoent) { + if (err.code != 'ENOENT') { throw err; } + if (!ignoreEnoent) { + throw err; + } + tl.warning(`Ignoring error: "${path}" is not found`); } } @@ -97,7 +101,15 @@ async function main(): Promise { let allPaths: string[] = tl.find(sourceFolder, findOptions); let sourceFolderPattern = sourceFolder.replace('[', '[[]'); // directories can have [] in them, and they have special meanings as a pattern, so escape them let matchedPaths: string[] = tl.match(allPaths, contents, sourceFolderPattern); // default match options - let matchedFiles: string[] = matchedPaths.filter((itemPath: string) => !stats(itemPath, false).isDirectory()); // filter-out directories + let matchedFiles: string[] = matchedPaths.filter((itemPath: string) => { + // filter-out directories + const itemStats: tl.FsStats | undefined = stats(itemPath, true); + if (itemStats) { + return itemStats.isDirectory(); + } else { + return false; + } + }); // copy the files to the target folder console.log(tl.loc('FoundNFiles', matchedFiles.length)); @@ -198,7 +210,7 @@ async function main(): Promise { try { let fileStats; fileStats = await retryHelper.RunWithRetry( - () => stats(file, false), + () => stats(file, true), `stats for ${file}` ); fs.utimes(targetPath, fileStats.atime, fileStats.mtime, (err) => { @@ -242,7 +254,7 @@ async function main(): Promise { if (preserveTimestamp) { try { const fileStats = await retryHelper.RunWithRetry( - () => stats(file, false), + () => stats(file, true), `stats for ${file}` ); fs.utimes(targetPath, fileStats.atime, fileStats.mtime, (err) => { From 62c620b6810d259597f6a4bde209744ba98dc86d Mon Sep 17 00:00:00 2001 From: Denis Rumyantsev Date: Wed, 15 Jun 2022 09:40:30 +0200 Subject: [PATCH 02/11] filter-out directories fixed --- Tasks/CopyFilesV2/copyfiles.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tasks/CopyFilesV2/copyfiles.ts b/Tasks/CopyFilesV2/copyfiles.ts index 3b3224a94964..10c80fec853a 100644 --- a/Tasks/CopyFilesV2/copyfiles.ts +++ b/Tasks/CopyFilesV2/copyfiles.ts @@ -54,7 +54,6 @@ function stats(path: string, ignoreEnoent: boolean): tl.FsStats | undefined { if (!ignoreEnoent) { throw err; } - tl.warning(`Ignoring error: "${path}" is not found`); } } @@ -105,8 +104,9 @@ async function main(): Promise { // filter-out directories const itemStats: tl.FsStats | undefined = stats(itemPath, true); if (itemStats) { - return itemStats.isDirectory(); + return !itemStats.isDirectory(); } else { + tl.warning(`Skipping "${path}" since it was not found`); return false; } }); From bf1872527437a71ff9141404537cd0a7481a1fe4 Mon Sep 17 00:00:00 2001 From: Denis Rumyantsev Date: Wed, 15 Jun 2022 09:43:21 +0200 Subject: [PATCH 03/11] bump up CopyFiles task version --- Tasks/CopyFilesV2/task.json | 2 +- Tasks/CopyFilesV2/task.loc.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Tasks/CopyFilesV2/task.json b/Tasks/CopyFilesV2/task.json index 430798e44f77..d93837bd974d 100644 --- a/Tasks/CopyFilesV2/task.json +++ b/Tasks/CopyFilesV2/task.json @@ -16,7 +16,7 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 200, + "Minor": 207, "Patch": 0 }, "releaseNotes": "Match pattern consistency.", diff --git a/Tasks/CopyFilesV2/task.loc.json b/Tasks/CopyFilesV2/task.loc.json index 25850bc8d0d1..a2cd126ddcfa 100644 --- a/Tasks/CopyFilesV2/task.loc.json +++ b/Tasks/CopyFilesV2/task.loc.json @@ -16,7 +16,7 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 200, + "Minor": 207, "Patch": 0 }, "releaseNotes": "ms-resource:loc.releaseNotes", From 481067c8c9b51177e8347005305f8f132217cbe1 Mon Sep 17 00:00:00 2001 From: Denis Rumyantsev Date: Wed, 15 Jun 2022 09:55:31 +0200 Subject: [PATCH 04/11] fix warning when item is not found --- Tasks/CopyFilesV2/copyfiles.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tasks/CopyFilesV2/copyfiles.ts b/Tasks/CopyFilesV2/copyfiles.ts index 10c80fec853a..fd63d2509043 100644 --- a/Tasks/CopyFilesV2/copyfiles.ts +++ b/Tasks/CopyFilesV2/copyfiles.ts @@ -106,7 +106,7 @@ async function main(): Promise { if (itemStats) { return !itemStats.isDirectory(); } else { - tl.warning(`Skipping "${path}" since it was not found`); + tl.warning(`Skipping "${itemPath}" since it was not found`); return false; } }); From 40998798d22d0b651ded0103ede6ed23c71d4157 Mon Sep 17 00:00:00 2001 From: Denis Rumyantsev Date: Wed, 22 Jun 2022 13:19:24 +0200 Subject: [PATCH 05/11] refactored stats function; added filterOutDirectories function; fixed test --- Tasks/CopyFilesV2/Tests/L0copyAllFiles.ts | 31 +++++++++-- Tasks/CopyFilesV2/copyfiles.ts | 68 +++++++++++------------ 2 files changed, 59 insertions(+), 40 deletions(-) diff --git a/Tasks/CopyFilesV2/Tests/L0copyAllFiles.ts b/Tasks/CopyFilesV2/Tests/L0copyAllFiles.ts index 77e510d6bced..2dc7461ff013 100644 --- a/Tasks/CopyFilesV2/Tests/L0copyAllFiles.ts +++ b/Tasks/CopyFilesV2/Tests/L0copyAllFiles.ts @@ -27,23 +27,44 @@ answers.find[path.normalize('/srcDir')] = [ path.normalize('/srcDir/someOtherDir3'), ]; runner.setAnswers(answers); -runner.registerMockExport('stats', (itemPath: string) => { - console.log('##vso[task.debug]stats ' + itemPath); + +fs.existsSync = (itemPath: string) => { + switch (itemPath) { + case path.normalize('/srcDir'): + case path.normalize('/srcDir/someOtherDir'): + case path.normalize('/srcDir/someOtherDir/file1.file'): + case path.normalize('/srcDir/someOtherDir/file2.file'): + case path.normalize('/srcDir/someOtherDir2'): + case path.normalize('/srcDir/someOtherDir2/file1.file'): + case path.normalize('/srcDir/someOtherDir2/file2.file'): + case path.normalize('/srcDir/someOtherDir2/file3.file'): + case path.normalize('/srcDir/someOtherDir3'): + return true; + default: + return false; + } +} + +fs.statSync = (itemPath: string) => { + const result: fs.Stats = new fs.Stats(); switch (itemPath) { case path.normalize('/srcDir/someOtherDir'): case path.normalize('/srcDir/someOtherDir2'): case path.normalize('/srcDir/someOtherDir3'): - return { isDirectory: () => true }; + result.isDirectory = () => true; + break; case path.normalize('/srcDir/someOtherDir/file1.file'): case path.normalize('/srcDir/someOtherDir/file2.file'): case path.normalize('/srcDir/someOtherDir2/file1.file'): case path.normalize('/srcDir/someOtherDir2/file2.file'): case path.normalize('/srcDir/someOtherDir2/file3.file'): - return { isDirectory: () => false }; + result.isDirectory = () => false; + break; default: throw { code: 'ENOENT' }; } -}); + return result; +} // as a precaution, disable fs.chmodSync. it should not be called during this scenario. fs.chmodSync = null; diff --git a/Tasks/CopyFilesV2/copyfiles.ts b/Tasks/CopyFilesV2/copyfiles.ts index fd63d2509043..b64bc9356f8a 100644 --- a/Tasks/CopyFilesV2/copyfiles.ts +++ b/Tasks/CopyFilesV2/copyfiles.ts @@ -9,7 +9,7 @@ import { RetryOptions, RetryHelper } from './retrylogichelper'; * @param err error - null if there is no error */ function displayTimestampChangeResults( - fileStats: tl.FsStats, + fileStats: fs.Stats, err: NodeJS.ErrnoException ) { if (err) { @@ -38,25 +38,32 @@ function makeDirP(targetFolder: string, ignoreErrors: boolean): void { } /** - * Gets stats for the provided path. Will ignore ENOENT error if ignoreEnoent is true. - * If ignoreEnoent is false ENOENT will be thrown from the function. - * @param path path for which methid will try to get tl.FsStats. - * @param ignoreEnoent ignore ENOENT error during check of path stats. - * @returns `FsStats` or `undefined` + * Gets stats for the provided path. + * Will throw error if entry does not exist and `throwEnoent` is `true`. + * @param path path for which method will try to get `fs.Stats`. + * @param throwEnoent throw error if entry does not exist. + * @returns `fs.Stats` or `null` */ -function stats(path: string, ignoreEnoent: boolean): tl.FsStats | undefined { - try { - return tl.stats(path); - } catch (err) { - if (err.code != 'ENOENT') { - throw err; - } - if (!ignoreEnoent) { - throw err; +function stats(path: string, throwEnoent: boolean = false): fs.Stats | null { + if (fs.existsSync(path)) { + return fs.statSync(path); + } else { + const message: string = `Entry "${path}" does not exist`; + if (throwEnoent) { + throw Error(message); } + tl.debug(message); + return null; } } +function filterOutDirectories(paths: string[]): string[] { + return paths.filter((path: string) => { + const itemStats: fs.Stats = stats(path, true); + return !itemStats.isDirectory(); + }); +} + async function main(): Promise { // we allow broken symlinks - since there could be broken symlinks found in source folder, but filtered by contents pattern const findOptions: tl.FindOptions = { @@ -100,16 +107,7 @@ async function main(): Promise { let allPaths: string[] = tl.find(sourceFolder, findOptions); let sourceFolderPattern = sourceFolder.replace('[', '[[]'); // directories can have [] in them, and they have special meanings as a pattern, so escape them let matchedPaths: string[] = tl.match(allPaths, contents, sourceFolderPattern); // default match options - let matchedFiles: string[] = matchedPaths.filter((itemPath: string) => { - // filter-out directories - const itemStats: tl.FsStats | undefined = stats(itemPath, true); - if (itemStats) { - return !itemStats.isDirectory(); - } else { - tl.warning(`Skipping "${itemPath}" since it was not found`); - return false; - } - }); + let matchedFiles: string[] = filterOutDirectories(matchedPaths); // copy the files to the target folder console.log(tl.loc('FoundNFiles', matchedFiles.length)); @@ -120,9 +118,9 @@ async function main(): Promise { console.log(tl.loc('CleaningTargetFolder', targetFolder)); // stat the targetFolder path - let targetFolderStats: tl.FsStats; - targetFolderStats = await retryHelper.RunWithRetry( - () => stats(targetFolder, true), + let targetFolderStats: fs.Stats; + targetFolderStats = await retryHelper.RunWithRetry( + () => stats(targetFolder), `stats for ${targetFolder}` ); @@ -184,10 +182,10 @@ async function main(): Promise { } // stat the target - let targetStats: tl.FsStats; + let targetStats: fs.Stats; if (!cleanTargetFolder) { // optimization - no need to check if relative target exists when CleanTargetFolder=true - targetStats = await retryHelper.RunWithRetry( - () => stats(targetPath, true), + targetStats = await retryHelper.RunWithRetry( + () => stats(targetPath), `Stats for ${targetPath}` ); } @@ -209,8 +207,8 @@ async function main(): Promise { if (preserveTimestamp) { try { let fileStats; - fileStats = await retryHelper.RunWithRetry( - () => stats(file, true), + fileStats = await retryHelper.RunWithRetry( + () => stats(file), `stats for ${file}` ); fs.utimes(targetPath, fileStats.atime, fileStats.mtime, (err) => { @@ -253,8 +251,8 @@ async function main(): Promise { if (preserveTimestamp) { try { - const fileStats = await retryHelper.RunWithRetry( - () => stats(file, true), + const fileStats = await retryHelper.RunWithRetry( + () => stats(file), `stats for ${file}` ); fs.utimes(targetPath, fileStats.atime, fileStats.mtime, (err) => { From 5692485738b7bc244d9b605b5c1c4e2ba6f71072 Mon Sep 17 00:00:00 2001 From: Denis Rumyantsev Date: Wed, 22 Jun 2022 14:34:59 +0200 Subject: [PATCH 06/11] throw enoent by default --- Tasks/CopyFilesV2/copyfiles.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tasks/CopyFilesV2/copyfiles.ts b/Tasks/CopyFilesV2/copyfiles.ts index b64bc9356f8a..7288f6e8c843 100644 --- a/Tasks/CopyFilesV2/copyfiles.ts +++ b/Tasks/CopyFilesV2/copyfiles.ts @@ -44,7 +44,7 @@ function makeDirP(targetFolder: string, ignoreErrors: boolean): void { * @param throwEnoent throw error if entry does not exist. * @returns `fs.Stats` or `null` */ -function stats(path: string, throwEnoent: boolean = false): fs.Stats | null { +function stats(path: string, throwEnoent: boolean = true): fs.Stats | null { if (fs.existsSync(path)) { return fs.statSync(path); } else { @@ -59,7 +59,7 @@ function stats(path: string, throwEnoent: boolean = false): fs.Stats | null { function filterOutDirectories(paths: string[]): string[] { return paths.filter((path: string) => { - const itemStats: fs.Stats = stats(path, true); + const itemStats: fs.Stats = stats(path); return !itemStats.isDirectory(); }); } @@ -185,7 +185,7 @@ async function main(): Promise { let targetStats: fs.Stats; if (!cleanTargetFolder) { // optimization - no need to check if relative target exists when CleanTargetFolder=true targetStats = await retryHelper.RunWithRetry( - () => stats(targetPath), + () => stats(targetPath, false), `Stats for ${targetPath}` ); } From 1f66294bca00b621d7b601e50a0fccc86ee926b0 Mon Sep 17 00:00:00 2001 From: Denis Rumyantsev Date: Wed, 22 Jun 2022 14:50:08 +0200 Subject: [PATCH 07/11] refactoring --- Tasks/CopyFilesV2/copyfiles.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Tasks/CopyFilesV2/copyfiles.ts b/Tasks/CopyFilesV2/copyfiles.ts index 7288f6e8c843..f6811a483315 100644 --- a/Tasks/CopyFilesV2/copyfiles.ts +++ b/Tasks/CopyFilesV2/copyfiles.ts @@ -118,8 +118,7 @@ async function main(): Promise { console.log(tl.loc('CleaningTargetFolder', targetFolder)); // stat the targetFolder path - let targetFolderStats: fs.Stats; - targetFolderStats = await retryHelper.RunWithRetry( + const targetFolderStats: fs.Stats = await retryHelper.RunWithRetry( () => stats(targetFolder), `stats for ${targetFolder}` ); @@ -206,8 +205,7 @@ async function main(): Promise { ); if (preserveTimestamp) { try { - let fileStats; - fileStats = await retryHelper.RunWithRetry( + const fileStats: fs.Stats = await retryHelper.RunWithRetry( () => stats(file), `stats for ${file}` ); From 9284454b50e2d7a06380aa29ebbdcc7f0a338284 Mon Sep 17 00:00:00 2001 From: Denis Rumyantsev Date: Wed, 22 Jun 2022 14:52:54 +0200 Subject: [PATCH 08/11] rename itemStats --- Tasks/CopyFilesV2/Tests/L0copyAllFiles.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Tasks/CopyFilesV2/Tests/L0copyAllFiles.ts b/Tasks/CopyFilesV2/Tests/L0copyAllFiles.ts index 2dc7461ff013..dabf0be4ae90 100644 --- a/Tasks/CopyFilesV2/Tests/L0copyAllFiles.ts +++ b/Tasks/CopyFilesV2/Tests/L0copyAllFiles.ts @@ -46,24 +46,24 @@ fs.existsSync = (itemPath: string) => { } fs.statSync = (itemPath: string) => { - const result: fs.Stats = new fs.Stats(); + const itemStats: fs.Stats = new fs.Stats(); switch (itemPath) { case path.normalize('/srcDir/someOtherDir'): case path.normalize('/srcDir/someOtherDir2'): case path.normalize('/srcDir/someOtherDir3'): - result.isDirectory = () => true; + itemStats.isDirectory = () => true; break; case path.normalize('/srcDir/someOtherDir/file1.file'): case path.normalize('/srcDir/someOtherDir/file2.file'): case path.normalize('/srcDir/someOtherDir2/file1.file'): case path.normalize('/srcDir/someOtherDir2/file2.file'): case path.normalize('/srcDir/someOtherDir2/file3.file'): - result.isDirectory = () => false; + itemStats.isDirectory = () => false; break; default: throw { code: 'ENOENT' }; } - return result; + return itemStats; } // as a precaution, disable fs.chmodSync. it should not be called during this scenario. From a4f307856308b358f99af82b0e60be48f58e20fb Mon Sep 17 00:00:00 2001 From: Denis Rumyantsev Date: Wed, 22 Jun 2022 15:06:56 +0200 Subject: [PATCH 09/11] add warning before throw --- Tasks/CopyFilesV2/copyfiles.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Tasks/CopyFilesV2/copyfiles.ts b/Tasks/CopyFilesV2/copyfiles.ts index f6811a483315..55c7ce64145a 100644 --- a/Tasks/CopyFilesV2/copyfiles.ts +++ b/Tasks/CopyFilesV2/copyfiles.ts @@ -50,7 +50,8 @@ function stats(path: string, throwEnoent: boolean = true): fs.Stats | null { } else { const message: string = `Entry "${path}" does not exist`; if (throwEnoent) { - throw Error(message); + tl.warning(message); + throw new Error(message); } tl.debug(message); return null; From b99872d413d0cf3afa1aee1179c4cc5d3e5ffc10 Mon Sep 17 00:00:00 2001 From: Denis Rumyantsev Date: Fri, 8 Jul 2022 11:07:43 +0200 Subject: [PATCH 10/11] bump version --- Tasks/CopyFilesV2/task.json | 2 +- Tasks/CopyFilesV2/task.loc.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Tasks/CopyFilesV2/task.json b/Tasks/CopyFilesV2/task.json index d93837bd974d..a673379d8e0a 100644 --- a/Tasks/CopyFilesV2/task.json +++ b/Tasks/CopyFilesV2/task.json @@ -16,7 +16,7 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 207, + "Minor": 208, "Patch": 0 }, "releaseNotes": "Match pattern consistency.", diff --git a/Tasks/CopyFilesV2/task.loc.json b/Tasks/CopyFilesV2/task.loc.json index a2cd126ddcfa..74065d0c81c7 100644 --- a/Tasks/CopyFilesV2/task.loc.json +++ b/Tasks/CopyFilesV2/task.loc.json @@ -16,7 +16,7 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 207, + "Minor": 208, "Patch": 0 }, "releaseNotes": "ms-resource:loc.releaseNotes", From 1fcef51c40be67d2371c843b841d39fc30bfaddb Mon Sep 17 00:00:00 2001 From: Denis Rumyantsev Date: Thu, 21 Jul 2022 10:09:48 +0200 Subject: [PATCH 11/11] tests fixed --- .../Tests/L0FailsIfThereIsMkdirError.ts | 25 +++++++++++--- .../Tests/L0IgnoresMakeDirError.ts | 25 +++++++++++--- .../CopyFilesV2/Tests/L0cleansIfSpecified.ts | 29 ++++++++++++---- .../L0cleansIfSpecifiedAndTargetIsFile.ts | 28 +++++++++++---- .../L0copyAllFilesWithBracketsInSrcPath.ts | 30 +++++++++++++--- .../Tests/L0copySubtractExclude.ts | 30 +++++++++++++--- .../Tests/L0failsIfTargetFileIsDir.ts | 26 +++++++++++--- .../Tests/L0overwritesIfSpecified.ts | 34 ++++++++++++++----- .../CopyFilesV2/Tests/L0overwritesReadonly.ts | 34 ++++++++++++++----- .../Tests/L0preservesTimestampIfSpecified.ts | 30 +++++++++++++--- Tasks/CopyFilesV2/Tests/L0rootsPatterns.ts | 22 +++++++++--- Tasks/CopyFilesV2/Tests/L0skipsIfExists.ts | 27 ++++++++++++--- 12 files changed, 271 insertions(+), 69 deletions(-) diff --git a/Tasks/CopyFilesV2/Tests/L0FailsIfThereIsMkdirError.ts b/Tasks/CopyFilesV2/Tests/L0FailsIfThereIsMkdirError.ts index 6379a53a1c98..e85e14396b15 100644 --- a/Tasks/CopyFilesV2/Tests/L0FailsIfThereIsMkdirError.ts +++ b/Tasks/CopyFilesV2/Tests/L0FailsIfThereIsMkdirError.ts @@ -23,18 +23,33 @@ answers.find[path.normalize('/srcDir')] = [ path.normalize('/srcDir/someOtherDir/file2.file'), ]; runner.setAnswers(answers); -runner.registerMockExport('stats', (itemPath: string) => { - console.log('##vso[task.debug]stats ' + itemPath); + +fs.existsSync = (itemPath: string) => { switch (itemPath) { case path.normalize('/srcDir/someOtherDir'): - return { isDirectory: () => true }; case path.normalize('/srcDir/someOtherDir/file1.file'): case path.normalize('/srcDir/someOtherDir/file2.file'): - return { isDirectory: () => false }; + return true; + default: + return false; + } +} + +fs.statSync = (itemPath: string) => { + const itemStats: fs.Stats = new fs.Stats(); + switch (itemPath) { + case path.normalize('/srcDir/someOtherDir'): + itemStats.isDirectory = () => true; + break; + case path.normalize('/srcDir/someOtherDir/file1.file'): + case path.normalize('/srcDir/someOtherDir/file2.file'): + itemStats.isDirectory = () => false; + break; default: throw { code: 'ENOENT' }; } -}); + return itemStats; +} runner.registerMockExport('mkdirP', (p: string) => { console.log(`mkdirP: ${p}`); diff --git a/Tasks/CopyFilesV2/Tests/L0IgnoresMakeDirError.ts b/Tasks/CopyFilesV2/Tests/L0IgnoresMakeDirError.ts index 01ad0bcf581c..7e85b2978c8f 100644 --- a/Tasks/CopyFilesV2/Tests/L0IgnoresMakeDirError.ts +++ b/Tasks/CopyFilesV2/Tests/L0IgnoresMakeDirError.ts @@ -23,18 +23,33 @@ answers.find[path.normalize('/srcDir')] = [ path.normalize('/srcDir/someOtherDir/file2.file'), ]; runner.setAnswers(answers); -runner.registerMockExport('stats', (itemPath: string) => { - console.log('##vso[task.debug]stats ' + itemPath); + +fs.existsSync = (itemPath: string) => { switch (itemPath) { case path.normalize('/srcDir/someOtherDir'): - return { isDirectory: () => true }; case path.normalize('/srcDir/someOtherDir/file1.file'): case path.normalize('/srcDir/someOtherDir/file2.file'): - return { isDirectory: () => false }; + return true; + default: + return false; + } +} + +fs.statSync = (itemPath: string) => { + const itemStats: fs.Stats = new fs.Stats(); + switch (itemPath) { + case path.normalize('/srcDir/someOtherDir'): + itemStats.isDirectory = () => true; + break; + case path.normalize('/srcDir/someOtherDir/file1.file'): + case path.normalize('/srcDir/someOtherDir/file2.file'): + itemStats.isDirectory = () => false; + break; default: throw { code: 'ENOENT' }; } -}); + return itemStats; +} runner.registerMockExport('mkdirP', (p: string) => { console.log(`mkdirP: ${p}`); diff --git a/Tasks/CopyFilesV2/Tests/L0cleansIfSpecified.ts b/Tasks/CopyFilesV2/Tests/L0cleansIfSpecified.ts index a55fd47096c4..146482a7a7eb 100644 --- a/Tasks/CopyFilesV2/Tests/L0cleansIfSpecified.ts +++ b/Tasks/CopyFilesV2/Tests/L0cleansIfSpecified.ts @@ -25,21 +25,38 @@ answers.find[path.normalize('/srcDir')] = [ answers.rmRF[path.join(path.normalize('/destDir/clean-subDir'))] = { success: true }; answers.rmRF[path.join(path.normalize('/destDir/clean-file.txt'))] = { success: true }; runner.setAnswers(answers); -runner.registerMockExport('stats', (itemPath: string) => { - console.log('##vso[task.debug]stats ' + itemPath); + +fs.existsSync = (itemPath: string) => { switch (itemPath) { case path.normalize('/destDir'): - return { isDirectory: () => true }; case path.normalize('/srcDir'): case path.normalize('/srcDir/someOtherDir'): - return { isDirectory: () => true }; case path.normalize('/srcDir/someOtherDir/file1.file'): case path.normalize('/srcDir/someOtherDir/file2.file'): - return { isDirectory: () => false }; + return true; + default: + return false; + } +} + +fs.statSync = (itemPath: string) => { + const itemStats: fs.Stats = new fs.Stats(); + switch (itemPath) { + case path.normalize('/destDir'): + case path.normalize('/srcDir'): + case path.normalize('/srcDir/someOtherDir'): + itemStats.isDirectory = () => true; + break; + case path.normalize('/srcDir/someOtherDir/file1.file'): + case path.normalize('/srcDir/someOtherDir/file2.file'): + itemStats.isDirectory = () => false; + break; default: throw { code: 'ENOENT' }; } -}); + return itemStats; +} + let origReaddirSync = fs.readdirSync; fs.readdirSync = (p: fs.PathLike, o?: any): any => { console.log('HERE path ' + p); diff --git a/Tasks/CopyFilesV2/Tests/L0cleansIfSpecifiedAndTargetIsFile.ts b/Tasks/CopyFilesV2/Tests/L0cleansIfSpecifiedAndTargetIsFile.ts index c4b442850ab6..52f6f856c026 100644 --- a/Tasks/CopyFilesV2/Tests/L0cleansIfSpecifiedAndTargetIsFile.ts +++ b/Tasks/CopyFilesV2/Tests/L0cleansIfSpecifiedAndTargetIsFile.ts @@ -24,21 +24,37 @@ answers.find[path.normalize('/srcDir')] = [ ]; answers.rmRF[path.join(path.normalize('/destDir'))] = { success: true }; runner.setAnswers(answers); -runner.registerMockExport('stats', (itemPath: string) => { - console.log('##vso[task.debug]stats ' + itemPath); + +fs.existsSync = (itemPath: string) => { switch (itemPath) { + case path.normalize('/srcDir'): + case path.normalize('/srcDir/someOtherDir'): case path.normalize('/destDir'): - return { isDirectory: () => false }; + case path.normalize('/srcDir/someOtherDir/file1.file'): + case path.normalize('/srcDir/someOtherDir/file2.file'): + return true; + default: + return false; + } +} + +fs.statSync = (itemPath: string) => { + const itemStats: fs.Stats = new fs.Stats(); + switch (itemPath) { case path.normalize('/srcDir'): case path.normalize('/srcDir/someOtherDir'): - return { isDirectory: () => true }; + itemStats.isDirectory = () => true; + break; + case path.normalize('/destDir'): case path.normalize('/srcDir/someOtherDir/file1.file'): case path.normalize('/srcDir/someOtherDir/file2.file'): - return { isDirectory: () => false }; + itemStats.isDirectory = () => false; + break; default: throw { code: 'ENOENT' }; } -}); + return itemStats; +} // as a precaution, disable fs.chmodSync. it should not be called during this scenario. fs.chmodSync = null; diff --git a/Tasks/CopyFilesV2/Tests/L0copyAllFilesWithBracketsInSrcPath.ts b/Tasks/CopyFilesV2/Tests/L0copyAllFilesWithBracketsInSrcPath.ts index 6849e7ba2fb7..850a60ba70da 100644 --- a/Tasks/CopyFilesV2/Tests/L0copyAllFilesWithBracketsInSrcPath.ts +++ b/Tasks/CopyFilesV2/Tests/L0copyAllFilesWithBracketsInSrcPath.ts @@ -27,23 +27,43 @@ answers.find[path.normalize('/srcDir [bracket]')] = [ path.normalize('/srcDir [bracket]/someOtherDir3'), ]; runner.setAnswers(answers); -runner.registerMockExport('stats', (itemPath: string) => { - console.log('##vso[task.debug]stats ' + itemPath); + +fs.existsSync = (itemPath: string) => { + switch (itemPath) { + case path.normalize('/srcDir [bracket]/someOtherDir'): + case path.normalize('/srcDir [bracket]/someOtherDir2'): + case path.normalize('/srcDir [bracket]/someOtherDir3'): + case path.normalize('/srcDir [bracket]/someOtherDir/file1.file'): + case path.normalize('/srcDir [bracket]/someOtherDir/file2.file'): + case path.normalize('/srcDir [bracket]/someOtherDir2/file1.file'): + case path.normalize('/srcDir [bracket]/someOtherDir2/file2.file'): + case path.normalize('/srcDir [bracket]/someOtherDir2/file3.file'): + return true; + default: + return false; + } +} + +fs.statSync = (itemPath: string) => { + const itemStats: fs.Stats = new fs.Stats(); switch (itemPath) { case path.normalize('/srcDir [bracket]/someOtherDir'): case path.normalize('/srcDir [bracket]/someOtherDir2'): case path.normalize('/srcDir [bracket]/someOtherDir3'): - return { isDirectory: () => true }; + itemStats.isDirectory = () => true; + break; case path.normalize('/srcDir [bracket]/someOtherDir/file1.file'): case path.normalize('/srcDir [bracket]/someOtherDir/file2.file'): case path.normalize('/srcDir [bracket]/someOtherDir2/file1.file'): case path.normalize('/srcDir [bracket]/someOtherDir2/file2.file'): case path.normalize('/srcDir [bracket]/someOtherDir2/file3.file'): - return { isDirectory: () => false }; + itemStats.isDirectory = () => false; + break; default: throw { code: 'ENOENT' }; } -}); + return itemStats; +} // as a precaution, disable fs.chmodSync. it should not be called during this scenario. fs.chmodSync = null; diff --git a/Tasks/CopyFilesV2/Tests/L0copySubtractExclude.ts b/Tasks/CopyFilesV2/Tests/L0copySubtractExclude.ts index 9edfa3330a25..3b0b27383e9c 100644 --- a/Tasks/CopyFilesV2/Tests/L0copySubtractExclude.ts +++ b/Tasks/CopyFilesV2/Tests/L0copySubtractExclude.ts @@ -28,23 +28,43 @@ answers.find[path.normalize('/srcDir')] = [ path.normalize('/srcDir/someOtherDir3'), ]; runner.setAnswers(answers); -runner.registerMockExport('stats', (itemPath: string) => { - console.log('##vso[task.debug]stats ' + itemPath); + +fs.existsSync = (itemPath: string) => { + switch (itemPath) { + case path.normalize('/srcDir/someOtherDir'): + case path.normalize('/srcDir/someOtherDir2'): + case path.normalize('/srcDir/someOtherDir3'): + case path.normalize('/srcDir/someOtherDir/file1.file'): + case path.normalize('/srcDir/someOtherDir/file2.file'): + case path.normalize('/srcDir/someOtherDir2/file1.file'): + case path.normalize('/srcDir/someOtherDir2/file2.file'): + case path.normalize('/srcDir/someOtherDir2/file3.file'): + return true; + default: + return false; + } +} + +fs.statSync = (itemPath: string) => { + const itemStats: fs.Stats = new fs.Stats(); switch (itemPath) { case path.normalize('/srcDir/someOtherDir'): case path.normalize('/srcDir/someOtherDir2'): case path.normalize('/srcDir/someOtherDir3'): - return { isDirectory: () => true }; + itemStats.isDirectory = () => true; + break; case path.normalize('/srcDir/someOtherDir/file1.file'): case path.normalize('/srcDir/someOtherDir/file2.file'): case path.normalize('/srcDir/someOtherDir2/file1.file'): case path.normalize('/srcDir/someOtherDir2/file2.file'): case path.normalize('/srcDir/someOtherDir2/file3.file'): - return { isDirectory: () => false }; + itemStats.isDirectory = () => false; + break; default: throw { code: 'ENOENT' }; } -}); + return itemStats; +} // as a precaution, disable fs.chmodSync. it should not be called during this scenario. fs.chmodSync = null; diff --git a/Tasks/CopyFilesV2/Tests/L0failsIfTargetFileIsDir.ts b/Tasks/CopyFilesV2/Tests/L0failsIfTargetFileIsDir.ts index 1f3423e3f753..d956eb3c11d9 100644 --- a/Tasks/CopyFilesV2/Tests/L0failsIfTargetFileIsDir.ts +++ b/Tasks/CopyFilesV2/Tests/L0failsIfTargetFileIsDir.ts @@ -22,19 +22,35 @@ answers.find[path.normalize('/srcDir')] = [ path.normalize('/srcDir/someOtherDir/file2.file'), ]; runner.setAnswers(answers); -runner.registerMockExport('stats', (itemPath: string) => { - console.log('##vso[task.debug]stats ' + itemPath); + +fs.existsSync = (itemPath: string) => { + switch (itemPath) { + case path.normalize('/srcDir/someOtherDir'): + case path.normalize('/destDir/someOtherDir/file1.file'): + case path.normalize('/srcDir/someOtherDir/file1.file'): + case path.normalize('/srcDir/someOtherDir/file2.file'): + return true; + default: + return false; + } +} + +fs.statSync = (itemPath: string) => { + const itemStats: fs.Stats = new fs.Stats(); switch (itemPath) { case path.normalize('/srcDir/someOtherDir'): case path.normalize('/destDir/someOtherDir/file1.file'): - return { isDirectory: () => true }; + itemStats.isDirectory = () => true; + break; case path.normalize('/srcDir/someOtherDir/file1.file'): case path.normalize('/srcDir/someOtherDir/file2.file'): - return { isDirectory: () => false }; + itemStats.isDirectory = () => false; + break; default: throw { code: 'ENOENT' }; } -}); + return itemStats; +} // as a precaution, disable fs.chmodSync. it should not be called during this scenario. fs.chmodSync = null; diff --git a/Tasks/CopyFilesV2/Tests/L0overwritesIfSpecified.ts b/Tasks/CopyFilesV2/Tests/L0overwritesIfSpecified.ts index 871e5e3a0c39..d58b2636f7d1 100644 --- a/Tasks/CopyFilesV2/Tests/L0overwritesIfSpecified.ts +++ b/Tasks/CopyFilesV2/Tests/L0overwritesIfSpecified.ts @@ -22,24 +22,40 @@ answers.find[path.normalize('/srcDir')] = [ path.normalize('/srcDir/someOtherDir/file2.file'), ]; runner.setAnswers(answers); -runner.registerMockExport('stats', (itemPath: string): any => { - console.log('##vso[task.debug]stats ' + itemPath); + +fs.existsSync = (itemPath: string) => { + switch (itemPath) { + case path.normalize('/srcDir/someOtherDir'): + case path.normalize('/destDir/someOtherDir'): + case path.normalize('/srcDir/someOtherDir/file1.file'): + case path.normalize('/srcDir/someOtherDir/file2.file'): + case path.normalize('/destDir/someOtherDir/file1.file'): + return true; + default: + return false; + } +} + +fs.statSync = (itemPath: string) => { + const itemStats: fs.Stats = new fs.Stats(); switch (itemPath) { case path.normalize('/srcDir/someOtherDir'): case path.normalize('/destDir/someOtherDir'): - return { isDirectory: () => true }; + itemStats.isDirectory = () => true; + break; case path.normalize('/srcDir/someOtherDir/file1.file'): case path.normalize('/srcDir/someOtherDir/file2.file'): - return { isDirectory: () => false }; + itemStats.isDirectory = () => false; + break; case path.normalize('/destDir/someOtherDir/file1.file'): - return { - isDirectory: () => false, - mode: (6 << 6) + (6 << 3) + 6, // rw-rw-rw- - }; + itemStats.isDirectory = () => false; + itemStats.mode = (6 << 6) + (6 << 3) + 6; // rw-rw-rw- + break; default: throw { code: 'ENOENT' }; } -}); + return itemStats; +} // as a precaution, disable fs.chmodSync. it should not be called during this scenario. fs.chmodSync = null; diff --git a/Tasks/CopyFilesV2/Tests/L0overwritesReadonly.ts b/Tasks/CopyFilesV2/Tests/L0overwritesReadonly.ts index aec1a0688356..113eb7dc3ac7 100644 --- a/Tasks/CopyFilesV2/Tests/L0overwritesReadonly.ts +++ b/Tasks/CopyFilesV2/Tests/L0overwritesReadonly.ts @@ -22,24 +22,40 @@ answers.find[path.normalize('/srcDir')] = [ path.normalize('/srcDir/someOtherDir/file2.file'), ]; runner.setAnswers(answers); -runner.registerMockExport('stats', (itemPath: string): any => { - console.log('##vso[task.debug]stats ' + itemPath); + +fs.existsSync = (itemPath: string) => { + switch (itemPath) { + case path.normalize('/srcDir/someOtherDir'): + case path.normalize('/destDir/someOtherDir'): + case path.normalize('/srcDir/someOtherDir/file1.file'): + case path.normalize('/srcDir/someOtherDir/file2.file'): + case path.normalize('/destDir/someOtherDir/file1.file'): + return true; + default: + return false; + } +} + +fs.statSync = (itemPath: string) => { + const itemStats: fs.Stats = new fs.Stats(); switch (itemPath) { case path.normalize('/srcDir/someOtherDir'): case path.normalize('/destDir/someOtherDir'): - return { isDirectory: () => true }; + itemStats.isDirectory = () => true; + break; case path.normalize('/srcDir/someOtherDir/file1.file'): case path.normalize('/srcDir/someOtherDir/file2.file'): - return { isDirectory: () => false }; + itemStats.isDirectory = () => false; + break; case path.normalize('/destDir/someOtherDir/file1.file'): - return { - isDirectory: () => false, - mode: (4 << 6) + (4 << 3) + 4, // r--r--r-- - }; + itemStats.isDirectory = () => false; + itemStats.mode = (4 << 6) + (4 << 3) + 4; // r--r--r-- + break; default: throw { code: 'ENOENT' }; } -}); + return itemStats; +} // override fs.chmodSync (fs as any).chmodSync = (path: string, mode: number) => { diff --git a/Tasks/CopyFilesV2/Tests/L0preservesTimestampIfSpecified.ts b/Tasks/CopyFilesV2/Tests/L0preservesTimestampIfSpecified.ts index c7a88efae3a3..3f2cc478e01b 100644 --- a/Tasks/CopyFilesV2/Tests/L0preservesTimestampIfSpecified.ts +++ b/Tasks/CopyFilesV2/Tests/L0preservesTimestampIfSpecified.ts @@ -30,23 +30,43 @@ answers.find[path.normalize('/srcDir')] = [ path.normalize('/srcDir/someOtherDir3'), ]; runner.setAnswers(answers); -runner.registerMockExport('stats', (itemPath: string) => { - console.log('##vso[task.debug]stats ' + itemPath); + +fs.existsSync = (itemPath: string) => { + switch (itemPath) { + case path.normalize('/srcDir/someOtherDir'): + case path.normalize('/srcDir/someOtherDir2'): + case path.normalize('/srcDir/someOtherDir3'): + case path.normalize('/srcDir/someOtherDir/file1.file'): + case path.normalize('/srcDir/someOtherDir/file2.file'): + case path.normalize('/srcDir/someOtherDir2/file1.file'): + case path.normalize('/srcDir/someOtherDir2/file2.file'): + case path.normalize('/srcDir/someOtherDir2/file3.file'): + return true; + default: + return false; + } +} + +fs.statSync = (itemPath: string) => { + const itemStats: fs.Stats = new fs.Stats(); switch (itemPath) { case path.normalize('/srcDir/someOtherDir'): case path.normalize('/srcDir/someOtherDir2'): case path.normalize('/srcDir/someOtherDir3'): - return { isDirectory: () => true }; + itemStats.isDirectory = () => true; + break; case path.normalize('/srcDir/someOtherDir/file1.file'): case path.normalize('/srcDir/someOtherDir/file2.file'): case path.normalize('/srcDir/someOtherDir2/file1.file'): case path.normalize('/srcDir/someOtherDir2/file2.file'): case path.normalize('/srcDir/someOtherDir2/file3.file'): - return { isDirectory: () => false }; + itemStats.isDirectory = () => false; + break; default: throw { code: 'ENOENT' }; } -}); + return itemStats; +} fs.utimes = promisify(function (targetPath, atime, mtime, err) { console.log('Calling fs.utimes on', targetPath); diff --git a/Tasks/CopyFilesV2/Tests/L0rootsPatterns.ts b/Tasks/CopyFilesV2/Tests/L0rootsPatterns.ts index fabeb235f452..9f0c2b324dbf 100644 --- a/Tasks/CopyFilesV2/Tests/L0rootsPatterns.ts +++ b/Tasks/CopyFilesV2/Tests/L0rootsPatterns.ts @@ -28,17 +28,31 @@ answers.find[path.normalize('/srcDir')] = [ path.normalize('/srcDir/someOtherDir3'), ]; runner.setAnswers(answers); -runner.registerMockExport('stats', (itemPath: string) => { - console.log('##vso[task.debug]stats ' + itemPath); + +fs.existsSync = (itemPath: string) => { + switch (itemPath) { + case path.normalize('/srcDir/someOtherDir/file1.file'): + case path.normalize('/srcDir/someOtherDir/file2.file'): + case path.normalize('/srcDir/someOtherDir2/file2.file'): + return true; + default: + return false; + } +} + +fs.statSync = (itemPath: string) => { + const itemStats: fs.Stats = new fs.Stats(); switch (itemPath) { case path.normalize('/srcDir/someOtherDir/file1.file'): case path.normalize('/srcDir/someOtherDir/file2.file'): case path.normalize('/srcDir/someOtherDir2/file2.file'): - return { isDirectory: () => false }; + itemStats.isDirectory = () => false; + break; default: throw { code: 'ENOENT' }; } -}); + return itemStats; +} // as a precaution, disable fs.chmodSync. it should not be called during this scenario. fs.chmodSync = null; diff --git a/Tasks/CopyFilesV2/Tests/L0skipsIfExists.ts b/Tasks/CopyFilesV2/Tests/L0skipsIfExists.ts index 27753d3b5d64..f7c8cfc0ae58 100644 --- a/Tasks/CopyFilesV2/Tests/L0skipsIfExists.ts +++ b/Tasks/CopyFilesV2/Tests/L0skipsIfExists.ts @@ -22,20 +22,37 @@ answers.find[path.normalize('/srcDir')] = [ path.normalize('/srcDir/someOtherDir/file2.file'), ]; runner.setAnswers(answers); -runner.registerMockExport('stats', (itemPath: string) => { - console.log('##vso[task.debug]stats ' + itemPath); + +fs.existsSync = (itemPath: string) => { + switch (itemPath) { + case path.normalize('/srcDir/someOtherDir'): + case path.normalize('/destDir/someOtherDir'): + case path.normalize('/srcDir/someOtherDir/file1.file'): + case path.normalize('/srcDir/someOtherDir/file2.file'): + case path.normalize('/destDir/someOtherDir/file1.file'): + return true; + default: + return false; + } +} + +fs.statSync = (itemPath: string) => { + const itemStats: fs.Stats = new fs.Stats(); switch (itemPath) { case path.normalize('/srcDir/someOtherDir'): case path.normalize('/destDir/someOtherDir'): - return { isDirectory: () => true }; + itemStats.isDirectory = () => true; + break; case path.normalize('/srcDir/someOtherDir/file1.file'): case path.normalize('/srcDir/someOtherDir/file2.file'): case path.normalize('/destDir/someOtherDir/file1.file'): - return { isDirectory: () => false }; + itemStats.isDirectory = () => false; + break; default: throw { code: 'ENOENT' }; } -}); + return itemStats; +} // as a precaution, disable fs.chmodSync. it should not be called during this scenario. fs.chmodSync = null;