@rushstack/package-deps-hash 4.3.10 → 4.3.12
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 +24 -0
- package/CHANGELOG.md +11 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/lib/getPackageDeps.js +24 -15
- package/lib/getPackageDeps.js.map +1 -1
- package/lib/getRepoState.js +28 -66
- package/lib/getRepoState.js.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.json
CHANGED
|
@@ -1,6 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rushstack/package-deps-hash",
|
|
3
3
|
"entries": [
|
|
4
|
+
{
|
|
5
|
+
"version": "4.3.12",
|
|
6
|
+
"tag": "@rushstack/package-deps-hash_v4.3.12",
|
|
7
|
+
"date": "Tue, 11 Mar 2025 00:11:25 GMT",
|
|
8
|
+
"comments": {
|
|
9
|
+
"dependency": [
|
|
10
|
+
{
|
|
11
|
+
"comment": "Updating dependency \"@rushstack/heft\" to `0.69.3`"
|
|
12
|
+
}
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"version": "4.3.11",
|
|
18
|
+
"tag": "@rushstack/package-deps-hash_v4.3.11",
|
|
19
|
+
"date": "Sat, 01 Mar 2025 05:00:09 GMT",
|
|
20
|
+
"comments": {
|
|
21
|
+
"dependency": [
|
|
22
|
+
{
|
|
23
|
+
"comment": "Updating dependency \"@rushstack/heft\" to `0.69.2`"
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
},
|
|
4
28
|
{
|
|
5
29
|
"version": "4.3.10",
|
|
6
30
|
"tag": "@rushstack/package-deps-hash_v4.3.10",
|
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
# Change Log - @rushstack/package-deps-hash
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Tue, 11 Mar 2025 00:11:25 GMT and should not be manually modified.
|
|
4
|
+
|
|
5
|
+
## 4.3.12
|
|
6
|
+
Tue, 11 Mar 2025 00:11:25 GMT
|
|
7
|
+
|
|
8
|
+
_Version update only_
|
|
9
|
+
|
|
10
|
+
## 4.3.11
|
|
11
|
+
Sat, 01 Mar 2025 05:00:09 GMT
|
|
12
|
+
|
|
13
|
+
_Version update only_
|
|
4
14
|
|
|
5
15
|
## 4.3.10
|
|
6
16
|
Thu, 27 Feb 2025 01:10:39 GMT
|
package/dist/tsdoc-metadata.json
CHANGED
package/lib/getPackageDeps.js
CHANGED
|
@@ -17,15 +17,31 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
17
17
|
}) : function(o, v) {
|
|
18
18
|
o["default"] = v;
|
|
19
19
|
});
|
|
20
|
-
var __importStar = (this && this.__importStar) || function (
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
};
|
|
20
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
21
|
+
var ownKeys = function(o) {
|
|
22
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
23
|
+
var ar = [];
|
|
24
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
25
|
+
return ar;
|
|
26
|
+
};
|
|
27
|
+
return ownKeys(o);
|
|
28
|
+
};
|
|
29
|
+
return function (mod) {
|
|
30
|
+
if (mod && mod.__esModule) return mod;
|
|
31
|
+
var result = {};
|
|
32
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
33
|
+
__setModuleDefault(result, mod);
|
|
34
|
+
return result;
|
|
35
|
+
};
|
|
36
|
+
})();
|
|
27
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
-
exports.
|
|
38
|
+
exports.parseGitFilename = parseGitFilename;
|
|
39
|
+
exports.parseGitLsTree = parseGitLsTree;
|
|
40
|
+
exports.parseGitStatus = parseGitStatus;
|
|
41
|
+
exports.getGitHashForFiles = getGitHashForFiles;
|
|
42
|
+
exports.gitLsTree = gitLsTree;
|
|
43
|
+
exports.gitStatus = gitStatus;
|
|
44
|
+
exports.getPackageDeps = getPackageDeps;
|
|
29
45
|
const path = __importStar(require("path"));
|
|
30
46
|
const node_core_library_1 = require("@rushstack/node-core-library");
|
|
31
47
|
const getRepoState_1 = require("./getRepoState");
|
|
@@ -64,7 +80,6 @@ function parseGitFilename(filename) {
|
|
|
64
80
|
// Finally, decode the filename and unescape the escaped UTF-8 chars
|
|
65
81
|
return JSON.parse(decodeURIComponent(filename));
|
|
66
82
|
}
|
|
67
|
-
exports.parseGitFilename = parseGitFilename;
|
|
68
83
|
/**
|
|
69
84
|
* Parses the output of the "git ls-tree" command
|
|
70
85
|
*/
|
|
@@ -94,7 +109,6 @@ function parseGitLsTree(output) {
|
|
|
94
109
|
}
|
|
95
110
|
return changes;
|
|
96
111
|
}
|
|
97
|
-
exports.parseGitLsTree = parseGitLsTree;
|
|
98
112
|
/**
|
|
99
113
|
* Parses the output of the "git status" command
|
|
100
114
|
*/
|
|
@@ -142,7 +156,6 @@ function parseGitStatus(output, packagePath) {
|
|
|
142
156
|
}
|
|
143
157
|
return changes;
|
|
144
158
|
}
|
|
145
|
-
exports.parseGitStatus = parseGitStatus;
|
|
146
159
|
/**
|
|
147
160
|
* Takes a list of files and returns the current git hashes for them
|
|
148
161
|
*
|
|
@@ -172,7 +185,6 @@ function getGitHashForFiles(filesToHash, packagePath, gitPath) {
|
|
|
172
185
|
}
|
|
173
186
|
return changes;
|
|
174
187
|
}
|
|
175
|
-
exports.getGitHashForFiles = getGitHashForFiles;
|
|
176
188
|
/**
|
|
177
189
|
* Executes "git ls-tree" in a folder
|
|
178
190
|
*/
|
|
@@ -186,7 +198,6 @@ function gitLsTree(cwdPath, gitPath) {
|
|
|
186
198
|
}
|
|
187
199
|
return result.stdout;
|
|
188
200
|
}
|
|
189
|
-
exports.gitLsTree = gitLsTree;
|
|
190
201
|
/**
|
|
191
202
|
* Executes "git status" in a folder
|
|
192
203
|
*/
|
|
@@ -208,7 +219,6 @@ function gitStatus(cwdPath, gitPath) {
|
|
|
208
219
|
}
|
|
209
220
|
return result.stdout;
|
|
210
221
|
}
|
|
211
|
-
exports.gitStatus = gitStatus;
|
|
212
222
|
/**
|
|
213
223
|
* Builds an object containing hashes for the files under the specified `packagePath` folder.
|
|
214
224
|
* @param packagePath - The folder path to derive the package dependencies from. This is typically the folder
|
|
@@ -251,5 +261,4 @@ function getPackageDeps(packagePath = process.cwd(), excludedPaths, gitPath) {
|
|
|
251
261
|
}
|
|
252
262
|
return result;
|
|
253
263
|
}
|
|
254
|
-
exports.getPackageDeps = getPackageDeps;
|
|
255
264
|
//# sourceMappingURL=getPackageDeps.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getPackageDeps.js","sourceRoot":"","sources":["../src/getPackageDeps.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type * as child_process from 'child_process';\nimport * as path from 'path';\nimport { Executable } from '@rushstack/node-core-library';\n\nimport { ensureGitMinimumVersion } from './getRepoState';\n\n/**\n * Parses a quoted filename sourced from the output of the \"git status\" command.\n *\n * Paths with non-standard characters will be enclosed with double-quotes, and non-standard\n * characters will be backslash escaped (ex. double-quotes, non-ASCII characters). The\n * escaped chars can be included in one of two ways:\n * - backslash-escaped chars (ex. \\\")\n * - octal encoded chars (ex. \\347)\n *\n * See documentation: https://git-scm.com/docs/git-status\n */\nexport function parseGitFilename(filename: string): string {\n // If there are no double-quotes around the string, then there are no escaped characters\n // to decode, so just return\n if (!filename.match(/^\".+\"$/)) {\n return filename;\n }\n\n // Need to hex encode '%' since we will be decoding the converted octal values from hex\n filename = filename.replace(/%/g, '%25');\n // Replace all instances of octal literals with percent-encoded hex (ex. '\\347\\275\\221' -> '%E7%BD%91').\n // This is done because the octal literals represent UTF-8 bytes, and by converting them to percent-encoded\n // hex, we can use decodeURIComponent to get the Unicode chars.\n filename = filename.replace(/(?:\\\\(\\d{1,3}))/g, (match, ...[octalValue, index, source]) => {\n // We need to make sure that the backslash is intended to escape the octal value. To do this, walk\n // backwards from the match to ensure that it's already escaped.\n const trailingBackslashes: RegExpMatchArray | null = (source as string)\n .slice(0, index as number)\n .match(/\\\\*$/);\n return trailingBackslashes && trailingBackslashes.length > 0 && trailingBackslashes[0].length % 2 === 0\n ? `%${parseInt(octalValue, 8).toString(16)}`\n : match;\n });\n\n // Finally, decode the filename and unescape the escaped UTF-8 chars\n return JSON.parse(decodeURIComponent(filename));\n}\n\n/**\n * Parses the output of the \"git ls-tree\" command\n */\nexport function parseGitLsTree(output: string): Map<string, string> {\n const changes: Map<string, string> = new Map<string, string>();\n\n if (output) {\n // A line is expected to look like:\n // 100644 blob 3451bccdc831cb43d7a70ed8e628dcf9c7f888c8 src/typings/tsd.d.ts\n // 160000 commit c5880bf5b0c6c1f2e2c43c95beeb8f0a808e8bac rushstack\n const gitRegex: RegExp = /([0-9]{6})\\s(blob|commit)\\s([a-f0-9]{40})\\s*(.*)/;\n\n // Note: The output of git ls-tree uses \\n newlines regardless of OS.\n const outputLines: string[] = output.trim().split('\\n');\n for (const line of outputLines) {\n if (line) {\n // Take everything after the \"100644 blob\", which is just the hash and filename\n const matches: RegExpMatchArray | null = line.match(gitRegex);\n if (matches && matches[3] && matches[4]) {\n const hash: string = matches[3];\n const filename: string = parseGitFilename(matches[4]);\n\n changes.set(filename, hash);\n } else {\n throw new Error(`Cannot parse git ls-tree input: \"${line}\"`);\n }\n }\n }\n }\n\n return changes;\n}\n\n/**\n * Parses the output of the \"git status\" command\n */\nexport function parseGitStatus(output: string, packagePath: string): Map<string, string> {\n const changes: Map<string, string> = new Map<string, string>();\n\n /*\n * Typically, output will look something like:\n * M temp_modules/rush-package-deps-hash/package.json\n * D package-deps-hash/src/index.ts\n */\n\n // If there was an issue with `git ls-tree`, or there are no current changes, processOutputBlocks[1]\n // will be empty or undefined\n if (!output) {\n return changes;\n }\n\n // Note: The output of git hash-object uses \\n newlines regardless of OS.\n const outputLines: string[] = output.trim().split('\\n');\n for (const line of outputLines) {\n /*\n * changeType is in the format of \"XY\" where \"X\" is the status of the file in the index and \"Y\" is the status of\n * the file in the working tree. Some example statuses:\n * - 'D' == deletion\n * - 'M' == modification\n * - 'A' == addition\n * - '??' == untracked\n * - 'R' == rename\n * - 'RM' == rename with modifications\n * - '[MARC]D' == deleted in work tree\n * Full list of examples: https://git-scm.com/docs/git-status#_short_format\n */\n const match: RegExpMatchArray | null = line.match(/(\"(\\\\\"|[^\"])+\")|(\\S+\\s*)/g);\n\n if (match && match.length > 1) {\n const [changeType, ...filenameMatches] = match;\n\n // We always care about the last filename in the filenames array. In the case of non-rename changes,\n // the filenames array only contains one file, so we can join all segments that were split on spaces.\n // In the case of rename changes, the last item in the array is the path to the file in the working tree,\n // which is the only one that we care about. It is also surrounded by double-quotes if spaces are\n // included, so no need to worry about joining different segments\n let lastFilename: string = changeType.startsWith('R')\n ? filenameMatches[filenameMatches.length - 1]\n : filenameMatches.join('');\n lastFilename = parseGitFilename(lastFilename);\n\n changes.set(lastFilename, changeType.trimRight());\n }\n }\n\n return changes;\n}\n\n/**\n * Takes a list of files and returns the current git hashes for them\n *\n * @public\n */\nexport function getGitHashForFiles(\n filesToHash: string[],\n packagePath: string,\n gitPath?: string\n): Map<string, string> {\n const changes: Map<string, string> = new Map<string, string>();\n\n if (filesToHash.length) {\n // Use --stdin-paths arg to pass the list of files to git in order to avoid issues with\n // command length\n const result: child_process.SpawnSyncReturns<string> = Executable.spawnSync(\n gitPath || 'git',\n ['hash-object', '--stdin-paths'],\n { input: filesToHash.map((x) => path.resolve(packagePath, x)).join('\\n') }\n );\n\n if (result.status !== 0) {\n ensureGitMinimumVersion(gitPath);\n\n throw new Error(`git hash-object exited with status ${result.status}: ${result.stderr}`);\n }\n\n const hashStdout: string = result.stdout.trim();\n\n // The result of \"git hash-object\" will be a list of file hashes delimited by newlines\n const hashes: string[] = hashStdout.split('\\n');\n\n if (hashes.length !== filesToHash.length) {\n throw new Error(\n `Passed ${filesToHash.length} file paths to Git to hash, but received ${hashes.length} hashes.`\n );\n }\n\n for (let i: number = 0; i < hashes.length; i++) {\n const hash: string = hashes[i];\n const filePath: string = filesToHash[i];\n changes.set(filePath, hash);\n }\n }\n\n return changes;\n}\n\n/**\n * Executes \"git ls-tree\" in a folder\n */\nexport function gitLsTree(cwdPath: string, gitPath?: string): string {\n const result: child_process.SpawnSyncReturns<string> = Executable.spawnSync(\n gitPath || 'git',\n ['ls-tree', 'HEAD', '-r'],\n {\n currentWorkingDirectory: cwdPath\n }\n );\n\n if (result.status !== 0) {\n ensureGitMinimumVersion(gitPath);\n\n throw new Error(`git ls-tree exited with status ${result.status}: ${result.stderr}`);\n }\n\n return result.stdout;\n}\n\n/**\n * Executes \"git status\" in a folder\n */\nexport function gitStatus(cwdPath: string, gitPath?: string): string {\n /**\n * -s - Short format. Will be printed as 'XY PATH' or 'XY ORIG_PATH -> PATH'. Paths with non-standard\n * characters will be escaped using double-quotes, and non-standard characters will be backslash\n * escaped (ex. spaces, tabs, double-quotes)\n * -u - Untracked files are included\n *\n * See documentation here: https://git-scm.com/docs/git-status\n */\n const result: child_process.SpawnSyncReturns<string> = Executable.spawnSync(\n gitPath || 'git',\n ['status', '-s', '-u', '.'],\n {\n currentWorkingDirectory: cwdPath\n }\n );\n\n if (result.status !== 0) {\n ensureGitMinimumVersion(gitPath);\n\n throw new Error(`git status exited with status ${result.status}: ${result.stderr}`);\n }\n\n return result.stdout;\n}\n\n/**\n * Builds an object containing hashes for the files under the specified `packagePath` folder.\n * @param packagePath - The folder path to derive the package dependencies from. This is typically the folder\n * containing package.json. If omitted, the default value is the current working directory.\n * @param excludedPaths - An optional array of file path exclusions. If a file should be omitted from the list\n * of dependencies, use this to exclude it.\n * @returns the package-deps.json file content\n *\n * @public\n */\nexport function getPackageDeps(\n packagePath: string = process.cwd(),\n excludedPaths?: string[],\n gitPath?: string\n): Map<string, string> {\n const gitLsOutput: string = gitLsTree(packagePath, gitPath);\n\n // Add all the checked in hashes\n const result: Map<string, string> = parseGitLsTree(gitLsOutput);\n\n // Remove excluded paths\n if (excludedPaths) {\n for (const excludedPath of excludedPaths) {\n result.delete(excludedPath);\n }\n }\n\n // Update the checked in hashes with the current repo status\n const gitStatusOutput: string = gitStatus(packagePath, gitPath);\n const currentlyChangedFiles: Map<string, string> = parseGitStatus(gitStatusOutput, packagePath);\n const filesToHash: string[] = [];\n const excludedPathSet: Set<string> = new Set<string>(excludedPaths);\n for (const [filename, changeType] of currentlyChangedFiles) {\n // See comments inside parseGitStatus() for more information\n if (changeType === 'D' || (changeType.length === 2 && changeType.charAt(1) === 'D')) {\n result.delete(filename);\n } else {\n if (!excludedPathSet.has(filename)) {\n filesToHash.push(filename);\n }\n }\n }\n\n const currentlyChangedFileHashes: Map<string, string> = getGitHashForFiles(\n filesToHash,\n packagePath,\n gitPath\n );\n for (const [filename, hash] of currentlyChangedFileHashes) {\n result.set(filename, hash);\n }\n\n return result;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"getPackageDeps.js","sourceRoot":"","sources":["../src/getPackageDeps.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type * as child_process from 'child_process';\nimport * as path from 'path';\nimport { Executable } from '@rushstack/node-core-library';\n\nimport { ensureGitMinimumVersion } from './getRepoState';\n\n/**\n * Parses a quoted filename sourced from the output of the \"git status\" command.\n *\n * Paths with non-standard characters will be enclosed with double-quotes, and non-standard\n * characters will be backslash escaped (ex. double-quotes, non-ASCII characters). The\n * escaped chars can be included in one of two ways:\n * - backslash-escaped chars (ex. \\\")\n * - octal encoded chars (ex. \\347)\n *\n * See documentation: https://git-scm.com/docs/git-status\n */\nexport function parseGitFilename(filename: string): string {\n // If there are no double-quotes around the string, then there are no escaped characters\n // to decode, so just return\n if (!filename.match(/^\".+\"$/)) {\n return filename;\n }\n\n // Need to hex encode '%' since we will be decoding the converted octal values from hex\n filename = filename.replace(/%/g, '%25');\n // Replace all instances of octal literals with percent-encoded hex (ex. '\\347\\275\\221' -> '%E7%BD%91').\n // This is done because the octal literals represent UTF-8 bytes, and by converting them to percent-encoded\n // hex, we can use decodeURIComponent to get the Unicode chars.\n filename = filename.replace(/(?:\\\\(\\d{1,3}))/g, (match, ...[octalValue, index, source]) => {\n // We need to make sure that the backslash is intended to escape the octal value. To do this, walk\n // backwards from the match to ensure that it's already escaped.\n const trailingBackslashes: RegExpMatchArray | null = (source as string)\n .slice(0, index as number)\n .match(/\\\\*$/);\n return trailingBackslashes && trailingBackslashes.length > 0 && trailingBackslashes[0].length % 2 === 0\n ? `%${parseInt(octalValue, 8).toString(16)}`\n : match;\n });\n\n // Finally, decode the filename and unescape the escaped UTF-8 chars\n return JSON.parse(decodeURIComponent(filename));\n}\n\n/**\n * Parses the output of the \"git ls-tree\" command\n */\nexport function parseGitLsTree(output: string): Map<string, string> {\n const changes: Map<string, string> = new Map<string, string>();\n\n if (output) {\n // A line is expected to look like:\n // 100644 blob 3451bccdc831cb43d7a70ed8e628dcf9c7f888c8 src/typings/tsd.d.ts\n // 160000 commit c5880bf5b0c6c1f2e2c43c95beeb8f0a808e8bac rushstack\n const gitRegex: RegExp = /([0-9]{6})\\s(blob|commit)\\s([a-f0-9]{40})\\s*(.*)/;\n\n // Note: The output of git ls-tree uses \\n newlines regardless of OS.\n const outputLines: string[] = output.trim().split('\\n');\n for (const line of outputLines) {\n if (line) {\n // Take everything after the \"100644 blob\", which is just the hash and filename\n const matches: RegExpMatchArray | null = line.match(gitRegex);\n if (matches && matches[3] && matches[4]) {\n const hash: string = matches[3];\n const filename: string = parseGitFilename(matches[4]);\n\n changes.set(filename, hash);\n } else {\n throw new Error(`Cannot parse git ls-tree input: \"${line}\"`);\n }\n }\n }\n }\n\n return changes;\n}\n\n/**\n * Parses the output of the \"git status\" command\n */\nexport function parseGitStatus(output: string, packagePath: string): Map<string, string> {\n const changes: Map<string, string> = new Map<string, string>();\n\n /*\n * Typically, output will look something like:\n * M temp_modules/rush-package-deps-hash/package.json\n * D package-deps-hash/src/index.ts\n */\n\n // If there was an issue with `git ls-tree`, or there are no current changes, processOutputBlocks[1]\n // will be empty or undefined\n if (!output) {\n return changes;\n }\n\n // Note: The output of git hash-object uses \\n newlines regardless of OS.\n const outputLines: string[] = output.trim().split('\\n');\n for (const line of outputLines) {\n /*\n * changeType is in the format of \"XY\" where \"X\" is the status of the file in the index and \"Y\" is the status of\n * the file in the working tree. Some example statuses:\n * - 'D' == deletion\n * - 'M' == modification\n * - 'A' == addition\n * - '??' == untracked\n * - 'R' == rename\n * - 'RM' == rename with modifications\n * - '[MARC]D' == deleted in work tree\n * Full list of examples: https://git-scm.com/docs/git-status#_short_format\n */\n const match: RegExpMatchArray | null = line.match(/(\"(\\\\\"|[^\"])+\")|(\\S+\\s*)/g);\n\n if (match && match.length > 1) {\n const [changeType, ...filenameMatches] = match;\n\n // We always care about the last filename in the filenames array. In the case of non-rename changes,\n // the filenames array only contains one file, so we can join all segments that were split on spaces.\n // In the case of rename changes, the last item in the array is the path to the file in the working tree,\n // which is the only one that we care about. It is also surrounded by double-quotes if spaces are\n // included, so no need to worry about joining different segments\n let lastFilename: string = changeType.startsWith('R')\n ? filenameMatches[filenameMatches.length - 1]\n : filenameMatches.join('');\n lastFilename = parseGitFilename(lastFilename);\n\n changes.set(lastFilename, changeType.trimRight());\n }\n }\n\n return changes;\n}\n\n/**\n * Takes a list of files and returns the current git hashes for them\n *\n * @public\n */\nexport function getGitHashForFiles(\n filesToHash: string[],\n packagePath: string,\n gitPath?: string\n): Map<string, string> {\n const changes: Map<string, string> = new Map<string, string>();\n\n if (filesToHash.length) {\n // Use --stdin-paths arg to pass the list of files to git in order to avoid issues with\n // command length\n const result: child_process.SpawnSyncReturns<string> = Executable.spawnSync(\n gitPath || 'git',\n ['hash-object', '--stdin-paths'],\n { input: filesToHash.map((x) => path.resolve(packagePath, x)).join('\\n') }\n );\n\n if (result.status !== 0) {\n ensureGitMinimumVersion(gitPath);\n\n throw new Error(`git hash-object exited with status ${result.status}: ${result.stderr}`);\n }\n\n const hashStdout: string = result.stdout.trim();\n\n // The result of \"git hash-object\" will be a list of file hashes delimited by newlines\n const hashes: string[] = hashStdout.split('\\n');\n\n if (hashes.length !== filesToHash.length) {\n throw new Error(\n `Passed ${filesToHash.length} file paths to Git to hash, but received ${hashes.length} hashes.`\n );\n }\n\n for (let i: number = 0; i < hashes.length; i++) {\n const hash: string = hashes[i];\n const filePath: string = filesToHash[i];\n changes.set(filePath, hash);\n }\n }\n\n return changes;\n}\n\n/**\n * Executes \"git ls-tree\" in a folder\n */\nexport function gitLsTree(cwdPath: string, gitPath?: string): string {\n const result: child_process.SpawnSyncReturns<string> = Executable.spawnSync(\n gitPath || 'git',\n ['ls-tree', 'HEAD', '-r'],\n {\n currentWorkingDirectory: cwdPath\n }\n );\n\n if (result.status !== 0) {\n ensureGitMinimumVersion(gitPath);\n\n throw new Error(`git ls-tree exited with status ${result.status}: ${result.stderr}`);\n }\n\n return result.stdout;\n}\n\n/**\n * Executes \"git status\" in a folder\n */\nexport function gitStatus(cwdPath: string, gitPath?: string): string {\n /**\n * -s - Short format. Will be printed as 'XY PATH' or 'XY ORIG_PATH -> PATH'. Paths with non-standard\n * characters will be escaped using double-quotes, and non-standard characters will be backslash\n * escaped (ex. spaces, tabs, double-quotes)\n * -u - Untracked files are included\n *\n * See documentation here: https://git-scm.com/docs/git-status\n */\n const result: child_process.SpawnSyncReturns<string> = Executable.spawnSync(\n gitPath || 'git',\n ['status', '-s', '-u', '.'],\n {\n currentWorkingDirectory: cwdPath\n }\n );\n\n if (result.status !== 0) {\n ensureGitMinimumVersion(gitPath);\n\n throw new Error(`git status exited with status ${result.status}: ${result.stderr}`);\n }\n\n return result.stdout;\n}\n\n/**\n * Builds an object containing hashes for the files under the specified `packagePath` folder.\n * @param packagePath - The folder path to derive the package dependencies from. This is typically the folder\n * containing package.json. If omitted, the default value is the current working directory.\n * @param excludedPaths - An optional array of file path exclusions. If a file should be omitted from the list\n * of dependencies, use this to exclude it.\n * @returns the package-deps.json file content\n *\n * @public\n */\nexport function getPackageDeps(\n packagePath: string = process.cwd(),\n excludedPaths?: string[],\n gitPath?: string\n): Map<string, string> {\n const gitLsOutput: string = gitLsTree(packagePath, gitPath);\n\n // Add all the checked in hashes\n const result: Map<string, string> = parseGitLsTree(gitLsOutput);\n\n // Remove excluded paths\n if (excludedPaths) {\n for (const excludedPath of excludedPaths) {\n result.delete(excludedPath);\n }\n }\n\n // Update the checked in hashes with the current repo status\n const gitStatusOutput: string = gitStatus(packagePath, gitPath);\n const currentlyChangedFiles: Map<string, string> = parseGitStatus(gitStatusOutput, packagePath);\n const filesToHash: string[] = [];\n const excludedPathSet: Set<string> = new Set<string>(excludedPaths);\n for (const [filename, changeType] of currentlyChangedFiles) {\n // See comments inside parseGitStatus() for more information\n if (changeType === 'D' || (changeType.length === 2 && changeType.charAt(1) === 'D')) {\n result.delete(filename);\n } else {\n if (!excludedPathSet.has(filename)) {\n filesToHash.push(filename);\n }\n }\n }\n\n const currentlyChangedFileHashes: Map<string, string> = getGitHashForFiles(\n filesToHash,\n packagePath,\n gitPath\n );\n for (const [filename, hash] of currentlyChangedFileHashes) {\n result.set(filename, hash);\n }\n\n return result;\n}\n"]}
|
package/lib/getRepoState.js
CHANGED
|
@@ -1,28 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
3
3
|
// See LICENSE in the project root for license information.
|
|
4
|
-
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
5
|
-
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
6
|
-
var m = o[Symbol.asyncIterator], i;
|
|
7
|
-
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
8
|
-
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
9
|
-
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
10
|
-
};
|
|
11
|
-
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
|
|
12
|
-
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
|
13
|
-
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
14
|
-
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
|
15
|
-
return i = {}, verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
|
|
16
|
-
function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
|
|
17
|
-
function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
|
|
18
|
-
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
|
|
19
|
-
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
|
|
20
|
-
function fulfill(value) { resume("next", value); }
|
|
21
|
-
function reject(value) { resume("throw", value); }
|
|
22
|
-
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
|
|
23
|
-
};
|
|
24
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.
|
|
5
|
+
exports.parseGitLsTree = parseGitLsTree;
|
|
6
|
+
exports.parseGitHashObject = parseGitHashObject;
|
|
7
|
+
exports.parseGitDiffIndex = parseGitDiffIndex;
|
|
8
|
+
exports.parseGitStatus = parseGitStatus;
|
|
9
|
+
exports.getRepoRoot = getRepoRoot;
|
|
10
|
+
exports.hashFilesAsync = hashFilesAsync;
|
|
11
|
+
exports.getRepoStateAsync = getRepoStateAsync;
|
|
12
|
+
exports.getRepoChanges = getRepoChanges;
|
|
13
|
+
exports.ensureGitMinimumVersion = ensureGitMinimumVersion;
|
|
14
|
+
exports.parseGitVersion = parseGitVersion;
|
|
26
15
|
const events_1 = require("events");
|
|
27
16
|
const stream_1 = require("stream");
|
|
28
17
|
const node_core_library_1 = require("@rushstack/node-core-library");
|
|
@@ -79,7 +68,6 @@ function parseGitLsTree(output) {
|
|
|
79
68
|
submodules
|
|
80
69
|
};
|
|
81
70
|
}
|
|
82
|
-
exports.parseGitLsTree = parseGitLsTree;
|
|
83
71
|
/**
|
|
84
72
|
* Parses the output of `git hash-object`
|
|
85
73
|
* yields [filePath, hash] pairs.
|
|
@@ -110,7 +98,6 @@ function* parseGitHashObject(output, filePaths) {
|
|
|
110
98
|
throw new Error(`Expected ${expected} hashes from "git hash-object" but received ${i}`);
|
|
111
99
|
}
|
|
112
100
|
}
|
|
113
|
-
exports.parseGitHashObject = parseGitHashObject;
|
|
114
101
|
/**
|
|
115
102
|
* Parses the output of `git diff-index --color=never --no-renames --no-commit-id -z <REVISION> --
|
|
116
103
|
* Returns a map of file path to diff
|
|
@@ -147,7 +134,6 @@ function parseGitDiffIndex(output) {
|
|
|
147
134
|
}
|
|
148
135
|
return result;
|
|
149
136
|
}
|
|
150
|
-
exports.parseGitDiffIndex = parseGitDiffIndex;
|
|
151
137
|
/**
|
|
152
138
|
* Parses the output of `git status -z -u` to extract the set of files that have changed since HEAD.
|
|
153
139
|
*
|
|
@@ -177,7 +163,6 @@ function parseGitStatus(output) {
|
|
|
177
163
|
}
|
|
178
164
|
return result;
|
|
179
165
|
}
|
|
180
|
-
exports.parseGitStatus = parseGitStatus;
|
|
181
166
|
const repoRootCache = new Map();
|
|
182
167
|
/**
|
|
183
168
|
* Finds the root of the current Git repository
|
|
@@ -205,7 +190,6 @@ function getRepoRoot(currentWorkingDirectory, gitPath) {
|
|
|
205
190
|
}
|
|
206
191
|
return cachedResult;
|
|
207
192
|
}
|
|
208
|
-
exports.getRepoRoot = getRepoRoot;
|
|
209
193
|
/**
|
|
210
194
|
* Helper function for async process invocation with optional stdin support.
|
|
211
195
|
* @param gitPath - Path to the Git executable
|
|
@@ -268,26 +252,11 @@ async function hashFilesAsync(rootDirectory, filesToHash, gitPath) {
|
|
|
268
252
|
yield `${file}\n`;
|
|
269
253
|
}
|
|
270
254
|
})()
|
|
271
|
-
: (function () {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
_c = filesToHash_1_1.value;
|
|
277
|
-
_d = false;
|
|
278
|
-
const file = _c;
|
|
279
|
-
hashPaths.push(file);
|
|
280
|
-
yield yield __await(`${file}\n`);
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
284
|
-
finally {
|
|
285
|
-
try {
|
|
286
|
-
if (!_d && !_a && (_b = filesToHash_1.return)) yield __await(_b.call(filesToHash_1));
|
|
287
|
-
}
|
|
288
|
-
finally { if (e_1) throw e_1.error; }
|
|
289
|
-
}
|
|
290
|
-
});
|
|
255
|
+
: (async function* () {
|
|
256
|
+
for await (const file of filesToHash) {
|
|
257
|
+
hashPaths.push(file);
|
|
258
|
+
yield `${file}\n`;
|
|
259
|
+
}
|
|
291
260
|
})(), {
|
|
292
261
|
encoding: 'utf-8',
|
|
293
262
|
objectMode: false,
|
|
@@ -296,7 +265,6 @@ async function hashFilesAsync(rootDirectory, filesToHash, gitPath) {
|
|
|
296
265
|
const hashObjectResult = await spawnGitAsync(gitPath, STANDARD_GIT_OPTIONS.concat(['hash-object', '--stdin-paths']), rootDirectory, input);
|
|
297
266
|
return parseGitHashObject(hashObjectResult, hashPaths);
|
|
298
267
|
}
|
|
299
|
-
exports.hashFilesAsync = hashFilesAsync;
|
|
300
268
|
/**
|
|
301
269
|
* Gets the object hashes for all files in the Git repo, combining the current commit with working tree state.
|
|
302
270
|
* Uses async operations and runs all primary Git calls in parallel.
|
|
@@ -334,23 +302,21 @@ async function getRepoStateAsync(rootDirectory, additionalRelativePathsToHash, g
|
|
|
334
302
|
'--',
|
|
335
303
|
...(filterPath !== null && filterPath !== void 0 ? filterPath : [])
|
|
336
304
|
]), rootDirectory).then(parseGitStatus);
|
|
337
|
-
function getFilesToHash() {
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
305
|
+
async function* getFilesToHash() {
|
|
306
|
+
if (additionalRelativePathsToHash) {
|
|
307
|
+
for (const file of additionalRelativePathsToHash) {
|
|
308
|
+
yield file;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
const [{ files }, locallyModified] = await Promise.all([statePromise, locallyModifiedPromise]);
|
|
312
|
+
for (const [filePath, exists] of locallyModified) {
|
|
313
|
+
if (exists) {
|
|
314
|
+
yield filePath;
|
|
343
315
|
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
if (exists) {
|
|
347
|
-
yield yield __await(filePath);
|
|
348
|
-
}
|
|
349
|
-
else {
|
|
350
|
-
files.delete(filePath);
|
|
351
|
-
}
|
|
316
|
+
else {
|
|
317
|
+
files.delete(filePath);
|
|
352
318
|
}
|
|
353
|
-
}
|
|
319
|
+
}
|
|
354
320
|
}
|
|
355
321
|
const hashObjectPromise = hashFilesAsync(rootDirectory, getFilesToHash(), gitPath);
|
|
356
322
|
const [{ files, submodules }] = await Promise.all([statePromise, locallyModifiedPromise]);
|
|
@@ -372,7 +338,6 @@ async function getRepoStateAsync(rootDirectory, additionalRelativePathsToHash, g
|
|
|
372
338
|
}
|
|
373
339
|
return files;
|
|
374
340
|
}
|
|
375
|
-
exports.getRepoStateAsync = getRepoStateAsync;
|
|
376
341
|
/**
|
|
377
342
|
* Find all changed files tracked by Git, their current hashes, and the nature of the change. Only useful if all changes are staged or committed.
|
|
378
343
|
* @param currentWorkingDirectory - The working directory. Only used to find the repository root.
|
|
@@ -403,7 +368,6 @@ function getRepoChanges(currentWorkingDirectory, revision = 'HEAD', gitPath) {
|
|
|
403
368
|
const changes = parseGitDiffIndex(result.stdout);
|
|
404
369
|
return changes;
|
|
405
370
|
}
|
|
406
|
-
exports.getRepoChanges = getRepoChanges;
|
|
407
371
|
/**
|
|
408
372
|
* Checks the git version and throws an error if it is less than the minimum required version.
|
|
409
373
|
*
|
|
@@ -421,7 +385,6 @@ function ensureGitMinimumVersion(gitPath) {
|
|
|
421
385
|
`Your version is ${gitVersion.major}.${gitVersion.minor}.${gitVersion.patch}.`);
|
|
422
386
|
}
|
|
423
387
|
}
|
|
424
|
-
exports.ensureGitMinimumVersion = ensureGitMinimumVersion;
|
|
425
388
|
function getGitVersion(gitPath) {
|
|
426
389
|
const result = node_core_library_1.Executable.spawnSync(gitPath || 'git', STANDARD_GIT_OPTIONS.concat(['version']));
|
|
427
390
|
if (result.status !== 0) {
|
|
@@ -452,5 +415,4 @@ function parseGitVersion(gitVersionOutput) {
|
|
|
452
415
|
patch
|
|
453
416
|
};
|
|
454
417
|
}
|
|
455
|
-
exports.parseGitVersion = parseGitVersion;
|
|
456
418
|
//# sourceMappingURL=getRepoState.js.map
|
package/lib/getRepoState.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getRepoState.js","sourceRoot":"","sources":["../src/getRepoState.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type * as child_process from 'child_process';\nimport { once } from 'events';\nimport { Readable, pipeline } from 'stream';\n\nimport { Executable, FileSystem, type IExecutableSpawnOptions } from '@rushstack/node-core-library';\n\nexport interface IGitVersion {\n major: number;\n minor: number;\n patch: number;\n}\n\nconst MINIMUM_GIT_VERSION: IGitVersion = {\n major: 2,\n minor: 20,\n patch: 0\n};\n\nconst STANDARD_GIT_OPTIONS: readonly string[] = [\n // Don't request any optional file locks\n '--no-optional-locks',\n // Ensure that commands don't run automatic maintenance, since performance of the command itself is paramount\n '-c',\n 'maintenance.auto=false'\n];\n\ninterface IGitTreeState {\n files: Map<string, string>; // type \"blob\"\n submodules: Map<string, string>; // type \"commit\"\n}\n\n/**\n * Parses the output of the \"git ls-tree -r -z\" command\n * @internal\n */\nexport function parseGitLsTree(output: string): IGitTreeState {\n const files: Map<string, string> = new Map();\n const submodules: Map<string, string> = new Map();\n\n // Parse the output\n // With the -z modifier, paths are delimited by nulls\n // A line looks like:\n // <mode> <type> <newhash>\\t<path>\\0\n // 100644 blob a300ccb0b36bd2c85ef18e3c619a2c747f95959e\\ttools/prettier-git/prettier-git.js\\0\n\n let last: number = 0;\n let index: number = output.indexOf('\\0', last);\n while (index >= 0) {\n const item: string = output.slice(last, index);\n\n const tabIndex: number = item.indexOf('\\t');\n const filePath: string = item.slice(tabIndex + 1);\n\n // The newHash will be all zeros if the file is deleted, or a hash if it exists\n const hash: string = item.slice(tabIndex - 40, tabIndex);\n\n const spaceIndex: number = item.lastIndexOf(' ', tabIndex - 42);\n\n const type: string = item.slice(spaceIndex + 1, tabIndex - 41);\n\n switch (type) {\n case 'commit': {\n submodules.set(filePath, hash);\n break;\n }\n case 'blob':\n default: {\n files.set(filePath, hash);\n break;\n }\n }\n\n last = index + 1;\n index = output.indexOf('\\0', last);\n }\n\n return {\n files,\n submodules\n };\n}\n\n/**\n * Parses the output of `git hash-object`\n * yields [filePath, hash] pairs.\n * @internal\n */\nexport function* parseGitHashObject(\n output: string,\n filePaths: ReadonlyArray<string>\n): IterableIterator<[string, string]> {\n const expected: number = filePaths.length;\n if (expected === 0) {\n return;\n }\n\n output = output.trim();\n\n let last: number = 0;\n let i: number = 0;\n let index: number = output.indexOf('\\n', last);\n for (; i < expected && index > 0; i++) {\n const hash: string = output.slice(last, index);\n yield [filePaths[i], hash];\n last = index + 1;\n index = output.indexOf('\\n', last);\n }\n\n // Handle last line. Will be non-empty to due trim() call.\n if (index < 0) {\n const hash: string = output.slice(last);\n yield [filePaths[i], hash];\n i++;\n }\n\n if (i !== expected) {\n throw new Error(`Expected ${expected} hashes from \"git hash-object\" but received ${i}`);\n }\n}\n\n/**\n * Information about the changes to a file.\n * @beta\n */\nexport interface IFileDiffStatus {\n mode: string;\n oldhash: string;\n newhash: string;\n status: 'A' | 'D' | 'M';\n}\n\n/**\n * Parses the output of `git diff-index --color=never --no-renames --no-commit-id -z <REVISION> --\n * Returns a map of file path to diff\n * @internal\n */\nexport function parseGitDiffIndex(output: string): Map<string, IFileDiffStatus> {\n const result: Map<string, IFileDiffStatus> = new Map();\n\n // Parse the output\n // With the -z modifier, paths are delimited by nulls\n // A line looks like:\n // :<oldmode> <newmode> <oldhash> <newhash> <status>\\0<path>\\0\n // :100644 100644 a300ccb0b36bd2c85ef18e3c619a2c747f95959e 0000000000000000000000000000000000000000 M\\0tools/prettier-git/prettier-git.js\\0\n\n let last: number = 0;\n let index: number = output.indexOf('\\0', last);\n while (index >= 0) {\n const header: string = output.slice(last, index);\n const status: IFileDiffStatus['status'] = header.slice(-1) as IFileDiffStatus['status'];\n\n last = index + 1;\n index = output.indexOf('\\0', last);\n const filePath: string = output.slice(last, index);\n\n // We passed --no-renames above, so a rename will be a delete of the old location and an add at the new.\n // The newHash will be all zeros if the file is deleted, or a hash if it exists\n const mode: string = header.slice(8, 14);\n const oldhash: string = header.slice(-83, -43);\n const newhash: string = header.slice(-42, -2);\n result.set(filePath, {\n mode,\n oldhash,\n newhash,\n status\n });\n\n last = index + 1;\n index = output.indexOf('\\0', last);\n }\n\n return result;\n}\n\n/**\n * Parses the output of `git status -z -u` to extract the set of files that have changed since HEAD.\n *\n * @param output - The raw output from Git\n * @returns a map of file path to if it exists\n * @internal\n */\nexport function parseGitStatus(output: string): Map<string, boolean> {\n const result: Map<string, boolean> = new Map();\n\n // Parse the output\n // With the -z modifier, paths are delimited by nulls\n // A line looks like:\n // XY <path>\\0\n // M tools/prettier-git/prettier-git.js\\0\n\n let startOfLine: number = 0;\n let eolIndex: number = output.indexOf('\\0', startOfLine);\n while (eolIndex >= 0) {\n // We passed --no-renames above, so a rename will be a delete of the old location and an add at the new.\n // charAt(startOfLine) is the index status, charAt(startOfLine + 1) is the working tree status\n const workingTreeStatus: string = output.charAt(startOfLine + 1);\n // Deleted in working tree, or not modified in working tree and deleted in index\n const deleted: boolean =\n workingTreeStatus === 'D' || (workingTreeStatus === ' ' && output.charAt(startOfLine) === 'D');\n\n const filePath: string = output.slice(startOfLine + 3, eolIndex);\n result.set(filePath, !deleted);\n\n startOfLine = eolIndex + 1;\n eolIndex = output.indexOf('\\0', startOfLine);\n }\n\n return result;\n}\n\nconst repoRootCache: Map<string, string> = new Map();\n\n/**\n * Finds the root of the current Git repository\n *\n * @param currentWorkingDirectory - The working directory for which to locate the repository\n * @param gitPath - The path to the Git executable\n *\n * @returns The full path to the root directory of the Git repository\n * @beta\n */\nexport function getRepoRoot(currentWorkingDirectory: string, gitPath?: string): string {\n let cachedResult: string | undefined = repoRootCache.get(currentWorkingDirectory);\n if (!cachedResult) {\n const result: child_process.SpawnSyncReturns<string> = Executable.spawnSync(\n gitPath || 'git',\n ['--no-optional-locks', 'rev-parse', '--show-toplevel'],\n {\n currentWorkingDirectory\n }\n );\n\n if (result.status !== 0) {\n ensureGitMinimumVersion(gitPath);\n\n throw new Error(`git rev-parse exited with status ${result.status}: ${result.stderr}`);\n }\n\n cachedResult = result.stdout.trim();\n\n repoRootCache.set(currentWorkingDirectory, cachedResult);\n // To ensure that calling getRepoRoot on the result is a no-op.\n repoRootCache.set(cachedResult, cachedResult);\n }\n\n return cachedResult;\n}\n\n/**\n * Helper function for async process invocation with optional stdin support.\n * @param gitPath - Path to the Git executable\n * @param args - The process arguments\n * @param currentWorkingDirectory - The working directory. Should be the repository root.\n * @param stdin - An optional Readable stream to use as stdin to the process.\n */\nasync function spawnGitAsync(\n gitPath: string | undefined,\n args: string[],\n currentWorkingDirectory: string,\n stdin?: Readable\n): Promise<string> {\n const spawnOptions: IExecutableSpawnOptions = {\n currentWorkingDirectory,\n stdio: ['pipe', 'pipe', 'pipe']\n };\n\n let stdout: string = '';\n let stderr: string = '';\n\n const proc: child_process.ChildProcess = Executable.spawn(gitPath || 'git', args, spawnOptions);\n proc.stdout!.setEncoding('utf-8');\n proc.stderr!.setEncoding('utf-8');\n\n proc.stdout!.on('data', (chunk: string) => {\n stdout += chunk.toString();\n });\n proc.stderr!.on('data', (chunk: string) => {\n stderr += chunk.toString();\n });\n\n if (stdin) {\n /**\n * For `git hash-object` data is piped in asynchronously. In the event that one of the\n * passed filenames cannot be hashed, subsequent writes to `proc.stdin` will error.\n * Silence this error since it will be handled by the non-zero exit code of the process.\n */\n pipeline(stdin, proc.stdin!, (err) => {});\n }\n\n const [status] = await once(proc, 'close');\n if (status !== 0) {\n throw new Error(`git ${args[0]} exited with code ${status}:\\n${stderr}`);\n }\n\n return stdout;\n}\n\nfunction isIterable<T>(value: Iterable<T> | AsyncIterable<T>): value is Iterable<T> {\n return Symbol.iterator in value;\n}\n\n/**\n * Uses `git hash-object` to hash the provided files. Unlike `getGitHashForFiles`, this API is asynchronous, and also allows for\n * the input file paths to be specified as an async iterable.\n *\n * @param rootDirectory - The root directory to which paths are specified relative. Must be the root of the Git repository.\n * @param filesToHash - The file paths to hash using `git hash-object`\n * @param gitPath - The path to the Git executable\n * @returns An iterable of [filePath, hash] pairs\n *\n * @remarks\n * The input file paths must be specified relative to the Git repository root, or else be absolute paths.\n * @beta\n */\nexport async function hashFilesAsync(\n rootDirectory: string,\n filesToHash: Iterable<string> | AsyncIterable<string>,\n gitPath?: string\n): Promise<Iterable<[string, string]>> {\n const hashPaths: string[] = [];\n\n const input: Readable = Readable.from(\n isIterable(filesToHash)\n ? (function* (): IterableIterator<string> {\n for (const file of filesToHash) {\n hashPaths.push(file);\n yield `${file}\\n`;\n }\n })()\n : (async function* (): AsyncIterableIterator<string> {\n for await (const file of filesToHash) {\n hashPaths.push(file);\n yield `${file}\\n`;\n }\n })(),\n {\n encoding: 'utf-8',\n objectMode: false,\n autoDestroy: true\n }\n );\n\n const hashObjectResult: string = await spawnGitAsync(\n gitPath,\n STANDARD_GIT_OPTIONS.concat(['hash-object', '--stdin-paths']),\n rootDirectory,\n input\n );\n\n return parseGitHashObject(hashObjectResult, hashPaths);\n}\n\n/**\n * Gets the object hashes for all files in the Git repo, combining the current commit with working tree state.\n * Uses async operations and runs all primary Git calls in parallel.\n * @param rootDirectory - The root directory of the Git repository\n * @param additionalRelativePathsToHash - Root-relative file paths to have Git hash and include in the results\n * @param gitPath - The path to the Git executable\n * @beta\n */\nexport async function getRepoStateAsync(\n rootDirectory: string,\n additionalRelativePathsToHash?: string[],\n gitPath?: string,\n filterPath?: string[]\n): Promise<Map<string, string>> {\n const statePromise: Promise<IGitTreeState> = spawnGitAsync(\n gitPath,\n STANDARD_GIT_OPTIONS.concat([\n 'ls-tree',\n // Recursively expand trees\n '-r',\n // Use NUL as the separator\n '-z',\n // Specify the full path to files relative to the root\n '--full-name',\n // As of last commit\n 'HEAD',\n '--',\n ...(filterPath ?? [])\n ]),\n rootDirectory\n ).then(parseGitLsTree);\n const locallyModifiedPromise: Promise<Map<string, boolean>> = spawnGitAsync(\n gitPath,\n STANDARD_GIT_OPTIONS.concat([\n 'status',\n // Use NUL as the separator\n '-z',\n // Include untracked files\n '-u',\n // Disable rename detection so that renames show up as add + delete\n '--no-renames',\n // Don't process submodules with this command; they'll be handled individually\n '--ignore-submodules',\n // Don't compare against the remote\n '--no-ahead-behind',\n '--',\n ...(filterPath ?? [])\n ]),\n rootDirectory\n ).then(parseGitStatus);\n\n async function* getFilesToHash(): AsyncIterableIterator<string> {\n if (additionalRelativePathsToHash) {\n for (const file of additionalRelativePathsToHash) {\n yield file;\n }\n }\n\n const [{ files }, locallyModified] = await Promise.all([statePromise, locallyModifiedPromise]);\n\n for (const [filePath, exists] of locallyModified) {\n if (exists) {\n yield filePath;\n } else {\n files.delete(filePath);\n }\n }\n }\n\n const hashObjectPromise: Promise<Iterable<[string, string]>> = hashFilesAsync(\n rootDirectory,\n getFilesToHash(),\n gitPath\n );\n\n const [{ files, submodules }] = await Promise.all([statePromise, locallyModifiedPromise]);\n\n // The result of \"git hash-object\" will be a list of file hashes delimited by newlines\n for (const [filePath, hash] of await hashObjectPromise) {\n files.set(filePath, hash);\n }\n\n // Existence check for the .gitmodules file\n const hasSubmodules: boolean = submodules.size > 0 && FileSystem.exists(`${rootDirectory}/.gitmodules`);\n\n if (hasSubmodules) {\n // Submodules are not the normal critical path. Accept serial performance rather than investing in complexity.\n // Can revisit if submodules become more commonly used.\n for (const submodulePath of submodules.keys()) {\n const submoduleState: Map<string, string> = await getRepoStateAsync(\n `${rootDirectory}/${submodulePath}`,\n [],\n gitPath\n );\n for (const [filePath, hash] of submoduleState) {\n files.set(`${submodulePath}/${filePath}`, hash);\n }\n }\n }\n\n return files;\n}\n\n/**\n * Find all changed files tracked by Git, their current hashes, and the nature of the change. Only useful if all changes are staged or committed.\n * @param currentWorkingDirectory - The working directory. Only used to find the repository root.\n * @param revision - The Git revision specifier to detect changes relative to. Defaults to HEAD (i.e. will compare staged vs. committed)\n * If comparing against a different branch, call `git merge-base` first to find the target commit.\n * @param gitPath - The path to the Git executable\n * @returns A map from the Git file path to the corresponding file change metadata\n * @beta\n */\nexport function getRepoChanges(\n currentWorkingDirectory: string,\n revision: string = 'HEAD',\n gitPath?: string\n): Map<string, IFileDiffStatus> {\n const rootDirectory: string = getRepoRoot(currentWorkingDirectory, gitPath);\n\n const result: child_process.SpawnSyncReturns<string> = Executable.spawnSync(\n gitPath || 'git',\n STANDARD_GIT_OPTIONS.concat([\n 'diff-index',\n '--color=never',\n '--no-renames',\n '--no-commit-id',\n '--cached',\n '-z',\n revision,\n '--'\n ]),\n {\n currentWorkingDirectory: rootDirectory\n }\n );\n\n if (result.status !== 0) {\n ensureGitMinimumVersion(gitPath);\n\n throw new Error(`git diff-index exited with status ${result.status}: ${result.stderr}`);\n }\n\n const changes: Map<string, IFileDiffStatus> = parseGitDiffIndex(result.stdout);\n\n return changes;\n}\n\n/**\n * Checks the git version and throws an error if it is less than the minimum required version.\n *\n * @public\n */\nexport function ensureGitMinimumVersion(gitPath?: string): void {\n const gitVersion: IGitVersion = getGitVersion(gitPath);\n if (\n gitVersion.major < MINIMUM_GIT_VERSION.major ||\n (gitVersion.major === MINIMUM_GIT_VERSION.major && gitVersion.minor < MINIMUM_GIT_VERSION.minor) ||\n (gitVersion.major === MINIMUM_GIT_VERSION.major &&\n gitVersion.minor === MINIMUM_GIT_VERSION.minor &&\n gitVersion.patch < MINIMUM_GIT_VERSION.patch)\n ) {\n throw new Error(\n `The minimum Git version required is ` +\n `${MINIMUM_GIT_VERSION.major}.${MINIMUM_GIT_VERSION.minor}.${MINIMUM_GIT_VERSION.patch}. ` +\n `Your version is ${gitVersion.major}.${gitVersion.minor}.${gitVersion.patch}.`\n );\n }\n}\n\nfunction getGitVersion(gitPath?: string): IGitVersion {\n const result: child_process.SpawnSyncReturns<string> = Executable.spawnSync(\n gitPath || 'git',\n STANDARD_GIT_OPTIONS.concat(['version'])\n );\n\n if (result.status !== 0) {\n throw new Error(\n `While validating the Git installation, the \"git version\" command failed with ` +\n `status ${result.status}: ${result.stderr}`\n );\n }\n\n return parseGitVersion(result.stdout);\n}\n\nexport function parseGitVersion(gitVersionOutput: string): IGitVersion {\n // This regexp matches output of \"git version\" that looks like `git version <number>.<number>.<number>(+whatever)`\n // Examples:\n // - git version 1.2.3\n // - git version 1.2.3.4.5\n // - git version 1.2.3windows.1\n // - git version 1.2.3.windows.1\n const versionRegex: RegExp = /^git version (\\d+)\\.(\\d+)\\.(\\d+)/;\n const match: RegExpMatchArray | null = versionRegex.exec(gitVersionOutput);\n if (!match) {\n throw new Error(\n `While validating the Git installation, the \"git version\" command produced ` +\n `unexpected output: \"${gitVersionOutput}\"`\n );\n }\n\n const major: number = parseInt(match[1], 10);\n const minor: number = parseInt(match[2], 10);\n const patch: number = parseInt(match[3], 10);\n\n return {\n major,\n minor,\n patch\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"getRepoState.js","sourceRoot":"","sources":["../src/getRepoState.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type * as child_process from 'child_process';\nimport { once } from 'events';\nimport { Readable, pipeline } from 'stream';\n\nimport { Executable, FileSystem, type IExecutableSpawnOptions } from '@rushstack/node-core-library';\n\nexport interface IGitVersion {\n major: number;\n minor: number;\n patch: number;\n}\n\nconst MINIMUM_GIT_VERSION: IGitVersion = {\n major: 2,\n minor: 20,\n patch: 0\n};\n\nconst STANDARD_GIT_OPTIONS: readonly string[] = [\n // Don't request any optional file locks\n '--no-optional-locks',\n // Ensure that commands don't run automatic maintenance, since performance of the command itself is paramount\n '-c',\n 'maintenance.auto=false'\n];\n\ninterface IGitTreeState {\n files: Map<string, string>; // type \"blob\"\n submodules: Map<string, string>; // type \"commit\"\n}\n\n/**\n * Parses the output of the \"git ls-tree -r -z\" command\n * @internal\n */\nexport function parseGitLsTree(output: string): IGitTreeState {\n const files: Map<string, string> = new Map();\n const submodules: Map<string, string> = new Map();\n\n // Parse the output\n // With the -z modifier, paths are delimited by nulls\n // A line looks like:\n // <mode> <type> <newhash>\\t<path>\\0\n // 100644 blob a300ccb0b36bd2c85ef18e3c619a2c747f95959e\\ttools/prettier-git/prettier-git.js\\0\n\n let last: number = 0;\n let index: number = output.indexOf('\\0', last);\n while (index >= 0) {\n const item: string = output.slice(last, index);\n\n const tabIndex: number = item.indexOf('\\t');\n const filePath: string = item.slice(tabIndex + 1);\n\n // The newHash will be all zeros if the file is deleted, or a hash if it exists\n const hash: string = item.slice(tabIndex - 40, tabIndex);\n\n const spaceIndex: number = item.lastIndexOf(' ', tabIndex - 42);\n\n const type: string = item.slice(spaceIndex + 1, tabIndex - 41);\n\n switch (type) {\n case 'commit': {\n submodules.set(filePath, hash);\n break;\n }\n case 'blob':\n default: {\n files.set(filePath, hash);\n break;\n }\n }\n\n last = index + 1;\n index = output.indexOf('\\0', last);\n }\n\n return {\n files,\n submodules\n };\n}\n\n/**\n * Parses the output of `git hash-object`\n * yields [filePath, hash] pairs.\n * @internal\n */\nexport function* parseGitHashObject(\n output: string,\n filePaths: ReadonlyArray<string>\n): IterableIterator<[string, string]> {\n const expected: number = filePaths.length;\n if (expected === 0) {\n return;\n }\n\n output = output.trim();\n\n let last: number = 0;\n let i: number = 0;\n let index: number = output.indexOf('\\n', last);\n for (; i < expected && index > 0; i++) {\n const hash: string = output.slice(last, index);\n yield [filePaths[i], hash];\n last = index + 1;\n index = output.indexOf('\\n', last);\n }\n\n // Handle last line. Will be non-empty to due trim() call.\n if (index < 0) {\n const hash: string = output.slice(last);\n yield [filePaths[i], hash];\n i++;\n }\n\n if (i !== expected) {\n throw new Error(`Expected ${expected} hashes from \"git hash-object\" but received ${i}`);\n }\n}\n\n/**\n * Information about the changes to a file.\n * @beta\n */\nexport interface IFileDiffStatus {\n mode: string;\n oldhash: string;\n newhash: string;\n status: 'A' | 'D' | 'M';\n}\n\n/**\n * Parses the output of `git diff-index --color=never --no-renames --no-commit-id -z <REVISION> --\n * Returns a map of file path to diff\n * @internal\n */\nexport function parseGitDiffIndex(output: string): Map<string, IFileDiffStatus> {\n const result: Map<string, IFileDiffStatus> = new Map();\n\n // Parse the output\n // With the -z modifier, paths are delimited by nulls\n // A line looks like:\n // :<oldmode> <newmode> <oldhash> <newhash> <status>\\0<path>\\0\n // :100644 100644 a300ccb0b36bd2c85ef18e3c619a2c747f95959e 0000000000000000000000000000000000000000 M\\0tools/prettier-git/prettier-git.js\\0\n\n let last: number = 0;\n let index: number = output.indexOf('\\0', last);\n while (index >= 0) {\n const header: string = output.slice(last, index);\n const status: IFileDiffStatus['status'] = header.slice(-1) as IFileDiffStatus['status'];\n\n last = index + 1;\n index = output.indexOf('\\0', last);\n const filePath: string = output.slice(last, index);\n\n // We passed --no-renames above, so a rename will be a delete of the old location and an add at the new.\n // The newHash will be all zeros if the file is deleted, or a hash if it exists\n const mode: string = header.slice(8, 14);\n const oldhash: string = header.slice(-83, -43);\n const newhash: string = header.slice(-42, -2);\n result.set(filePath, {\n mode,\n oldhash,\n newhash,\n status\n });\n\n last = index + 1;\n index = output.indexOf('\\0', last);\n }\n\n return result;\n}\n\n/**\n * Parses the output of `git status -z -u` to extract the set of files that have changed since HEAD.\n *\n * @param output - The raw output from Git\n * @returns a map of file path to if it exists\n * @internal\n */\nexport function parseGitStatus(output: string): Map<string, boolean> {\n const result: Map<string, boolean> = new Map();\n\n // Parse the output\n // With the -z modifier, paths are delimited by nulls\n // A line looks like:\n // XY <path>\\0\n // M tools/prettier-git/prettier-git.js\\0\n\n let startOfLine: number = 0;\n let eolIndex: number = output.indexOf('\\0', startOfLine);\n while (eolIndex >= 0) {\n // We passed --no-renames above, so a rename will be a delete of the old location and an add at the new.\n // charAt(startOfLine) is the index status, charAt(startOfLine + 1) is the working tree status\n const workingTreeStatus: string = output.charAt(startOfLine + 1);\n // Deleted in working tree, or not modified in working tree and deleted in index\n const deleted: boolean =\n workingTreeStatus === 'D' || (workingTreeStatus === ' ' && output.charAt(startOfLine) === 'D');\n\n const filePath: string = output.slice(startOfLine + 3, eolIndex);\n result.set(filePath, !deleted);\n\n startOfLine = eolIndex + 1;\n eolIndex = output.indexOf('\\0', startOfLine);\n }\n\n return result;\n}\n\nconst repoRootCache: Map<string, string> = new Map();\n\n/**\n * Finds the root of the current Git repository\n *\n * @param currentWorkingDirectory - The working directory for which to locate the repository\n * @param gitPath - The path to the Git executable\n *\n * @returns The full path to the root directory of the Git repository\n * @beta\n */\nexport function getRepoRoot(currentWorkingDirectory: string, gitPath?: string): string {\n let cachedResult: string | undefined = repoRootCache.get(currentWorkingDirectory);\n if (!cachedResult) {\n const result: child_process.SpawnSyncReturns<string> = Executable.spawnSync(\n gitPath || 'git',\n ['--no-optional-locks', 'rev-parse', '--show-toplevel'],\n {\n currentWorkingDirectory\n }\n );\n\n if (result.status !== 0) {\n ensureGitMinimumVersion(gitPath);\n\n throw new Error(`git rev-parse exited with status ${result.status}: ${result.stderr}`);\n }\n\n cachedResult = result.stdout.trim();\n\n repoRootCache.set(currentWorkingDirectory, cachedResult);\n // To ensure that calling getRepoRoot on the result is a no-op.\n repoRootCache.set(cachedResult, cachedResult);\n }\n\n return cachedResult;\n}\n\n/**\n * Helper function for async process invocation with optional stdin support.\n * @param gitPath - Path to the Git executable\n * @param args - The process arguments\n * @param currentWorkingDirectory - The working directory. Should be the repository root.\n * @param stdin - An optional Readable stream to use as stdin to the process.\n */\nasync function spawnGitAsync(\n gitPath: string | undefined,\n args: string[],\n currentWorkingDirectory: string,\n stdin?: Readable\n): Promise<string> {\n const spawnOptions: IExecutableSpawnOptions = {\n currentWorkingDirectory,\n stdio: ['pipe', 'pipe', 'pipe']\n };\n\n let stdout: string = '';\n let stderr: string = '';\n\n const proc: child_process.ChildProcess = Executable.spawn(gitPath || 'git', args, spawnOptions);\n proc.stdout!.setEncoding('utf-8');\n proc.stderr!.setEncoding('utf-8');\n\n proc.stdout!.on('data', (chunk: string) => {\n stdout += chunk.toString();\n });\n proc.stderr!.on('data', (chunk: string) => {\n stderr += chunk.toString();\n });\n\n if (stdin) {\n /**\n * For `git hash-object` data is piped in asynchronously. In the event that one of the\n * passed filenames cannot be hashed, subsequent writes to `proc.stdin` will error.\n * Silence this error since it will be handled by the non-zero exit code of the process.\n */\n pipeline(stdin, proc.stdin!, (err) => {});\n }\n\n const [status] = await once(proc, 'close');\n if (status !== 0) {\n throw new Error(`git ${args[0]} exited with code ${status}:\\n${stderr}`);\n }\n\n return stdout;\n}\n\nfunction isIterable<T>(value: Iterable<T> | AsyncIterable<T>): value is Iterable<T> {\n return Symbol.iterator in value;\n}\n\n/**\n * Uses `git hash-object` to hash the provided files. Unlike `getGitHashForFiles`, this API is asynchronous, and also allows for\n * the input file paths to be specified as an async iterable.\n *\n * @param rootDirectory - The root directory to which paths are specified relative. Must be the root of the Git repository.\n * @param filesToHash - The file paths to hash using `git hash-object`\n * @param gitPath - The path to the Git executable\n * @returns An iterable of [filePath, hash] pairs\n *\n * @remarks\n * The input file paths must be specified relative to the Git repository root, or else be absolute paths.\n * @beta\n */\nexport async function hashFilesAsync(\n rootDirectory: string,\n filesToHash: Iterable<string> | AsyncIterable<string>,\n gitPath?: string\n): Promise<Iterable<[string, string]>> {\n const hashPaths: string[] = [];\n\n const input: Readable = Readable.from(\n isIterable(filesToHash)\n ? (function* (): IterableIterator<string> {\n for (const file of filesToHash) {\n hashPaths.push(file);\n yield `${file}\\n`;\n }\n })()\n : (async function* (): AsyncIterableIterator<string> {\n for await (const file of filesToHash) {\n hashPaths.push(file);\n yield `${file}\\n`;\n }\n })(),\n {\n encoding: 'utf-8',\n objectMode: false,\n autoDestroy: true\n }\n );\n\n const hashObjectResult: string = await spawnGitAsync(\n gitPath,\n STANDARD_GIT_OPTIONS.concat(['hash-object', '--stdin-paths']),\n rootDirectory,\n input\n );\n\n return parseGitHashObject(hashObjectResult, hashPaths);\n}\n\n/**\n * Gets the object hashes for all files in the Git repo, combining the current commit with working tree state.\n * Uses async operations and runs all primary Git calls in parallel.\n * @param rootDirectory - The root directory of the Git repository\n * @param additionalRelativePathsToHash - Root-relative file paths to have Git hash and include in the results\n * @param gitPath - The path to the Git executable\n * @beta\n */\nexport async function getRepoStateAsync(\n rootDirectory: string,\n additionalRelativePathsToHash?: string[],\n gitPath?: string,\n filterPath?: string[]\n): Promise<Map<string, string>> {\n const statePromise: Promise<IGitTreeState> = spawnGitAsync(\n gitPath,\n STANDARD_GIT_OPTIONS.concat([\n 'ls-tree',\n // Recursively expand trees\n '-r',\n // Use NUL as the separator\n '-z',\n // Specify the full path to files relative to the root\n '--full-name',\n // As of last commit\n 'HEAD',\n '--',\n ...(filterPath ?? [])\n ]),\n rootDirectory\n ).then(parseGitLsTree);\n const locallyModifiedPromise: Promise<Map<string, boolean>> = spawnGitAsync(\n gitPath,\n STANDARD_GIT_OPTIONS.concat([\n 'status',\n // Use NUL as the separator\n '-z',\n // Include untracked files\n '-u',\n // Disable rename detection so that renames show up as add + delete\n '--no-renames',\n // Don't process submodules with this command; they'll be handled individually\n '--ignore-submodules',\n // Don't compare against the remote\n '--no-ahead-behind',\n '--',\n ...(filterPath ?? [])\n ]),\n rootDirectory\n ).then(parseGitStatus);\n\n async function* getFilesToHash(): AsyncIterableIterator<string> {\n if (additionalRelativePathsToHash) {\n for (const file of additionalRelativePathsToHash) {\n yield file;\n }\n }\n\n const [{ files }, locallyModified] = await Promise.all([statePromise, locallyModifiedPromise]);\n\n for (const [filePath, exists] of locallyModified) {\n if (exists) {\n yield filePath;\n } else {\n files.delete(filePath);\n }\n }\n }\n\n const hashObjectPromise: Promise<Iterable<[string, string]>> = hashFilesAsync(\n rootDirectory,\n getFilesToHash(),\n gitPath\n );\n\n const [{ files, submodules }] = await Promise.all([statePromise, locallyModifiedPromise]);\n\n // The result of \"git hash-object\" will be a list of file hashes delimited by newlines\n for (const [filePath, hash] of await hashObjectPromise) {\n files.set(filePath, hash);\n }\n\n // Existence check for the .gitmodules file\n const hasSubmodules: boolean = submodules.size > 0 && FileSystem.exists(`${rootDirectory}/.gitmodules`);\n\n if (hasSubmodules) {\n // Submodules are not the normal critical path. Accept serial performance rather than investing in complexity.\n // Can revisit if submodules become more commonly used.\n for (const submodulePath of submodules.keys()) {\n const submoduleState: Map<string, string> = await getRepoStateAsync(\n `${rootDirectory}/${submodulePath}`,\n [],\n gitPath\n );\n for (const [filePath, hash] of submoduleState) {\n files.set(`${submodulePath}/${filePath}`, hash);\n }\n }\n }\n\n return files;\n}\n\n/**\n * Find all changed files tracked by Git, their current hashes, and the nature of the change. Only useful if all changes are staged or committed.\n * @param currentWorkingDirectory - The working directory. Only used to find the repository root.\n * @param revision - The Git revision specifier to detect changes relative to. Defaults to HEAD (i.e. will compare staged vs. committed)\n * If comparing against a different branch, call `git merge-base` first to find the target commit.\n * @param gitPath - The path to the Git executable\n * @returns A map from the Git file path to the corresponding file change metadata\n * @beta\n */\nexport function getRepoChanges(\n currentWorkingDirectory: string,\n revision: string = 'HEAD',\n gitPath?: string\n): Map<string, IFileDiffStatus> {\n const rootDirectory: string = getRepoRoot(currentWorkingDirectory, gitPath);\n\n const result: child_process.SpawnSyncReturns<string> = Executable.spawnSync(\n gitPath || 'git',\n STANDARD_GIT_OPTIONS.concat([\n 'diff-index',\n '--color=never',\n '--no-renames',\n '--no-commit-id',\n '--cached',\n '-z',\n revision,\n '--'\n ]),\n {\n currentWorkingDirectory: rootDirectory\n }\n );\n\n if (result.status !== 0) {\n ensureGitMinimumVersion(gitPath);\n\n throw new Error(`git diff-index exited with status ${result.status}: ${result.stderr}`);\n }\n\n const changes: Map<string, IFileDiffStatus> = parseGitDiffIndex(result.stdout);\n\n return changes;\n}\n\n/**\n * Checks the git version and throws an error if it is less than the minimum required version.\n *\n * @public\n */\nexport function ensureGitMinimumVersion(gitPath?: string): void {\n const gitVersion: IGitVersion = getGitVersion(gitPath);\n if (\n gitVersion.major < MINIMUM_GIT_VERSION.major ||\n (gitVersion.major === MINIMUM_GIT_VERSION.major && gitVersion.minor < MINIMUM_GIT_VERSION.minor) ||\n (gitVersion.major === MINIMUM_GIT_VERSION.major &&\n gitVersion.minor === MINIMUM_GIT_VERSION.minor &&\n gitVersion.patch < MINIMUM_GIT_VERSION.patch)\n ) {\n throw new Error(\n `The minimum Git version required is ` +\n `${MINIMUM_GIT_VERSION.major}.${MINIMUM_GIT_VERSION.minor}.${MINIMUM_GIT_VERSION.patch}. ` +\n `Your version is ${gitVersion.major}.${gitVersion.minor}.${gitVersion.patch}.`\n );\n }\n}\n\nfunction getGitVersion(gitPath?: string): IGitVersion {\n const result: child_process.SpawnSyncReturns<string> = Executable.spawnSync(\n gitPath || 'git',\n STANDARD_GIT_OPTIONS.concat(['version'])\n );\n\n if (result.status !== 0) {\n throw new Error(\n `While validating the Git installation, the \"git version\" command failed with ` +\n `status ${result.status}: ${result.stderr}`\n );\n }\n\n return parseGitVersion(result.stdout);\n}\n\nexport function parseGitVersion(gitVersionOutput: string): IGitVersion {\n // This regexp matches output of \"git version\" that looks like `git version <number>.<number>.<number>(+whatever)`\n // Examples:\n // - git version 1.2.3\n // - git version 1.2.3.4.5\n // - git version 1.2.3windows.1\n // - git version 1.2.3.windows.1\n const versionRegex: RegExp = /^git version (\\d+)\\.(\\d+)\\.(\\d+)/;\n const match: RegExpMatchArray | null = versionRegex.exec(gitVersionOutput);\n if (!match) {\n throw new Error(\n `While validating the Git installation, the \"git version\" command produced ` +\n `unexpected output: \"${gitVersionOutput}\"`\n );\n }\n\n const major: number = parseInt(match[1], 10);\n const minor: number = parseInt(match[2], 10);\n const patch: number = parseInt(match[3], 10);\n\n return {\n major,\n minor,\n patch\n };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rushstack/package-deps-hash",
|
|
3
|
-
"version": "4.3.
|
|
3
|
+
"version": "4.3.12",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "dist/package-deps-hash.d.ts",
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"directory": "libraries/package-deps-hash"
|
|
12
12
|
},
|
|
13
13
|
"devDependencies": {
|
|
14
|
-
"
|
|
15
|
-
"
|
|
14
|
+
"@rushstack/heft": "0.69.3",
|
|
15
|
+
"local-node-rig": "1.0.0"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@rushstack/node-core-library": "5.11.0"
|