just-scripts 1.8.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.json CHANGED
@@ -2,7 +2,22 @@
2
2
  "name": "just-scripts",
3
3
  "entries": [
4
4
  {
5
- "date": "Tue, 05 Apr 2022 20:55:40 GMT",
5
+ "date": "Mon, 16 May 2022 20:50:31 GMT",
6
+ "tag": "just-scripts_v2.0.0",
7
+ "version": "2.0.0",
8
+ "comments": {
9
+ "major": [
10
+ {
11
+ "author": "benw@microsoft.com",
12
+ "package": "just-scripts",
13
+ "comment": "Add support for symlink creation in the copy task",
14
+ "commit": "02e45b2c092548c4ac43e142aaa510a7ad95ec49"
15
+ }
16
+ ]
17
+ }
18
+ },
19
+ {
20
+ "date": "Tue, 05 Apr 2022 20:55:43 GMT",
6
21
  "tag": "just-scripts_v1.8.2",
7
22
  "version": "1.8.2",
8
23
  "comments": {
package/CHANGELOG.md CHANGED
@@ -1,12 +1,20 @@
1
1
  # Change Log - just-scripts
2
2
 
3
- This log was last generated on Tue, 05 Apr 2022 20:55:40 GMT and should not be manually modified.
3
+ This log was last generated on Mon, 16 May 2022 20:50:31 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## 2.0.0
8
+
9
+ Mon, 16 May 2022 20:50:31 GMT
10
+
11
+ ### Major changes
12
+
13
+ - Add support for symlink creation in the copy task (benw@microsoft.com)
14
+
7
15
  ## 1.8.2
8
16
 
9
- Tue, 05 Apr 2022 20:55:40 GMT
17
+ Tue, 05 Apr 2022 20:55:43 GMT
10
18
 
11
19
  ### Patches
12
20
 
@@ -8,6 +8,12 @@ export interface CopyInstruction {
8
8
  * The path+filename of the destination file.
9
9
  */
10
10
  destinationFilePath: string;
11
+ /**
12
+ * Set to true if a copy or merge should be performed, false if a symlink should be created.
13
+ * If multiple source files are specified (i.e. a merge), this must be true or undefined.
14
+ * The default value of undefined is equivalent to true for a merge, false in all other cases.
15
+ */
16
+ noSymlink?: boolean;
11
17
  }
12
18
  export interface CopyConfig {
13
19
  copyInstructions: CopyInstruction[];
@@ -17,13 +23,13 @@ export interface CopyConfig {
17
23
  * For example copyFilesToDestinationDirectory(['some/path/foo.js', 'bar.js'], 'dest/target') would result in the creation of
18
24
  * files 'dest/target/foo.js' and 'dest/target/bar.js'.
19
25
  */
20
- export declare function copyFilesToDestinationDirectory(sourceFilePaths: string | string[], destinationDirectory: string): CopyInstruction[];
26
+ export declare function copyFilesToDestinationDirectory(sourceFilePaths: string | string[], destinationDirectory: string, noSymlinks?: boolean): CopyInstruction[];
21
27
  /**
22
28
  * Copies a file into a destination directory with a different name.
23
29
  * For example copyFileToDestinationDirectoryWithRename('some/path/foo.js', 'bar.js', 'dest/target') would result in the creation of
24
30
  * the file 'dest/target/bar.js'.
25
31
  */
26
- export declare function copyFileToDestinationDirectoryWithRename(sourceFilePath: string, destinationName: string, destinationDirectory: string): CopyInstruction[];
32
+ export declare function copyFileToDestinationDirectoryWithRename(sourceFilePath: string, destinationName: string, destinationDirectory: string, noSymlink?: boolean): CopyInstruction[];
27
33
  /**
28
34
  * Copies files into a destination directory with different names.
29
35
  * For example copyFilesToDestinationDirectoryWithRename([{sourceFilePath:'some/path/foo.js', destinationName:'bar.js'}], 'dest/target')
@@ -32,12 +38,12 @@ export declare function copyFileToDestinationDirectoryWithRename(sourceFilePath:
32
38
  export declare function copyFilesToDestinationDirectoryWithRename(instrs: {
33
39
  sourceFilePath: string;
34
40
  destinationName: string;
35
- }[], destinationDirectory: string): CopyInstruction[];
41
+ }[], destinationDirectory: string, noSymlinks?: boolean): CopyInstruction[];
36
42
  /**
37
43
  * Copies all the files in a directory to the output folder.
38
44
  * You can optionally provide a filter function that determines which files to copy.
39
45
  */
40
- export declare function copyFilesInDirectory(sourceDirectoryPath: string, outputDirectoryPath: string, filterFunction?: (file: string) => boolean): CopyInstruction[];
46
+ export declare function copyFilesInDirectory(sourceDirectoryPath: string, outputDirectoryPath: string, filterFunction?: (file: string) => boolean, noSymlinks?: boolean): CopyInstruction[];
41
47
  /**
42
48
  * Merges the contents of multiple files and places them in the output folder.
43
49
  * This should only be used for text files and it should not be used for JavaScript
@@ -1 +1 @@
1
- {"version":3,"file":"CopyInstruction.d.ts","sourceRoot":"","sources":["../../src/copy/CopyInstruction.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,cAAc,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAElC;;OAEG;IACH,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,gBAAgB,EAAE,eAAe,EAAE,CAAC;CACrC;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,oBAAoB,EAAE,MAAM,GAAG,eAAe,EAAE,CAKnI;AAED;;;;GAIG;AACH,wBAAgB,wCAAwC,CACtD,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,MAAM,EACvB,oBAAoB,EAAE,MAAM,GAC3B,eAAe,EAAE,CAEnB;AAED;;;;GAIG;AACH,wBAAgB,yCAAyC,CACvD,MAAM,EAAE;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,EAAE,EAC7D,oBAAoB,EAAE,MAAM,GAC3B,eAAe,EAAE,CAKnB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,mBAAmB,EAAE,MAAM,EAC3B,mBAAmB,EAAE,MAAM,EAC3B,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GACzC,eAAe,EAAE,CAUnB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,eAAe,EAAE,MAAM,EAAE,EAAE,mBAAmB,EAAE,MAAM,GAAG,eAAe,CAKlG"}
1
+ {"version":3,"file":"CopyInstruction.d.ts","sourceRoot":"","sources":["../../src/copy/CopyInstruction.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,cAAc,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAElC;;OAEG;IACH,mBAAmB,EAAE,MAAM,CAAC;IAE5B;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,gBAAgB,EAAE,eAAe,EAAE,CAAC;CACrC;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,eAAe,EAAE,MAAM,GAAG,MAAM,EAAE,EAClC,oBAAoB,EAAE,MAAM,EAC5B,UAAU,CAAC,EAAE,OAAO,GACnB,eAAe,EAAE,CAMnB;AAED;;;;GAIG;AACH,wBAAgB,wCAAwC,CACtD,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,MAAM,EACvB,oBAAoB,EAAE,MAAM,EAC5B,SAAS,CAAC,EAAE,OAAO,GAClB,eAAe,EAAE,CAEnB;AAED;;;;GAIG;AACH,wBAAgB,yCAAyC,CACvD,MAAM,EAAE;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,EAAE,EAC7D,oBAAoB,EAAE,MAAM,EAC5B,UAAU,CAAC,EAAE,OAAO,GACnB,eAAe,EAAE,CAMnB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,mBAAmB,EAAE,MAAM,EAC3B,mBAAmB,EAAE,MAAM,EAC3B,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,EAC1C,UAAU,CAAC,EAAE,OAAO,GACnB,eAAe,EAAE,CAWnB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,eAAe,EAAE,MAAM,EAAE,EAAE,mBAAmB,EAAE,MAAM,GAAG,eAAe,CAKlG"}
@@ -9,10 +9,11 @@ const arrayify_1 = require("../arrayUtils/arrayify");
9
9
  * For example copyFilesToDestinationDirectory(['some/path/foo.js', 'bar.js'], 'dest/target') would result in the creation of
10
10
  * files 'dest/target/foo.js' and 'dest/target/bar.js'.
11
11
  */
12
- function copyFilesToDestinationDirectory(sourceFilePaths, destinationDirectory) {
12
+ function copyFilesToDestinationDirectory(sourceFilePaths, destinationDirectory, noSymlinks) {
13
13
  return arrayify_1.arrayify(sourceFilePaths).map(sourceName => ({
14
14
  sourceFilePath: path_1.normalize(sourceName),
15
15
  destinationFilePath: path_1.join(destinationDirectory, path_1.basename(sourceName)),
16
+ noSymlink: noSymlinks,
16
17
  }));
17
18
  }
18
19
  exports.copyFilesToDestinationDirectory = copyFilesToDestinationDirectory;
@@ -21,8 +22,8 @@ exports.copyFilesToDestinationDirectory = copyFilesToDestinationDirectory;
21
22
  * For example copyFileToDestinationDirectoryWithRename('some/path/foo.js', 'bar.js', 'dest/target') would result in the creation of
22
23
  * the file 'dest/target/bar.js'.
23
24
  */
24
- function copyFileToDestinationDirectoryWithRename(sourceFilePath, destinationName, destinationDirectory) {
25
- return [{ sourceFilePath, destinationFilePath: path_1.join(destinationDirectory, destinationName) }];
25
+ function copyFileToDestinationDirectoryWithRename(sourceFilePath, destinationName, destinationDirectory, noSymlink) {
26
+ return [{ sourceFilePath, destinationFilePath: path_1.join(destinationDirectory, destinationName), noSymlink }];
26
27
  }
27
28
  exports.copyFileToDestinationDirectoryWithRename = copyFileToDestinationDirectoryWithRename;
28
29
  /**
@@ -30,10 +31,11 @@ exports.copyFileToDestinationDirectoryWithRename = copyFileToDestinationDirector
30
31
  * For example copyFilesToDestinationDirectoryWithRename([{sourceFilePath:'some/path/foo.js', destinationName:'bar.js'}], 'dest/target')
31
32
  * would result in the creation of the file 'dest/target/bar.js'.
32
33
  */
33
- function copyFilesToDestinationDirectoryWithRename(instrs, destinationDirectory) {
34
+ function copyFilesToDestinationDirectoryWithRename(instrs, destinationDirectory, noSymlinks) {
34
35
  return instrs.map(instr => ({
35
36
  sourceFilePath: instr.sourceFilePath,
36
37
  destinationFilePath: path_1.join(destinationDirectory, instr.destinationName),
38
+ noSymlink: noSymlinks,
37
39
  }));
38
40
  }
39
41
  exports.copyFilesToDestinationDirectoryWithRename = copyFilesToDestinationDirectoryWithRename;
@@ -41,7 +43,7 @@ exports.copyFilesToDestinationDirectoryWithRename = copyFilesToDestinationDirect
41
43
  * Copies all the files in a directory to the output folder.
42
44
  * You can optionally provide a filter function that determines which files to copy.
43
45
  */
44
- function copyFilesInDirectory(sourceDirectoryPath, outputDirectoryPath, filterFunction) {
46
+ function copyFilesInDirectory(sourceDirectoryPath, outputDirectoryPath, filterFunction, noSymlinks) {
45
47
  let files = fs_1.readdirSync(sourceDirectoryPath);
46
48
  if (filterFunction) {
47
49
  files = files.filter(filterFunction);
@@ -49,6 +51,7 @@ function copyFilesInDirectory(sourceDirectoryPath, outputDirectoryPath, filterFu
49
51
  return files.map(file => ({
50
52
  sourceFilePath: path_1.join(sourceDirectoryPath, file),
51
53
  destinationFilePath: path_1.join(outputDirectoryPath, file),
54
+ noSymlink: noSymlinks,
52
55
  }));
53
56
  }
54
57
  exports.copyFilesInDirectory = copyFilesInDirectory;
@@ -1 +1 @@
1
- {"version":3,"file":"CopyInstruction.js","sourceRoot":"","sources":["../../src/copy/CopyInstruction.ts"],"names":[],"mappings":";;;AAAA,+BAAiD;AACjD,2BAAiC;AACjC,qDAAkD;AAmBlD;;;;GAIG;AACH,SAAgB,+BAA+B,CAAC,eAAkC,EAAE,oBAA4B;IAC9G,OAAO,mBAAQ,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAClD,cAAc,EAAE,gBAAS,CAAC,UAAU,CAAC;QACrC,mBAAmB,EAAE,WAAI,CAAC,oBAAoB,EAAE,eAAQ,CAAC,UAAU,CAAC,CAAC;KACtE,CAAC,CAAC,CAAC;AACN,CAAC;AALD,0EAKC;AAED;;;;GAIG;AACH,SAAgB,wCAAwC,CACtD,cAAsB,EACtB,eAAuB,EACvB,oBAA4B;IAE5B,OAAO,CAAC,EAAE,cAAc,EAAE,mBAAmB,EAAE,WAAI,CAAC,oBAAoB,EAAE,eAAe,CAAC,EAAE,CAAC,CAAC;AAChG,CAAC;AAND,4FAMC;AAED;;;;GAIG;AACH,SAAgB,yCAAyC,CACvD,MAA6D,EAC7D,oBAA4B;IAE5B,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC1B,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,mBAAmB,EAAE,WAAI,CAAC,oBAAoB,EAAE,KAAK,CAAC,eAAe,CAAC;KACvE,CAAC,CAAC,CAAC;AACN,CAAC;AARD,8FAQC;AAED;;;GAGG;AACH,SAAgB,oBAAoB,CAClC,mBAA2B,EAC3B,mBAA2B,EAC3B,cAA0C;IAE1C,IAAI,KAAK,GAAG,gBAAW,CAAC,mBAAmB,CAAC,CAAC;IAE7C,IAAI,cAAc,EAAE;QAClB,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;KACtC;IACD,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACxB,cAAc,EAAE,WAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC;QAC/C,mBAAmB,EAAE,WAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC;KACrD,CAAC,CAAC,CAAC;AACN,CAAC;AAdD,oDAcC;AAED;;;;GAIG;AACH,SAAgB,UAAU,CAAC,eAAyB,EAAE,mBAA2B;IAC/E,OAAO;QACL,cAAc,EAAE,eAAe;QAC/B,mBAAmB;KACpB,CAAC;AACJ,CAAC;AALD,gCAKC"}
1
+ {"version":3,"file":"CopyInstruction.js","sourceRoot":"","sources":["../../src/copy/CopyInstruction.ts"],"names":[],"mappings":";;;AAAA,+BAAiD;AACjD,2BAAiC;AACjC,qDAAkD;AA0BlD;;;;GAIG;AACH,SAAgB,+BAA+B,CAC7C,eAAkC,EAClC,oBAA4B,EAC5B,UAAoB;IAEpB,OAAO,mBAAQ,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAClD,cAAc,EAAE,gBAAS,CAAC,UAAU,CAAC;QACrC,mBAAmB,EAAE,WAAI,CAAC,oBAAoB,EAAE,eAAQ,CAAC,UAAU,CAAC,CAAC;QACrE,SAAS,EAAE,UAAU;KACtB,CAAC,CAAC,CAAC;AACN,CAAC;AAVD,0EAUC;AAED;;;;GAIG;AACH,SAAgB,wCAAwC,CACtD,cAAsB,EACtB,eAAuB,EACvB,oBAA4B,EAC5B,SAAmB;IAEnB,OAAO,CAAC,EAAE,cAAc,EAAE,mBAAmB,EAAE,WAAI,CAAC,oBAAoB,EAAE,eAAe,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;AAC3G,CAAC;AAPD,4FAOC;AAED;;;;GAIG;AACH,SAAgB,yCAAyC,CACvD,MAA6D,EAC7D,oBAA4B,EAC5B,UAAoB;IAEpB,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC1B,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,mBAAmB,EAAE,WAAI,CAAC,oBAAoB,EAAE,KAAK,CAAC,eAAe,CAAC;QACtE,SAAS,EAAE,UAAU;KACtB,CAAC,CAAC,CAAC;AACN,CAAC;AAVD,8FAUC;AAED;;;GAGG;AACH,SAAgB,oBAAoB,CAClC,mBAA2B,EAC3B,mBAA2B,EAC3B,cAA0C,EAC1C,UAAoB;IAEpB,IAAI,KAAK,GAAG,gBAAW,CAAC,mBAAmB,CAAC,CAAC;IAE7C,IAAI,cAAc,EAAE;QAClB,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;KACtC;IACD,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACxB,cAAc,EAAE,WAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC;QAC/C,mBAAmB,EAAE,WAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC;QACpD,SAAS,EAAE,UAAU;KACtB,CAAC,CAAC,CAAC;AACN,CAAC;AAhBD,oDAgBC;AAED;;;;GAIG;AACH,SAAgB,UAAU,CAAC,eAAyB,EAAE,mBAA2B;IAC/E,OAAO;QACL,cAAc,EAAE,eAAe;QAC/B,mBAAmB;KACpB,CAAC;AACJ,CAAC;AALD,gCAKC"}
@@ -1 +1 @@
1
- {"version":3,"file":"executeCopyInstructions.d.ts","sourceRoot":"","sources":["../../src/copy/executeCopyInstructions.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmB,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAIhE;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAK3F"}
1
+ {"version":3,"file":"executeCopyInstructions.d.ts","sourceRoot":"","sources":["../../src/copy/executeCopyInstructions.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmB,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAIhE;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAM3F"}
@@ -10,19 +10,32 @@ const uniqueValues_1 = require("../arrayUtils/uniqueValues");
10
10
  */
11
11
  async function executeCopyInstructions(config) {
12
12
  if (config && config.copyInstructions) {
13
+ validateConfig(config.copyInstructions);
13
14
  await createDirectories(config.copyInstructions);
14
15
  await Promise.all(config.copyInstructions.map(executeSingleCopyInstruction));
15
16
  }
16
17
  }
17
18
  exports.executeCopyInstructions = executeCopyInstructions;
19
+ function validateConfig(copyInstructions) {
20
+ copyInstructions.forEach(instr => {
21
+ if (instr.noSymlink === false && Array.isArray(instr.sourceFilePath) && instr.sourceFilePath.length > 1) {
22
+ throw new Error('Multiple source files cannot be specified when making a symlink');
23
+ }
24
+ });
25
+ }
18
26
  function createDirectories(copyInstructions) {
19
27
  return Promise.all(uniqueValues_1.uniqueValues(copyInstructions.map(instruction => path_1.dirname(instruction.destinationFilePath))).map(dirname => fs_extra_1.ensureDir(dirname)));
20
28
  }
21
29
  function executeSingleCopyInstruction(copyInstruction) {
22
30
  const sourceFileNames = arrayify_1.arrayify(copyInstruction.sourceFilePath);
23
- // source and dest are 1-to-1? perform binary copy.
31
+ // source and dest are 1-to-1? perform binary copy or symlink as desired.
24
32
  if (sourceFileNames.length === 1) {
25
- return fs_extra_1.copy(sourceFileNames[0], copyInstruction.destinationFilePath);
33
+ if (copyInstruction.noSymlink) {
34
+ return fs_extra_1.copy(sourceFileNames[0], copyInstruction.destinationFilePath);
35
+ }
36
+ else {
37
+ return fs_extra_1.ensureSymlink(path_1.resolve(sourceFileNames[0]), copyInstruction.destinationFilePath);
38
+ }
26
39
  }
27
40
  // perform text merge operation.
28
41
  return Promise.all(sourceFileNames.map(fileName => fs_extra_1.readFile(fileName))).then(fileContents => {
@@ -1 +1 @@
1
- {"version":3,"file":"executeCopyInstructions.js","sourceRoot":"","sources":["../../src/copy/executeCopyInstructions.ts"],"names":[],"mappings":";;;AAAA,+BAA+B;AAC/B,uCAAgE;AAEhE,qDAAkD;AAClD,6DAA0D;AAE1D;;GAEG;AACI,KAAK,UAAU,uBAAuB,CAAC,MAA8B;IAC1E,IAAI,MAAM,IAAI,MAAM,CAAC,gBAAgB,EAAE;QACrC,MAAM,iBAAiB,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;QACjD,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC,CAAC;KAC9E;AACH,CAAC;AALD,0DAKC;AAED,SAAS,iBAAiB,CAAC,gBAAmC;IAC5D,OAAO,OAAO,CAAC,GAAG,CAChB,2BAAY,CAAC,gBAAgB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,cAAO,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,oBAAS,CAAC,OAAO,CAAC,CAAC,CAC/H,CAAC;AACJ,CAAC;AAED,SAAS,4BAA4B,CAAC,eAAgC;IACpE,MAAM,eAAe,GAAG,mBAAQ,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;IAEjE,oDAAoD;IACpD,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE;QAChC,OAAO,eAAI,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC,mBAAmB,CAAC,CAAC;KACtE;IAED,gCAAgC;IAChC,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,mBAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE;QAC1F,OAAO,oBAAS,CAAC,eAAe,CAAC,mBAAmB,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACjF,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"executeCopyInstructions.js","sourceRoot":"","sources":["../../src/copy/executeCopyInstructions.ts"],"names":[],"mappings":";;;AAAA,+BAAwC;AACxC,uCAA+E;AAE/E,qDAAkD;AAClD,6DAA0D;AAE1D;;GAEG;AACI,KAAK,UAAU,uBAAuB,CAAC,MAA8B;IAC1E,IAAI,MAAM,IAAI,MAAM,CAAC,gBAAgB,EAAE;QACrC,cAAc,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;QACxC,MAAM,iBAAiB,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;QACjD,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC,CAAC;KAC9E;AACH,CAAC;AAND,0DAMC;AAED,SAAS,cAAc,CAAC,gBAAmC;IACzD,gBAAgB,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QAC/B,IAAI,KAAK,CAAC,SAAS,KAAK,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,KAAK,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE;YACvG,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;SACpF;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,iBAAiB,CAAC,gBAAmC;IAC5D,OAAO,OAAO,CAAC,GAAG,CAChB,2BAAY,CAAC,gBAAgB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,cAAO,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,oBAAS,CAAC,OAAO,CAAC,CAAC,CAC/H,CAAC;AACJ,CAAC;AAED,SAAS,4BAA4B,CAAC,eAAgC;IACpE,MAAM,eAAe,GAAG,mBAAQ,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;IAEjE,0EAA0E;IAC1E,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE;QAChC,IAAI,eAAe,CAAC,SAAS,EAAE;YAC7B,OAAO,eAAI,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC,mBAAmB,CAAC,CAAC;SACtE;aAAM;YACL,OAAO,wBAAa,CAAC,cAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC,mBAAmB,CAAC,CAAC;SACxF;KACF;IAED,gCAAgC;IAChC,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,mBAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE;QAC1F,OAAO,oBAAS,CAAC,eAAe,CAAC,mBAAmB,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACjF,CAAC,CAAC,CAAC;AACL,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "just-scripts",
3
- "version": "1.8.2",
3
+ "version": "2.0.0",
4
4
  "description": "Just Stack Scripts",
5
5
  "keywords": [],
6
6
  "repository": {
@@ -13,6 +13,13 @@ export interface CopyInstruction {
13
13
  * The path+filename of the destination file.
14
14
  */
15
15
  destinationFilePath: string;
16
+
17
+ /**
18
+ * Set to true if a copy or merge should be performed, false if a symlink should be created.
19
+ * If multiple source files are specified (i.e. a merge), this must be true or undefined.
20
+ * The default value of undefined is equivalent to true for a merge, false in all other cases.
21
+ */
22
+ noSymlink?: boolean;
16
23
  }
17
24
 
18
25
  export interface CopyConfig {
@@ -24,10 +31,15 @@ export interface CopyConfig {
24
31
  * For example copyFilesToDestinationDirectory(['some/path/foo.js', 'bar.js'], 'dest/target') would result in the creation of
25
32
  * files 'dest/target/foo.js' and 'dest/target/bar.js'.
26
33
  */
27
- export function copyFilesToDestinationDirectory(sourceFilePaths: string | string[], destinationDirectory: string): CopyInstruction[] {
34
+ export function copyFilesToDestinationDirectory(
35
+ sourceFilePaths: string | string[],
36
+ destinationDirectory: string,
37
+ noSymlinks?: boolean,
38
+ ): CopyInstruction[] {
28
39
  return arrayify(sourceFilePaths).map(sourceName => ({
29
40
  sourceFilePath: normalize(sourceName),
30
41
  destinationFilePath: join(destinationDirectory, basename(sourceName)),
42
+ noSymlink: noSymlinks,
31
43
  }));
32
44
  }
33
45
 
@@ -40,8 +52,9 @@ export function copyFileToDestinationDirectoryWithRename(
40
52
  sourceFilePath: string,
41
53
  destinationName: string,
42
54
  destinationDirectory: string,
55
+ noSymlink?: boolean,
43
56
  ): CopyInstruction[] {
44
- return [{ sourceFilePath, destinationFilePath: join(destinationDirectory, destinationName) }];
57
+ return [{ sourceFilePath, destinationFilePath: join(destinationDirectory, destinationName), noSymlink }];
45
58
  }
46
59
 
47
60
  /**
@@ -52,10 +65,12 @@ export function copyFileToDestinationDirectoryWithRename(
52
65
  export function copyFilesToDestinationDirectoryWithRename(
53
66
  instrs: { sourceFilePath: string; destinationName: string }[],
54
67
  destinationDirectory: string,
68
+ noSymlinks?: boolean,
55
69
  ): CopyInstruction[] {
56
70
  return instrs.map(instr => ({
57
71
  sourceFilePath: instr.sourceFilePath,
58
72
  destinationFilePath: join(destinationDirectory, instr.destinationName),
73
+ noSymlink: noSymlinks,
59
74
  }));
60
75
  }
61
76
 
@@ -67,6 +82,7 @@ export function copyFilesInDirectory(
67
82
  sourceDirectoryPath: string,
68
83
  outputDirectoryPath: string,
69
84
  filterFunction?: (file: string) => boolean,
85
+ noSymlinks?: boolean,
70
86
  ): CopyInstruction[] {
71
87
  let files = readdirSync(sourceDirectoryPath);
72
88
 
@@ -76,6 +92,7 @@ export function copyFilesInDirectory(
76
92
  return files.map(file => ({
77
93
  sourceFilePath: join(sourceDirectoryPath, file),
78
94
  destinationFilePath: join(outputDirectoryPath, file),
95
+ noSymlink: noSymlinks,
79
96
  }));
80
97
  }
81
98
 
@@ -1,8 +1,9 @@
1
+ import * as mockfs from 'mock-fs';
1
2
  import * as path from 'path';
2
3
  import * as fs from 'fs';
3
- import mockfs = require('mock-fs');
4
4
  // import { dirSync, fileSync, DirResult, FileResult } from 'tmp';
5
5
  import { executeCopyInstructions } from '../executeCopyInstructions';
6
+ import { CopyInstruction } from '../CopyInstruction';
6
7
 
7
8
  describe('executeCopyInstructions functional tests', () => {
8
9
  const sourceDir = 'sourceDir';
@@ -30,8 +31,8 @@ describe('executeCopyInstructions functional tests', () => {
30
31
  mockfs.restore();
31
32
  });
32
33
 
33
- it('executes single source copy instructions', async () => {
34
- const copyInstruction = {
34
+ it('executes single source copy instructions (symlink)', async () => {
35
+ const copyInstruction: CopyInstruction = {
35
36
  sourceFilePath: sourceFilePath1,
36
37
  destinationFilePath: destFilePath,
37
38
  };
@@ -43,13 +44,15 @@ describe('executeCopyInstructions functional tests', () => {
43
44
  });
44
45
 
45
46
  expect(fs.existsSync(destFilePath)).toBeTruthy();
47
+ expect(fs.lstatSync(destFilePath).isSymbolicLink()).toBeTruthy();
46
48
  expect(fs.readFileSync(destFilePath).toString()).toEqual(sourceFileContents1);
47
49
  });
48
50
 
49
- it('executes single source (arrayified) copy instructions', async () => {
50
- const copyInstruction = {
51
+ it('executes single source (arrayified) copy instructions (copy)', async () => {
52
+ const copyInstruction: CopyInstruction = {
51
53
  sourceFilePath: [sourceFilePath1],
52
54
  destinationFilePath: destFilePath,
55
+ noSymlink: true,
53
56
  };
54
57
 
55
58
  expect(fs.existsSync(destFilePath)).toBeFalsy();
@@ -59,11 +62,12 @@ describe('executeCopyInstructions functional tests', () => {
59
62
  });
60
63
 
61
64
  expect(fs.existsSync(destFilePath)).toBeTruthy();
65
+ expect(fs.lstatSync(destFilePath).isSymbolicLink()).toBeFalsy();
62
66
  expect(fs.readFileSync(destFilePath).toString()).toEqual(sourceFileContents1);
63
67
  });
64
68
 
65
69
  it('merges output', async () => {
66
- const copyInstruction = {
70
+ const copyInstruction: CopyInstruction = {
67
71
  sourceFilePath: [sourceFilePath1, sourceFilePath2],
68
72
  destinationFilePath: destFilePath,
69
73
  };
@@ -77,9 +81,24 @@ describe('executeCopyInstructions functional tests', () => {
77
81
  });
78
82
 
79
83
  expect(fs.existsSync(destFilePath)).toBeTruthy();
84
+ expect(fs.lstatSync(destFilePath).isSymbolicLink()).toBeFalsy();
80
85
  expect(fs.readFileSync(destFilePath).toString()).toEqual(expectedOutput);
81
86
  });
82
87
 
88
+ it('fails to validate merge + symlink copy instruction', async () => {
89
+ const copyInstruction: CopyInstruction = {
90
+ sourceFilePath: [sourceFilePath1, sourceFilePath2],
91
+ destinationFilePath: destFilePath,
92
+ noSymlink: false,
93
+ };
94
+
95
+ const promise = executeCopyInstructions({
96
+ copyInstructions: [copyInstruction],
97
+ });
98
+
99
+ await expect(promise).rejects.toThrow();
100
+ });
101
+
83
102
  /**
84
103
  * TODO:
85
104
  * Rationalize and document expected executeCopyInstructions behavior.
@@ -1,5 +1,5 @@
1
- import { dirname } from 'path';
2
- import { readFile, writeFile, copy, ensureDir } from 'fs-extra';
1
+ import { dirname, resolve } from 'path';
2
+ import { readFile, writeFile, copy, ensureDir, ensureSymlink } from 'fs-extra';
3
3
  import { CopyInstruction, CopyConfig } from './CopyInstruction';
4
4
  import { arrayify } from '../arrayUtils/arrayify';
5
5
  import { uniqueValues } from '../arrayUtils/uniqueValues';
@@ -9,11 +9,20 @@ import { uniqueValues } from '../arrayUtils/uniqueValues';
9
9
  */
10
10
  export async function executeCopyInstructions(config: CopyConfig | undefined): Promise<void> {
11
11
  if (config && config.copyInstructions) {
12
+ validateConfig(config.copyInstructions);
12
13
  await createDirectories(config.copyInstructions);
13
14
  await Promise.all(config.copyInstructions.map(executeSingleCopyInstruction));
14
15
  }
15
16
  }
16
17
 
18
+ function validateConfig(copyInstructions: CopyInstruction[]) {
19
+ copyInstructions.forEach(instr => {
20
+ if (instr.noSymlink === false && Array.isArray(instr.sourceFilePath) && instr.sourceFilePath.length > 1) {
21
+ throw new Error('Multiple source files cannot be specified when making a symlink');
22
+ }
23
+ });
24
+ }
25
+
17
26
  function createDirectories(copyInstructions: CopyInstruction[]) {
18
27
  return Promise.all(
19
28
  uniqueValues(copyInstructions.map(instruction => dirname(instruction.destinationFilePath))).map(dirname => ensureDir(dirname)),
@@ -23,9 +32,13 @@ function createDirectories(copyInstructions: CopyInstruction[]) {
23
32
  function executeSingleCopyInstruction(copyInstruction: CopyInstruction) {
24
33
  const sourceFileNames = arrayify(copyInstruction.sourceFilePath);
25
34
 
26
- // source and dest are 1-to-1? perform binary copy.
35
+ // source and dest are 1-to-1? perform binary copy or symlink as desired.
27
36
  if (sourceFileNames.length === 1) {
28
- return copy(sourceFileNames[0], copyInstruction.destinationFilePath);
37
+ if (copyInstruction.noSymlink) {
38
+ return copy(sourceFileNames[0], copyInstruction.destinationFilePath);
39
+ } else {
40
+ return ensureSymlink(resolve(sourceFileNames[0]), copyInstruction.destinationFilePath);
41
+ }
29
42
  }
30
43
 
31
44
  // perform text merge operation.