@lage-run/hasher 1.9.2 → 1.9.4
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/README.md +1 -1
- package/lib/FileHasher.js +6 -8
- package/lib/FileHasher.js.map +1 -1
- package/lib/PackageTree.d.ts +2 -2
- package/lib/PackageTree.js.map +1 -1
- package/lib/TargetHasher.d.ts +15 -22
- package/lib/TargetHasher.js +17 -35
- package/lib/TargetHasher.js.map +1 -1
- package/package.json +14 -11
- package/CHANGELOG.json +0 -735
- package/CHANGELOG.md +0 -323
- package/jest.config.js +0 -1
- package/lib/__fixtures__/config/backfill.config.d.ts +0 -1
- package/lib/__fixtures__/config/packages/package-1/backfill.config.d.ts +0 -0
- package/lib/__fixtures__/monorepo-nested/packages/package-a/build/another/file.d.ts +0 -1
- package/lib/__fixtures__/monorepo-nested/packages/package-a/build/another/file.js +0 -2
- package/lib/__fixtures__/monorepo-nested/packages/package-a/build/another/file.js.map +0 -1
- package/lib/__fixtures__/monorepo-with-global-files/some-global.config.d.ts +0 -1
- package/lib/__fixtures__/monorepo-with-global-files/some-global2.config.d.ts +0 -1
- package/lib/__fixtures__/monorepo-with-global-files-different-tasks/some-global.config.d.ts +0 -1
- package/lib/__tests__/PackageTree.test.d.ts +0 -1
- package/lib/__tests__/PackageTree.test.js +0 -76
- package/lib/__tests__/PackageTree.test.js.map +0 -1
- package/lib/__tests__/TargetHasher.test.d.ts +0 -1
- package/lib/__tests__/TargetHasher.test.js +0 -213
- package/lib/__tests__/TargetHasher.test.js.map +0 -1
- package/lib/__tests__/getPackageDeps.test.d.ts +0 -1
- package/lib/__tests__/getPackageDeps.test.js +0 -310
- package/lib/__tests__/getPackageDeps.test.js.map +0 -1
- package/lib/__tests__/resolveDependenciesHelper.d.ts +0 -3
- package/lib/__tests__/resolveDependenciesHelper.js +0 -66
- package/lib/__tests__/resolveDependenciesHelper.js.map +0 -1
- package/lib/__tests__/resolveExternalDependencies.test.d.ts +0 -1
- package/lib/__tests__/resolveExternalDependencies.test.js +0 -154
- package/lib/__tests__/resolveExternalDependencies.test.js.map +0 -1
- package/lib/__tests__/resolveInternalDependencies.test.d.ts +0 -1
- package/lib/__tests__/resolveInternalDependencies.test.js +0 -131
- package/lib/__tests__/resolveInternalDependencies.test.js.map +0 -1
- package/lib/getPackageDeps.d.ts +0 -45
- package/lib/getPackageDeps.js +0 -259
- package/lib/getPackageDeps.js.map +0 -1
- package/lib/nameAtVersion.d.ts +0 -1
- package/lib/nameAtVersion.js +0 -13
- package/lib/nameAtVersion.js.map +0 -1
- package/lib/resolveExternalDependencies.d.ts +0 -11
- package/lib/resolveExternalDependencies.js +0 -75
- package/lib/resolveExternalDependencies.js.map +0 -1
- package/lib/resolveInternalDependencies.d.ts +0 -6
- package/lib/resolveInternalDependencies.js +0 -26
- package/lib/resolveInternalDependencies.js.map +0 -1
- package/tsconfig.json +0 -7
package/README.md
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
# @lage-run/hasher
|
|
2
2
|
|
|
3
|
-
This package
|
|
3
|
+
This package builds on top of some helpers from `backfill-hasher` but adds customization for hashing targets with custom inputs and other logic.
|
package/lib/FileHasher.js
CHANGED
|
@@ -8,11 +8,11 @@ Object.defineProperty(exports, "FileHasher", {
|
|
|
8
8
|
return FileHasher;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
-
const
|
|
12
|
-
const _path = /*#__PURE__*/ _interop_require_default(require("path"));
|
|
11
|
+
const _backfillhasher = require("backfill-hasher");
|
|
13
12
|
const _globhasher = require("glob-hasher");
|
|
13
|
+
const _gracefulfs = /*#__PURE__*/ _interop_require_default(require("graceful-fs"));
|
|
14
14
|
const _nodereadline = require("node:readline");
|
|
15
|
-
const
|
|
15
|
+
const _path = /*#__PURE__*/ _interop_require_default(require("path"));
|
|
16
16
|
function _check_private_redeclaration(obj, privateCollection) {
|
|
17
17
|
if (privateCollection.has(obj)) {
|
|
18
18
|
throw new TypeError("Cannot initialize the same private elements twice on an object");
|
|
@@ -75,15 +75,13 @@ var _store = /*#__PURE__*/ new WeakMap(), _manifestFile = /*#__PURE__*/ new Weak
|
|
|
75
75
|
class FileHasher {
|
|
76
76
|
getHashesFromGit() {
|
|
77
77
|
const { root } = this.options;
|
|
78
|
-
const fileHashes = (0,
|
|
79
|
-
const files =
|
|
80
|
-
...fileHashes.keys()
|
|
81
|
-
];
|
|
78
|
+
const fileHashes = (0, _backfillhasher.getFileHashes)(root);
|
|
79
|
+
const files = Object.keys(fileHashes);
|
|
82
80
|
const fileStats = (0, _globhasher.stat)(files, {
|
|
83
81
|
cwd: root
|
|
84
82
|
}) ?? {};
|
|
85
83
|
for (const [relativePath, fileStat] of Object.entries(fileStats)){
|
|
86
|
-
const hash = fileHashes
|
|
84
|
+
const hash = fileHashes[relativePath];
|
|
87
85
|
if (hash) {
|
|
88
86
|
const { size, mtime } = fileStat;
|
|
89
87
|
_class_private_field_get(this, _store)[relativePath] = {
|
package/lib/FileHasher.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/FileHasher.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"sources":["../src/FileHasher.ts"],"sourcesContent":["import { getFileHashes } from \"backfill-hasher\";\nimport { hash as fastHash, stat } from \"glob-hasher\";\nimport fs from \"graceful-fs\";\nimport { createInterface } from \"node:readline\";\nimport path from \"path\";\n\ninterface FileHashStoreOptions {\n root: string;\n}\n\ntype FileHashManifestStore = Record<\n string,\n {\n mtime: bigint;\n size: number;\n hash: string;\n }\n>;\n\nexport class FileHasher {\n #store: FileHashManifestStore = {};\n #manifestFile: string;\n\n constructor(private options: FileHashStoreOptions) {\n const { root } = options;\n const cacheDirectory = path.join(root, \"node_modules\", \".cache\", \"lage\");\n this.#manifestFile = path.join(cacheDirectory, \"file_hashes.manifest\");\n }\n\n private getHashesFromGit(): void {\n const { root } = this.options;\n const fileHashes = getFileHashes(root);\n const files = Object.keys(fileHashes);\n const fileStats = stat(files, { cwd: root }) ?? {};\n\n for (const [relativePath, fileStat] of Object.entries(fileStats)) {\n const hash = fileHashes[relativePath];\n if (hash) {\n const { size, mtime } = fileStat;\n\n this.#store[relativePath] = { hash, size, mtime };\n }\n }\n\n this.writeManifest();\n }\n\n public async readManifest(): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n if (!fs.existsSync(this.#manifestFile)) {\n try {\n this.getHashesFromGit();\n resolve();\n } catch (err) {\n reject(err);\n }\n return;\n }\n\n const inputStream = fs.createReadStream(this.#manifestFile, \"utf-8\");\n const rl = createInterface({\n input: inputStream,\n crlfDelay: Infinity,\n });\n\n let info: string[] = [];\n\n rl.on(\"line\", (line) => {\n info = line.split(\"\\0\");\n\n this.#store[info[0]] = {\n mtime: BigInt(info[1]),\n size: parseInt(info[2]),\n hash: info[3],\n };\n });\n\n inputStream.on(\"end\", () => {\n rl.close();\n resolve();\n });\n });\n }\n\n public writeManifest(): void {\n fs.mkdirSync(path.dirname(this.#manifestFile), { recursive: true });\n const outputLines = Object.entries(this.#store).map(([relativePath, info]) => {\n return `${relativePath}\\0${info.mtime.toString()}\\0${info.size.toString()}\\0${info.hash}`;\n });\n\n fs.writeFileSync(this.#manifestFile, outputLines.join(\"\\n\"), \"utf-8\");\n }\n\n public hash(files: string[]): Record<string, string> {\n const hashes: Record<string, string> = {};\n\n const updatedFiles: string[] = [];\n\n const stats = stat(files, { cwd: this.options.root }) ?? {};\n\n for (const file of files) {\n const stat = stats[file];\n\n const info = this.#store[file];\n if (info && stat.mtime === info.mtime && stat.size == info.size) {\n hashes[file] = info.hash;\n } else {\n updatedFiles.push(file);\n }\n }\n\n const updatedHashes = fastHash(updatedFiles, { cwd: this.options.root, concurrency: 4 }) ?? {};\n\n for (const [file, hash] of Object.entries(updatedHashes)) {\n const stat = fs.statSync(path.join(this.options.root, file), { bigint: true });\n this.#store[file] = {\n mtime: stat.mtimeMs,\n size: Number(stat.size),\n hash: hash ?? \"\",\n };\n hashes[file] = hash ?? \"\";\n }\n\n return hashes;\n }\n}\n"],"names":["FileHasher","getHashesFromGit","root","options","fileHashes","getFileHashes","files","Object","keys","fileStats","stat","cwd","relativePath","fileStat","entries","hash","size","mtime","writeManifest","readManifest","Promise","resolve","reject","fs","existsSync","err","inputStream","createReadStream","rl","createInterface","input","crlfDelay","Infinity","info","on","line","split","BigInt","parseInt","close","mkdirSync","path","dirname","recursive","outputLines","map","toString","writeFileSync","join","hashes","updatedFiles","stats","file","push","updatedHashes","fastHash","concurrency","statSync","bigint","mtimeMs","Number","cacheDirectory"],"mappings":"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"}
|
package/lib/PackageTree.d.ts
CHANGED
|
@@ -13,8 +13,8 @@ export declare class PackageTree {
|
|
|
13
13
|
#private;
|
|
14
14
|
private options;
|
|
15
15
|
constructor(options: PackageTreeOptions);
|
|
16
|
-
reset
|
|
16
|
+
private reset;
|
|
17
17
|
initialize(): Promise<void>;
|
|
18
|
-
addToPackageTree
|
|
18
|
+
private addToPackageTree;
|
|
19
19
|
getPackageFiles(packageName: string, patterns: string[]): string[];
|
|
20
20
|
}
|
package/lib/PackageTree.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/PackageTree.ts"],"sourcesContent":["import { type PackageInfos } from \"workspace-tools\";\n\nimport execa from \"execa\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport micromatch from \"micromatch\";\n\nexport interface PackageTreeOptions {\n root: string;\n packageInfos: PackageInfos;\n includeUntracked: boolean;\n}\n\ninterface PathNode {\n children: {\n [key: string]: PathNode;\n };\n\n isPackage: boolean;\n}\n\n/**\n * Package Tree keeps a data structure to quickly find all files in a package.\n *\n * TODO: add a watcher to make sure the tree is up to date during a \"watched\" run.\n */\nexport class PackageTree {\n #tree: PathNode = { children: {}, isPackage: true };\n #packageFiles: Record<string, string[]> = {};\n #memoizedPackageFiles: Record<string, string[]> = {};\n\n constructor(private options: PackageTreeOptions) {}\n\n reset(): void {\n // reset the internal state\n this.#tree = { children: {}, isPackage: true };\n this.#packageFiles = {};\n this.#memoizedPackageFiles = {};\n }\n\n async initialize(): Promise<void> {\n const { root, includeUntracked, packageInfos } = this.options;\n\n this.reset();\n\n // Generate path tree of all packages in workspace (scale: ~2000 * ~3)\n for (const info of Object.values(packageInfos)) {\n const packagePath = path.dirname(info.packageJsonPath);\n const pathParts = path.relative(root, packagePath).split(/[\\\\/]/);\n\n let currentNode = this.#tree;\n\n for (const part of pathParts) {\n // initialize the children if not already done\n currentNode.children[part] = currentNode.children[part] || { children: {}, isPackage: false };\n currentNode = currentNode.children[part];\n }\n\n currentNode.isPackage = true;\n }\n\n // Get all files in the workspace (scale: ~2000) according to git\n const lsFilesResults = await execa(\"git\", [\"ls-files\", \"-z\"], { cwd: root });\n\n if (lsFilesResults.exitCode === 0) {\n const files = lsFilesResults.stdout.split(\"\\0\").filter((f) => Boolean(f) && fs.existsSync(path.join(root, f)));\n this.addToPackageTree(files);\n }\n\n if (includeUntracked) {\n // Also get all untracked files in the workspace according to git\n const lsOtherResults = await execa(\"git\", [\"ls-files\", \"-o\", \"-z\", \"--exclude-standard\"], { cwd: root });\n if (lsOtherResults.exitCode === 0) {\n const files = lsOtherResults.stdout.split(\"\\0\").filter(Boolean);\n this.addToPackageTree(files);\n }\n }\n }\n\n addToPackageTree(filePaths: string[]): void {\n // key: path/to/package (packageRoot), value: array of a tuple of [file, hash]\n const packageFiles = this.#packageFiles;\n\n for (const entry of filePaths) {\n const pathParts = entry.split(/[\\\\/]/);\n\n let node = this.#tree;\n\n const pathPartsBuffer: string[] = [];\n let packagePathParts: string[] = [];\n\n for (const part of pathParts) {\n if (node.children[part]) {\n node = node.children[part] as PathNode;\n pathPartsBuffer.push(part);\n\n if (node.isPackage) {\n packagePathParts = [...pathPartsBuffer];\n }\n } else {\n break;\n }\n }\n\n const packageRoot = packagePathParts.join(\"/\");\n packageFiles[packageRoot] = packageFiles[packageRoot] || [];\n packageFiles[packageRoot].push(entry);\n }\n }\n\n getPackageFiles(packageName: string, patterns: string[]): string[] {\n const { root, packageInfos } = this.options;\n const packagePath = path.relative(root, path.dirname(packageInfos[packageName].packageJsonPath)).replace(/\\\\/g, \"/\");\n\n const packageFiles = this.#packageFiles[packagePath];\n\n if (!packageFiles) {\n return [];\n }\n\n const key = `${packageName}\\0${patterns.join(\"\\0\")}`;\n\n if (!this.#memoizedPackageFiles[key]) {\n const packagePatterns = patterns.map((pattern) => {\n if (pattern.startsWith(\"!\")) {\n return `!${path.join(packagePath, pattern.slice(1)).replace(/\\\\/g, \"/\")}`;\n }\n\n return path.join(packagePath, pattern).replace(/\\\\/g, \"/\");\n });\n this.#memoizedPackageFiles[key] = micromatch(packageFiles, packagePatterns, { dot: true });\n }\n\n return this.#memoizedPackageFiles[key];\n }\n}\n"],"names":["PackageTree","reset","children","isPackage","initialize","root","includeUntracked","packageInfos","options","info","Object","values","packagePath","path","dirname","packageJsonPath","pathParts","relative","split","currentNode","part","lsFilesResults","execa","cwd","exitCode","files","stdout","filter","f","Boolean","fs","existsSync","join","addToPackageTree","lsOtherResults","filePaths","packageFiles","entry","node","pathPartsBuffer","packagePathParts","push","packageRoot","getPackageFiles","packageName","patterns","replace","key","packagePatterns","map","pattern","startsWith","slice","micromatch","dot"],"mappings":";;;;+BA0BaA;;;eAAAA;;;8DAxBK;6DACD;2DACF;mEACQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAsBrB,qCACA,6CACA;AAHK,MAAMA;
|
|
1
|
+
{"version":3,"sources":["../src/PackageTree.ts"],"sourcesContent":["import { type PackageInfos } from \"workspace-tools\";\n\nimport execa from \"execa\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport micromatch from \"micromatch\";\n\nexport interface PackageTreeOptions {\n root: string;\n packageInfos: PackageInfos;\n includeUntracked: boolean;\n}\n\ninterface PathNode {\n children: {\n [key: string]: PathNode;\n };\n\n isPackage: boolean;\n}\n\n/**\n * Package Tree keeps a data structure to quickly find all files in a package.\n *\n * TODO: add a watcher to make sure the tree is up to date during a \"watched\" run.\n */\nexport class PackageTree {\n #tree: PathNode = { children: {}, isPackage: true };\n #packageFiles: Record<string, string[]> = {};\n #memoizedPackageFiles: Record<string, string[]> = {};\n\n constructor(private options: PackageTreeOptions) {}\n\n private reset(): void {\n // reset the internal state\n this.#tree = { children: {}, isPackage: true };\n this.#packageFiles = {};\n this.#memoizedPackageFiles = {};\n }\n\n public async initialize(): Promise<void> {\n const { root, includeUntracked, packageInfos } = this.options;\n\n this.reset();\n\n // Generate path tree of all packages in workspace (scale: ~2000 * ~3)\n for (const info of Object.values(packageInfos)) {\n const packagePath = path.dirname(info.packageJsonPath);\n const pathParts = path.relative(root, packagePath).split(/[\\\\/]/);\n\n let currentNode = this.#tree;\n\n for (const part of pathParts) {\n // initialize the children if not already done\n currentNode.children[part] = currentNode.children[part] || { children: {}, isPackage: false };\n currentNode = currentNode.children[part];\n }\n\n currentNode.isPackage = true;\n }\n\n // Get all files in the workspace (scale: ~2000) according to git\n const lsFilesResults = await execa(\"git\", [\"ls-files\", \"-z\"], { cwd: root });\n\n if (lsFilesResults.exitCode === 0) {\n const files = lsFilesResults.stdout.split(\"\\0\").filter((f) => Boolean(f) && fs.existsSync(path.join(root, f)));\n this.addToPackageTree(files);\n }\n\n if (includeUntracked) {\n // Also get all untracked files in the workspace according to git\n const lsOtherResults = await execa(\"git\", [\"ls-files\", \"-o\", \"-z\", \"--exclude-standard\"], { cwd: root });\n if (lsOtherResults.exitCode === 0) {\n const files = lsOtherResults.stdout.split(\"\\0\").filter(Boolean);\n this.addToPackageTree(files);\n }\n }\n }\n\n private addToPackageTree(filePaths: string[]): void {\n // key: path/to/package (packageRoot), value: array of a tuple of [file, hash]\n const packageFiles = this.#packageFiles;\n\n for (const entry of filePaths) {\n const pathParts = entry.split(/[\\\\/]/);\n\n let node = this.#tree;\n\n const pathPartsBuffer: string[] = [];\n let packagePathParts: string[] = [];\n\n for (const part of pathParts) {\n if (node.children[part]) {\n node = node.children[part] as PathNode;\n pathPartsBuffer.push(part);\n\n if (node.isPackage) {\n packagePathParts = [...pathPartsBuffer];\n }\n } else {\n break;\n }\n }\n\n const packageRoot = packagePathParts.join(\"/\");\n packageFiles[packageRoot] = packageFiles[packageRoot] || [];\n packageFiles[packageRoot].push(entry);\n }\n }\n\n public getPackageFiles(packageName: string, patterns: string[]): string[] {\n const { root, packageInfos } = this.options;\n const packagePath = path.relative(root, path.dirname(packageInfos[packageName].packageJsonPath)).replace(/\\\\/g, \"/\");\n\n const packageFiles = this.#packageFiles[packagePath];\n\n if (!packageFiles) {\n return [];\n }\n\n const key = `${packageName}\\0${patterns.join(\"\\0\")}`;\n\n if (!this.#memoizedPackageFiles[key]) {\n const packagePatterns = patterns.map((pattern) => {\n if (pattern.startsWith(\"!\")) {\n return `!${path.join(packagePath, pattern.slice(1)).replace(/\\\\/g, \"/\")}`;\n }\n\n return path.join(packagePath, pattern).replace(/\\\\/g, \"/\");\n });\n this.#memoizedPackageFiles[key] = micromatch(packageFiles, packagePatterns, { dot: true });\n }\n\n return this.#memoizedPackageFiles[key];\n }\n}\n"],"names":["PackageTree","reset","children","isPackage","initialize","root","includeUntracked","packageInfos","options","info","Object","values","packagePath","path","dirname","packageJsonPath","pathParts","relative","split","currentNode","part","lsFilesResults","execa","cwd","exitCode","files","stdout","filter","f","Boolean","fs","existsSync","join","addToPackageTree","lsOtherResults","filePaths","packageFiles","entry","node","pathPartsBuffer","packagePathParts","push","packageRoot","getPackageFiles","packageName","patterns","replace","key","packagePatterns","map","pattern","startsWith","slice","micromatch","dot"],"mappings":"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"}
|
package/lib/TargetHasher.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
+
import type { Logger } from "@lage-run/logger";
|
|
1
2
|
import type { Target } from "@lage-run/target-graph";
|
|
2
|
-
import { type
|
|
3
|
-
import type { DependencyMap } from "workspace-tools/lib/graph/createDependencyMap.js";
|
|
3
|
+
import { type DependencyMap } from "workspace-tools";
|
|
4
4
|
import { FileHasher } from "./FileHasher.js";
|
|
5
|
-
import type { Logger } from "@lage-run/logger";
|
|
6
5
|
import { PackageTree } from "./PackageTree.js";
|
|
7
6
|
export interface TargetHasherOptions {
|
|
8
7
|
root: string;
|
|
@@ -25,32 +24,26 @@ export interface TargetManifest {
|
|
|
25
24
|
}
|
|
26
25
|
/**
|
|
27
26
|
* TargetHasher is a class that can be used to generate a hash of a target.
|
|
28
|
-
*
|
|
29
|
-
* Currently, it encapsulates the use of `backfill-hasher` to generate a hash.
|
|
27
|
+
* It uses `glob-hasher` internally.
|
|
30
28
|
*/
|
|
31
29
|
export declare class TargetHasher {
|
|
32
30
|
private options;
|
|
33
|
-
targetHashesLog
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
targetHashesDirectory: string;
|
|
38
|
-
logger: Logger | undefined;
|
|
39
|
-
fileHasher: FileHasher;
|
|
31
|
+
private targetHashesLog;
|
|
32
|
+
private targetHashesDirectory;
|
|
33
|
+
private logger;
|
|
34
|
+
private fileHasher;
|
|
40
35
|
packageTree: PackageTree | undefined;
|
|
41
|
-
initializedPromise
|
|
42
|
-
packageInfos
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
targetHashes: Record<string, string>;
|
|
36
|
+
private initializedPromise;
|
|
37
|
+
private packageInfos;
|
|
38
|
+
private globalInputsHash;
|
|
39
|
+
private lockInfo;
|
|
40
|
+
private targetHashes;
|
|
47
41
|
dependencyMap: DependencyMap;
|
|
48
|
-
getPackageInfos(workspacePackages: WorkspaceInfos): PackageInfos;
|
|
49
42
|
constructor(options: TargetHasherOptions);
|
|
50
|
-
ensureInitialized
|
|
43
|
+
private ensureInitialized;
|
|
51
44
|
initialize(): Promise<void>;
|
|
52
45
|
hash(target: Target): Promise<string>;
|
|
53
|
-
writeTargetHashesManifest
|
|
54
|
-
getEnvironmentGlobHashes
|
|
46
|
+
private writeTargetHashesManifest;
|
|
47
|
+
private getEnvironmentGlobHashes;
|
|
55
48
|
cleanup(): Promise<void>;
|
|
56
49
|
}
|
package/lib/TargetHasher.js
CHANGED
|
@@ -8,18 +8,16 @@ Object.defineProperty(exports, "TargetHasher", {
|
|
|
8
8
|
return TargetHasher;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
-
const _globhasher = require("glob-hasher");
|
|
12
11
|
const _globby = require("@lage-run/globby");
|
|
12
|
+
const _backfillhasher = require("backfill-hasher");
|
|
13
13
|
const _fs = /*#__PURE__*/ _interop_require_default(require("fs"));
|
|
14
|
+
const _globhasher = require("glob-hasher");
|
|
14
15
|
const _path = /*#__PURE__*/ _interop_require_default(require("path"));
|
|
15
16
|
const _workspacetools = require("workspace-tools");
|
|
16
|
-
const _infoFromPackageJson = require("workspace-tools/lib/infoFromPackageJson.js");
|
|
17
|
-
const _hashStrings = require("./hashStrings.js");
|
|
18
|
-
const _resolveInternalDependencies = require("./resolveInternalDependencies.js");
|
|
19
|
-
const _resolveExternalDependencies = require("./resolveExternalDependencies.js");
|
|
20
17
|
const _FileHasher = require("./FileHasher.js");
|
|
21
18
|
const _PackageTree = require("./PackageTree.js");
|
|
22
19
|
const _getInputFiles = require("./getInputFiles.js");
|
|
20
|
+
const _hashStrings = require("./hashStrings.js");
|
|
23
21
|
function _define_property(obj, key, value) {
|
|
24
22
|
if (key in obj) {
|
|
25
23
|
Object.defineProperty(obj, key, {
|
|
@@ -39,29 +37,6 @@ function _interop_require_default(obj) {
|
|
|
39
37
|
};
|
|
40
38
|
}
|
|
41
39
|
class TargetHasher {
|
|
42
|
-
getPackageInfos(workspacePackages) {
|
|
43
|
-
const { root } = this.options;
|
|
44
|
-
const packageInfos = {};
|
|
45
|
-
if (workspacePackages.length) {
|
|
46
|
-
for (const pkg of workspacePackages){
|
|
47
|
-
packageInfos[pkg.name] = pkg.packageJson;
|
|
48
|
-
}
|
|
49
|
-
} else {
|
|
50
|
-
const packageJsonPath = _path.default.join(root, "package.json");
|
|
51
|
-
if (_fs.default.existsSync(packageJsonPath)) {
|
|
52
|
-
try {
|
|
53
|
-
const packageJson = JSON.parse(_fs.default.readFileSync(packageJsonPath, "utf-8"));
|
|
54
|
-
const rootInfo = (0, _infoFromPackageJson.infoFromPackageJson)(packageJson, packageJsonPath);
|
|
55
|
-
if (rootInfo) {
|
|
56
|
-
packageInfos[rootInfo.name] = rootInfo;
|
|
57
|
-
}
|
|
58
|
-
} catch (e) {
|
|
59
|
-
throw new Error(`Invalid package.json file detected ${packageJsonPath}: ${e?.message || e}`);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return packageInfos;
|
|
64
|
-
}
|
|
65
40
|
ensureInitialized() {
|
|
66
41
|
if (!this.initializedPromise) {
|
|
67
42
|
throw new Error("TargetHasher is not initialized");
|
|
@@ -77,8 +52,17 @@ class TargetHasher {
|
|
|
77
52
|
this.fileHasher.readManifest().then(()=>(0, _globby.globAsync)(environmentGlob, {
|
|
78
53
|
cwd: root
|
|
79
54
|
})).then((files)=>this.fileHasher.hash(files)).then((hash)=>this.globalInputsHash = hash),
|
|
80
|
-
(0, _workspacetools.
|
|
81
|
-
|
|
55
|
+
(0, _workspacetools.getPackageInfosAsync)(root).then((packageInfos)=>{
|
|
56
|
+
if (Object.keys(packageInfos).length) {
|
|
57
|
+
this.packageInfos = packageInfos;
|
|
58
|
+
} else {
|
|
59
|
+
const rootInfo = (0, _workspacetools.getPackageInfo)(root);
|
|
60
|
+
if (rootInfo) {
|
|
61
|
+
this.packageInfos = {
|
|
62
|
+
[rootInfo.name]: rootInfo
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
82
66
|
this.dependencyMap = (0, _workspacetools.createDependencyMap)(this.packageInfos, {
|
|
83
67
|
withDevDependencies: true,
|
|
84
68
|
withPeerDependencies: false
|
|
@@ -118,14 +102,13 @@ class TargetHasher {
|
|
|
118
102
|
// 1. add hash of target's inputs
|
|
119
103
|
// 2. add hash of target packages' internal and external deps
|
|
120
104
|
const { dependencies, devDependencies } = this.packageInfos[target.packageName];
|
|
121
|
-
const workspaceInfo = this.workspaceInfo;
|
|
122
105
|
const parsedLock = this.lockInfo;
|
|
123
106
|
const allDependencies = {
|
|
124
107
|
...dependencies,
|
|
125
108
|
...devDependencies
|
|
126
109
|
};
|
|
127
|
-
const internalDeps =
|
|
128
|
-
const externalDeps = (0,
|
|
110
|
+
const internalDeps = Object.keys(allDependencies).filter((dep)=>this.packageInfos[dep]);
|
|
111
|
+
const externalDeps = (0, _backfillhasher.resolveExternalDependencies)(allDependencies, this.packageInfos, parsedLock);
|
|
129
112
|
const resolvedDependencies = [
|
|
130
113
|
...internalDeps,
|
|
131
114
|
...externalDeps
|
|
@@ -176,7 +159,7 @@ class TargetHasher {
|
|
|
176
159
|
}
|
|
177
160
|
async cleanup() {
|
|
178
161
|
this.writeTargetHashesManifest();
|
|
179
|
-
|
|
162
|
+
this.fileHasher.writeManifest();
|
|
180
163
|
}
|
|
181
164
|
constructor(options){
|
|
182
165
|
_define_property(this, "options", void 0);
|
|
@@ -187,7 +170,6 @@ class TargetHasher {
|
|
|
187
170
|
_define_property(this, "packageTree", void 0);
|
|
188
171
|
_define_property(this, "initializedPromise", void 0);
|
|
189
172
|
_define_property(this, "packageInfos", void 0);
|
|
190
|
-
_define_property(this, "workspaceInfo", void 0);
|
|
191
173
|
_define_property(this, "globalInputsHash", void 0);
|
|
192
174
|
_define_property(this, "lockInfo", void 0);
|
|
193
175
|
_define_property(this, "targetHashes", void 0);
|
package/lib/TargetHasher.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/TargetHasher.ts"],"sourcesContent":["import type { Target } from \"@lage-run/target-graph\";\nimport { hash } from \"glob-hasher\";\nimport { globAsync } from \"@lage-run/globby\";\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport {\n type ParsedLock,\n type WorkspaceInfos,\n type PackageInfos,\n getWorkspaceInfosAsync,\n parseLockFile,\n createDependencyMap,\n} from \"workspace-tools\";\nimport type { DependencyMap } from \"workspace-tools/lib/graph/createDependencyMap.js\";\nimport { infoFromPackageJson } from \"workspace-tools/lib/infoFromPackageJson.js\";\n\nimport { hashStrings } from \"./hashStrings.js\";\nimport { resolveInternalDependencies } from \"./resolveInternalDependencies.js\";\nimport { resolveExternalDependencies } from \"./resolveExternalDependencies.js\";\nimport { FileHasher } from \"./FileHasher.js\";\nimport type { Logger } from \"@lage-run/logger\";\nimport { PackageTree } from \"./PackageTree.js\";\nimport { getInputFiles } from \"./getInputFiles.js\";\n\nexport interface TargetHasherOptions {\n root: string;\n environmentGlob: string[];\n cacheKey?: string;\n cliArgs?: string[];\n logger?: Logger;\n}\n\nexport interface TargetManifest {\n id: string;\n hash: string;\n globalInputsHash: string;\n dependency: Record<string, string>;\n fileHasher: FileHasher;\n files: Record<\n string,\n {\n mtimeMs: number;\n size: number;\n hash: string;\n }\n >;\n}\n\n/**\n * TargetHasher is a class that can be used to generate a hash of a target.\n *\n * Currently, it encapsulates the use of `backfill-hasher` to generate a hash.\n */\nexport class TargetHasher {\n targetHashesLog: Record<string, { fileHashes: Record<string, string>; globalFileHashes: Record<string, string> }> = {};\n targetHashesDirectory: string;\n\n logger: Logger | undefined;\n fileHasher: FileHasher;\n packageTree: PackageTree | undefined;\n\n initializedPromise: Promise<unknown> | undefined;\n\n packageInfos: PackageInfos = {};\n workspaceInfo: WorkspaceInfos | undefined;\n globalInputsHash: Record<string, string> | undefined;\n lockInfo: ParsedLock | undefined;\n targetHashes: Record<string, string> = {};\n\n dependencyMap: DependencyMap = {\n dependencies: new Map(),\n dependents: new Map(),\n };\n\n getPackageInfos(workspacePackages: WorkspaceInfos): PackageInfos {\n const { root } = this.options;\n const packageInfos: PackageInfos = {};\n\n if (workspacePackages.length) {\n for (const pkg of workspacePackages) {\n packageInfos[pkg.name] = pkg.packageJson;\n }\n } else {\n const packageJsonPath = path.join(root, \"package.json\");\n if (fs.existsSync(packageJsonPath)) {\n try {\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, \"utf-8\"));\n const rootInfo = infoFromPackageJson(packageJson, packageJsonPath);\n if (rootInfo) {\n packageInfos[rootInfo.name] = rootInfo;\n }\n } catch (e) {\n throw new Error(`Invalid package.json file detected ${packageJsonPath}: ${(e as Error)?.message || e}`);\n }\n }\n }\n\n return packageInfos;\n }\n\n constructor(private options: TargetHasherOptions) {\n const { root, logger } = options;\n this.logger = logger;\n\n this.fileHasher = new FileHasher({\n root,\n });\n\n this.targetHashesDirectory = path.join(root, \"node_modules\", \".cache\", \"lage\", \"hashes\");\n\n if (!fs.existsSync(this.targetHashesDirectory)) {\n fs.mkdirSync(this.targetHashesDirectory, { recursive: true });\n }\n }\n\n ensureInitialized(): void {\n if (!this.initializedPromise) {\n throw new Error(\"TargetHasher is not initialized\");\n }\n }\n\n async initialize(): Promise<void> {\n const { environmentGlob, root } = this.options;\n\n if (this.initializedPromise) {\n await this.initializedPromise;\n return;\n }\n\n this.initializedPromise = Promise.all([\n this.fileHasher\n .readManifest()\n .then(() => globAsync(environmentGlob, { cwd: root }))\n .then((files) => this.fileHasher.hash(files))\n .then((hash) => (this.globalInputsHash = hash)),\n\n getWorkspaceInfosAsync(root)\n .then((workspaceInfo) => (this.workspaceInfo = workspaceInfo))\n .then(() => {\n this.packageInfos = this.getPackageInfos(this.workspaceInfo!);\n\n this.dependencyMap = createDependencyMap(this.packageInfos, { withDevDependencies: true, withPeerDependencies: false });\n this.packageTree = new PackageTree({\n root,\n packageInfos: this.packageInfos,\n\n // TODO: (optimization) false if process.env.TF_BUILD || process.env.CI\n includeUntracked: true,\n });\n\n return this.packageTree.initialize();\n }),\n\n parseLockFile(root).then((lockInfo) => (this.lockInfo = lockInfo)),\n ]);\n\n await this.initializedPromise;\n\n if (this.logger !== undefined) {\n const globalInputsHash = hashStrings(Object.values(this.globalInputsHash ?? {}));\n this.logger.verbose(`Global inputs hash: ${globalInputsHash}`);\n }\n }\n\n async hash(target: Target): Promise<string> {\n this.ensureInitialized();\n\n const { root } = this.options;\n\n if (target.cwd === root && target.cache) {\n if (!target.inputs) {\n throw new Error(`No \"inputs\" specified for target \"${target.id}\"; cannot cache.`);\n }\n\n const files = await globAsync(target.inputs, { cwd: root });\n const fileFashes = hash(files, { cwd: root }) ?? {};\n\n const hashes = Object.values(fileFashes) as string[];\n\n return hashStrings(hashes);\n }\n\n // 1. add hash of target's inputs\n // 2. add hash of target packages' internal and external deps\n const { dependencies, devDependencies } = this.packageInfos[target.packageName!];\n\n const workspaceInfo = this.workspaceInfo!;\n const parsedLock = this.lockInfo!;\n\n const allDependencies: Record<string, string> = {\n ...dependencies,\n ...devDependencies,\n };\n\n const internalDeps = resolveInternalDependencies(allDependencies, workspaceInfo);\n const externalDeps = resolveExternalDependencies(allDependencies, workspaceInfo, parsedLock);\n const resolvedDependencies = [...internalDeps, ...externalDeps].sort();\n\n const files = getInputFiles(target, this.dependencyMap, this.packageTree!);\n const fileHashes = this.fileHasher.hash(files) ?? {}; // this list is sorted by file name\n\n // get target hashes\n const targetDepHashes = target.dependencies?.sort().map((targetDep) => this.targetHashes[targetDep]);\n\n const globalFileHashes = await this.getEnvironmentGlobHashes(root, target);\n\n const combinedHashes = [\n // Environmental hashes\n ...Object.values(globalFileHashes),\n `${target.id}|${JSON.stringify(this.options.cliArgs)}`,\n this.options.cacheKey || \"\",\n\n // File content hashes based on target.inputs\n ...Object.values(fileHashes),\n\n // Dependency hashes\n ...resolvedDependencies,\n ...targetDepHashes,\n ].filter(Boolean);\n\n const hashString = hashStrings(combinedHashes);\n\n this.targetHashes[target.id] = hashString;\n\n this.targetHashesLog[target.id] = { fileHashes, globalFileHashes };\n\n return hashString;\n }\n\n writeTargetHashesManifest(): void {\n for (const [id, { fileHashes, globalFileHashes }] of Object.entries(this.targetHashesLog)) {\n const targetHashesManifestPath = path.join(this.targetHashesDirectory, `${id}.json`);\n if (!fs.existsSync(path.dirname(targetHashesManifestPath))) {\n fs.mkdirSync(path.dirname(targetHashesManifestPath), { recursive: true });\n }\n fs.writeFileSync(targetHashesManifestPath, JSON.stringify({ fileHashes, globalFileHashes }), \"utf-8\");\n }\n }\n\n async getEnvironmentGlobHashes(root: string, target: Target): Promise<Record<string, string>> {\n const globalFileHashes = target.environmentGlob\n ? this.fileHasher.hash(await globAsync(target.environmentGlob ?? [], { cwd: root }))\n : (this.globalInputsHash ?? {});\n\n return globalFileHashes;\n }\n\n async cleanup(): Promise<void> {\n this.writeTargetHashesManifest();\n await this.fileHasher.writeManifest();\n }\n}\n"],"names":["TargetHasher","getPackageInfos","workspacePackages","root","options","packageInfos","length","pkg","name","packageJson","packageJsonPath","path","join","fs","existsSync","JSON","parse","readFileSync","rootInfo","infoFromPackageJson","e","Error","message","ensureInitialized","initializedPromise","initialize","environmentGlob","Promise","all","fileHasher","readManifest","then","globAsync","cwd","files","hash","globalInputsHash","getWorkspaceInfosAsync","workspaceInfo","dependencyMap","createDependencyMap","withDevDependencies","withPeerDependencies","packageTree","PackageTree","includeUntracked","parseLockFile","lockInfo","logger","undefined","hashStrings","Object","values","verbose","target","cache","inputs","id","fileFashes","hashes","dependencies","devDependencies","packageName","parsedLock","allDependencies","internalDeps","resolveInternalDependencies","externalDeps","resolveExternalDependencies","resolvedDependencies","sort","getInputFiles","fileHashes","targetDepHashes","map","targetDep","targetHashes","globalFileHashes","getEnvironmentGlobHashes","combinedHashes","stringify","cliArgs","cacheKey","filter","Boolean","hashString","targetHashesLog","writeTargetHashesManifest","entries","targetHashesManifestPath","targetHashesDirectory","dirname","mkdirSync","recursive","writeFileSync","cleanup","writeManifest","Map","dependents","FileHasher"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/TargetHasher.ts"],"sourcesContent":["import { globAsync } from \"@lage-run/globby\";\nimport type { Logger } from \"@lage-run/logger\";\nimport type { Target } from \"@lage-run/target-graph\";\nimport { resolveExternalDependencies } from \"backfill-hasher\";\nimport fs from \"fs\";\nimport { hash } from \"glob-hasher\";\nimport path from \"path\";\nimport {\n createDependencyMap,\n type DependencyMap,\n getPackageInfo,\n getPackageInfosAsync,\n type PackageInfos,\n type ParsedLock,\n parseLockFile,\n} from \"workspace-tools\";\nimport { FileHasher } from \"./FileHasher.js\";\nimport { PackageTree } from \"./PackageTree.js\";\nimport { getInputFiles } from \"./getInputFiles.js\";\nimport { hashStrings } from \"./hashStrings.js\";\n\nexport interface TargetHasherOptions {\n root: string;\n environmentGlob: string[];\n cacheKey?: string;\n cliArgs?: string[];\n logger?: Logger;\n}\n\nexport interface TargetManifest {\n id: string;\n hash: string;\n globalInputsHash: string;\n dependency: Record<string, string>;\n fileHasher: FileHasher;\n files: Record<\n string,\n {\n mtimeMs: number;\n size: number;\n hash: string;\n }\n >;\n}\n\n/**\n * TargetHasher is a class that can be used to generate a hash of a target.\n * It uses `glob-hasher` internally.\n */\nexport class TargetHasher {\n private targetHashesLog: Record<string, { fileHashes: Record<string, string>; globalFileHashes: Record<string, string> }> = {};\n private targetHashesDirectory: string;\n\n private logger: Logger | undefined;\n private fileHasher: FileHasher;\n public packageTree: PackageTree | undefined;\n\n private initializedPromise: Promise<unknown> | undefined;\n\n private packageInfos: PackageInfos = {};\n private globalInputsHash: Record<string, string> | undefined;\n private lockInfo: ParsedLock | undefined;\n private targetHashes: Record<string, string> = {};\n\n public dependencyMap: DependencyMap = {\n dependencies: new Map(),\n dependents: new Map(),\n };\n\n constructor(private options: TargetHasherOptions) {\n const { root, logger } = options;\n this.logger = logger;\n\n this.fileHasher = new FileHasher({\n root,\n });\n\n this.targetHashesDirectory = path.join(root, \"node_modules\", \".cache\", \"lage\", \"hashes\");\n\n if (!fs.existsSync(this.targetHashesDirectory)) {\n fs.mkdirSync(this.targetHashesDirectory, { recursive: true });\n }\n }\n\n private ensureInitialized(): void {\n if (!this.initializedPromise) {\n throw new Error(\"TargetHasher is not initialized\");\n }\n }\n\n public async initialize(): Promise<void> {\n const { environmentGlob, root } = this.options;\n\n if (this.initializedPromise) {\n await this.initializedPromise;\n return;\n }\n\n this.initializedPromise = Promise.all([\n this.fileHasher\n .readManifest()\n .then(() => globAsync(environmentGlob, { cwd: root }))\n .then((files) => this.fileHasher.hash(files))\n .then((hash) => (this.globalInputsHash = hash)),\n\n getPackageInfosAsync(root).then((packageInfos) => {\n if (Object.keys(packageInfos).length) {\n this.packageInfos = packageInfos;\n } else {\n const rootInfo = getPackageInfo(root);\n if (rootInfo) {\n this.packageInfos = { [rootInfo.name]: rootInfo };\n }\n }\n\n this.dependencyMap = createDependencyMap(this.packageInfos, { withDevDependencies: true, withPeerDependencies: false });\n this.packageTree = new PackageTree({\n root,\n packageInfos: this.packageInfos,\n\n // TODO: (optimization) false if process.env.TF_BUILD || process.env.CI\n includeUntracked: true,\n });\n\n return this.packageTree.initialize();\n }),\n\n parseLockFile(root).then((lockInfo) => (this.lockInfo = lockInfo)),\n ]);\n\n await this.initializedPromise;\n\n if (this.logger !== undefined) {\n const globalInputsHash = hashStrings(Object.values(this.globalInputsHash ?? {}));\n this.logger.verbose(`Global inputs hash: ${globalInputsHash}`);\n }\n }\n\n public async hash(target: Target): Promise<string> {\n this.ensureInitialized();\n\n const { root } = this.options;\n\n if (target.cwd === root && target.cache) {\n if (!target.inputs) {\n throw new Error(`No \"inputs\" specified for target \"${target.id}\"; cannot cache.`);\n }\n\n const files = await globAsync(target.inputs, { cwd: root });\n const fileFashes = hash(files, { cwd: root }) ?? {};\n\n const hashes = Object.values(fileFashes) as string[];\n\n return hashStrings(hashes);\n }\n\n // 1. add hash of target's inputs\n // 2. add hash of target packages' internal and external deps\n const { dependencies, devDependencies } = this.packageInfos[target.packageName!];\n\n const parsedLock = this.lockInfo!;\n\n const allDependencies: Record<string, string> = {\n ...dependencies,\n ...devDependencies,\n };\n\n const internalDeps = Object.keys(allDependencies).filter((dep) => this.packageInfos[dep]);\n const externalDeps = resolveExternalDependencies(allDependencies, this.packageInfos, parsedLock);\n const resolvedDependencies = [...internalDeps, ...externalDeps].sort();\n\n const files = getInputFiles(target, this.dependencyMap, this.packageTree!);\n const fileHashes = this.fileHasher.hash(files) ?? {}; // this list is sorted by file name\n\n // get target hashes\n const targetDepHashes = target.dependencies?.sort().map((targetDep) => this.targetHashes[targetDep]);\n\n const globalFileHashes = await this.getEnvironmentGlobHashes(root, target);\n\n const combinedHashes = [\n // Environmental hashes\n ...Object.values(globalFileHashes),\n `${target.id}|${JSON.stringify(this.options.cliArgs)}`,\n this.options.cacheKey || \"\",\n\n // File content hashes based on target.inputs\n ...Object.values(fileHashes),\n\n // Dependency hashes\n ...resolvedDependencies,\n ...targetDepHashes,\n ].filter(Boolean);\n\n const hashString = hashStrings(combinedHashes);\n\n this.targetHashes[target.id] = hashString;\n\n this.targetHashesLog[target.id] = { fileHashes, globalFileHashes };\n\n return hashString;\n }\n\n private writeTargetHashesManifest(): void {\n for (const [id, { fileHashes, globalFileHashes }] of Object.entries(this.targetHashesLog)) {\n const targetHashesManifestPath = path.join(this.targetHashesDirectory, `${id}.json`);\n if (!fs.existsSync(path.dirname(targetHashesManifestPath))) {\n fs.mkdirSync(path.dirname(targetHashesManifestPath), { recursive: true });\n }\n fs.writeFileSync(targetHashesManifestPath, JSON.stringify({ fileHashes, globalFileHashes }), \"utf-8\");\n }\n }\n\n private async getEnvironmentGlobHashes(root: string, target: Target): Promise<Record<string, string>> {\n const globalFileHashes = target.environmentGlob\n ? this.fileHasher.hash(await globAsync(target.environmentGlob ?? [], { cwd: root }))\n : (this.globalInputsHash ?? {});\n\n return globalFileHashes;\n }\n\n public async cleanup(): Promise<void> {\n this.writeTargetHashesManifest();\n this.fileHasher.writeManifest();\n }\n}\n"],"names":["TargetHasher","ensureInitialized","initializedPromise","Error","initialize","environmentGlob","root","options","Promise","all","fileHasher","readManifest","then","globAsync","cwd","files","hash","globalInputsHash","getPackageInfosAsync","packageInfos","Object","keys","length","rootInfo","getPackageInfo","name","dependencyMap","createDependencyMap","withDevDependencies","withPeerDependencies","packageTree","PackageTree","includeUntracked","parseLockFile","lockInfo","logger","undefined","hashStrings","values","verbose","target","cache","inputs","id","fileFashes","hashes","dependencies","devDependencies","packageName","parsedLock","allDependencies","internalDeps","filter","dep","externalDeps","resolveExternalDependencies","resolvedDependencies","sort","getInputFiles","fileHashes","targetDepHashes","map","targetDep","targetHashes","globalFileHashes","getEnvironmentGlobHashes","combinedHashes","JSON","stringify","cliArgs","cacheKey","Boolean","hashString","targetHashesLog","writeTargetHashesManifest","entries","targetHashesManifestPath","path","join","targetHashesDirectory","fs","existsSync","dirname","mkdirSync","recursive","writeFileSync","cleanup","writeManifest","Map","dependents","FileHasher"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lage-run/hasher",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.4",
|
|
4
4
|
"description": "Hasher for Lage Targets",
|
|
5
5
|
"repository": {
|
|
6
6
|
"url": "https://github.com/microsoft/lage"
|
|
@@ -9,20 +9,22 @@
|
|
|
9
9
|
"main": "lib/index.js",
|
|
10
10
|
"types": "lib/index.d.ts",
|
|
11
11
|
"scripts": {
|
|
12
|
-
"build": "
|
|
13
|
-
"
|
|
14
|
-
"
|
|
12
|
+
"build": "yarn types && yarn transpile",
|
|
13
|
+
"transpile": "monorepo-scripts transpile",
|
|
14
|
+
"types": "yarn run -T tsc",
|
|
15
|
+
"test": "yarn run -T jest",
|
|
15
16
|
"lint": "monorepo-scripts lint"
|
|
16
17
|
},
|
|
17
18
|
"dependencies": {
|
|
18
|
-
"@lage-run/globby": "^
|
|
19
|
-
"@lage-run/logger": "^1.3.
|
|
20
|
-
"@lage-run/target-graph": "^0.
|
|
19
|
+
"@lage-run/globby": "^13.0.1",
|
|
20
|
+
"@lage-run/logger": "^1.3.3",
|
|
21
|
+
"@lage-run/target-graph": "^0.13.0",
|
|
22
|
+
"backfill-hasher": "^6.7.0",
|
|
21
23
|
"execa": "^5.1.1",
|
|
22
24
|
"glob-hasher": "^1.4.2",
|
|
23
25
|
"graceful-fs": "^4.2.11",
|
|
24
26
|
"micromatch": "^4.0.8",
|
|
25
|
-
"workspace-tools": "^0.
|
|
27
|
+
"workspace-tools": "^0.41.0"
|
|
26
28
|
},
|
|
27
29
|
"devDependencies": {
|
|
28
30
|
"@lage-run/monorepo-fixture": "^0.1.0",
|
|
@@ -30,7 +32,8 @@
|
|
|
30
32
|
"@types/graceful-fs": "^4.1.6",
|
|
31
33
|
"@types/micromatch": "^4.0.0"
|
|
32
34
|
},
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
|
|
35
|
+
"files": [
|
|
36
|
+
"lib/!(__*)",
|
|
37
|
+
"lib/!(__*)/**"
|
|
38
|
+
]
|
|
36
39
|
}
|