nx 20.5.0 → 20.6.0-beta.1

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.
@@ -37,12 +37,13 @@ export declare class ImportResult {
37
37
 
38
38
  export declare class NxCache {
39
39
  cacheDirectory: string
40
- constructor(workspaceRoot: string, cachePath: string, dbConnection: ExternalObject<NxDbConnection>, linkTaskDetails?: boolean | undefined | null)
40
+ constructor(workspaceRoot: string, cachePath: string, dbConnection: ExternalObject<NxDbConnection>, linkTaskDetails?: boolean | undefined | null, maxCacheSize?: number | undefined | null)
41
41
  get(hash: string): CachedResult | null
42
42
  put(hash: string, terminalOutput: string, outputs: Array<string>, code: number): void
43
- applyRemoteCacheResults(hash: string, result: CachedResult): void
43
+ applyRemoteCacheResults(hash: string, result: CachedResult, outputs: Array<string>): void
44
44
  getTaskOutputsPath(hash: string): string
45
- copyFilesFromCache(cachedResult: CachedResult, outputs: Array<string>): void
45
+ getCacheSize(): number
46
+ copyFilesFromCache(cachedResult: CachedResult, outputs: Array<string>): number
46
47
  removeOldCacheRecords(): void
47
48
  checkCacheFsInSync(): boolean
48
49
  }
@@ -112,13 +113,14 @@ export interface CachedResult {
112
113
  code: number
113
114
  terminalOutput: string
114
115
  outputsPath: string
116
+ size?: number
115
117
  }
116
118
 
117
119
  export declare export function closeDbConnection(connection: ExternalObject<NxDbConnection>): void
118
120
 
119
121
  export declare export function connectToNxDb(cacheDir: string, nxVersion: string, dbName?: string | undefined | null): ExternalObject<NxDbConnection>
120
122
 
121
- export declare export function copy(src: string, dest: string): void
123
+ export declare export function copy(src: string, dest: string): number
122
124
 
123
125
  export interface DepsOutputsInput {
124
126
  dependentTasksOutputFiles: string
@@ -165,6 +167,8 @@ export declare export function findImports(projectFileMap: Record<string, Array<
165
167
 
166
168
  export declare export function getBinaryTarget(): string
167
169
 
170
+ export declare export function getDefaultMaxCacheSize(cachePath: string): number
171
+
168
172
  /**
169
173
  * Expands the given outputs into a list of existing files.
170
174
  * This is used when hashing outputs
@@ -379,6 +379,7 @@ module.exports.EventType = nativeBinding.EventType
379
379
  module.exports.expandOutputs = nativeBinding.expandOutputs
380
380
  module.exports.findImports = nativeBinding.findImports
381
381
  module.exports.getBinaryTarget = nativeBinding.getBinaryTarget
382
+ module.exports.getDefaultMaxCacheSize = nativeBinding.getDefaultMaxCacheSize
382
383
  module.exports.getFilesForOutputs = nativeBinding.getFilesForOutputs
383
384
  module.exports.getTransformableOutputs = nativeBinding.getTransformableOutputs
384
385
  module.exports.hashArray = nativeBinding.hashArray
Binary file
@@ -15,6 +15,7 @@ export declare function dbCacheEnabled(nxJson?: NxJsonConfiguration): boolean;
15
15
  export declare function getCache(options: DefaultTasksRunnerOptions): DbCache | Cache;
16
16
  export declare class DbCache {
17
17
  private readonly options;
18
+ private nxJson;
18
19
  private cache;
19
20
  private remoteCache;
20
21
  private remoteCachePromise;
@@ -25,9 +26,10 @@ export declare class DbCache {
25
26
  });
26
27
  init(): Promise<void>;
27
28
  get(task: Task): Promise<CachedResult | null>;
29
+ getUsedCacheSpace(): number;
28
30
  private applyRemoteCacheResults;
29
31
  put(task: Task, terminalOutput: string | null, outputs: string[], code: number): Promise<void>;
30
- copyFilesFromCache(_: string, cachedResult: CachedResult, outputs: string[]): Promise<void>;
32
+ copyFilesFromCache(_: string, cachedResult: CachedResult, outputs: string[]): Promise<number>;
31
33
  removeOldCacheRecords(): void;
32
34
  temporaryOutputPath(task: Task): string;
33
35
  private getRemoteCache;
@@ -66,3 +68,14 @@ export declare class Cache {
66
68
  private createCacheDir;
67
69
  private createTerminalOutputsDir;
68
70
  }
71
+ /**
72
+ * Converts a string representation of a max cache size to a number.
73
+ *
74
+ * e.g. '1GB' -> 1024 * 1024 * 1024
75
+ * '1MB' -> 1024 * 1024
76
+ * '1KB' -> 1024
77
+ *
78
+ * @param maxCacheSize Max cache size as specified in nx.json
79
+ */
80
+ export declare function parseMaxCacheSize(maxCacheSize: string | number): number | undefined;
81
+ export declare function formatCacheSize(maxCacheSize: number, decimals?: number): string;
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Cache = exports.DbCache = void 0;
4
4
  exports.dbCacheEnabled = dbCacheEnabled;
5
5
  exports.getCache = getCache;
6
+ exports.parseMaxCacheSize = parseMaxCacheSize;
7
+ exports.formatCacheSize = formatCacheSize;
6
8
  const workspace_root_1 = require("../utils/workspace-root");
7
9
  const path_1 = require("path");
8
10
  const perf_hooks_1 = require("perf_hooks");
@@ -68,7 +70,10 @@ function getCache(options) {
68
70
  class DbCache {
69
71
  constructor(options) {
70
72
  this.options = options;
71
- this.cache = new native_1.NxCache(workspace_root_1.workspaceRoot, cache_directory_1.cacheDir, (0, db_connection_1.getDbConnection)());
73
+ this.nxJson = (0, nx_json_1.readNxJson)();
74
+ this.cache = new native_1.NxCache(workspace_root_1.workspaceRoot, cache_directory_1.cacheDir, (0, db_connection_1.getDbConnection)(), undefined, this.nxJson.maxCacheSize !== undefined
75
+ ? parseMaxCacheSize(this.nxJson.maxCacheSize)
76
+ : (0, native_1.getDefaultMaxCacheSize)(cache_directory_1.cacheDir));
72
77
  this.isVerbose = process.env.NX_VERBOSE_LOGGING === 'true';
73
78
  }
74
79
  async init() {
@@ -91,7 +96,7 @@ class DbCache {
91
96
  // attempt remote cache
92
97
  const res = await this.remoteCache.retrieve(task.hash, this.cache.cacheDirectory);
93
98
  if (res) {
94
- this.applyRemoteCacheResults(task.hash, res);
99
+ this.applyRemoteCacheResults(task.hash, res, task.outputs);
95
100
  return {
96
101
  ...res,
97
102
  remote: true,
@@ -105,8 +110,11 @@ class DbCache {
105
110
  return null;
106
111
  }
107
112
  }
108
- applyRemoteCacheResults(hash, res) {
109
- return this.cache.applyRemoteCacheResults(hash, res);
113
+ getUsedCacheSpace() {
114
+ return this.cache.getCacheSize();
115
+ }
116
+ applyRemoteCacheResults(hash, res, outputs) {
117
+ return this.cache.applyRemoteCacheResults(hash, res, outputs);
110
118
  }
111
119
  async put(task, terminalOutput, outputs, code) {
112
120
  return tryAndRetry(async () => {
@@ -455,3 +463,54 @@ function tryAndRetry(fn) {
455
463
  };
456
464
  return _try();
457
465
  }
466
+ /**
467
+ * Converts a string representation of a max cache size to a number.
468
+ *
469
+ * e.g. '1GB' -> 1024 * 1024 * 1024
470
+ * '1MB' -> 1024 * 1024
471
+ * '1KB' -> 1024
472
+ *
473
+ * @param maxCacheSize Max cache size as specified in nx.json
474
+ */
475
+ function parseMaxCacheSize(maxCacheSize) {
476
+ if (maxCacheSize === null || maxCacheSize === undefined) {
477
+ return undefined;
478
+ }
479
+ let regexResult = maxCacheSize
480
+ // Covers folks who accidentally specify as a number rather than a string
481
+ .toString()
482
+ // Match a number followed by an optional unit (KB, MB, GB), with optional whitespace between the number and unit
483
+ .match(/^(?<size>[\d|.]+)\s?((?<unit>[KMG]?B)?)$/);
484
+ if (!regexResult) {
485
+ throw new Error(`Invalid max cache size specified in nx.json: ${maxCacheSize}. Must be a number followed by an optional unit (KB, MB, GB)`);
486
+ }
487
+ let sizeString = regexResult.groups.size;
488
+ let unit = regexResult.groups.unit;
489
+ if ([...sizeString].filter((c) => c === '.').length > 1) {
490
+ throw new Error(`Invalid max cache size specified in nx.json: ${maxCacheSize} (multiple decimal points in size)`);
491
+ }
492
+ let size = parseFloat(sizeString);
493
+ if (isNaN(size)) {
494
+ throw new Error(`Invalid max cache size specified in nx.json: ${maxCacheSize} (${sizeString} is not a number)`);
495
+ }
496
+ switch (unit) {
497
+ case 'KB':
498
+ return size * 1024;
499
+ case 'MB':
500
+ return size * 1024 * 1024;
501
+ case 'GB':
502
+ return size * 1024 * 1024 * 1024;
503
+ default:
504
+ return size;
505
+ }
506
+ }
507
+ function formatCacheSize(maxCacheSize, decimals = 2) {
508
+ const exponents = ['B', 'KB', 'MB', 'GB'];
509
+ let exponent = 0;
510
+ let size = maxCacheSize;
511
+ while (size >= 1024 && exponent < exponents.length - 1) {
512
+ size /= 1024;
513
+ exponent++;
514
+ }
515
+ return `${size.toFixed(decimals)} ${exponents[exponent]}`;
516
+ }
@@ -131,7 +131,12 @@ class TaskOrchestrator {
131
131
  if (!cachedResult || cachedResult.code !== 0)
132
132
  return null;
133
133
  const outputs = task.outputs;
134
- const shouldCopyOutputsFromCache = !!outputs.length &&
134
+ const shouldCopyOutputsFromCache =
135
+ // No output files to restore
136
+ !!outputs.length &&
137
+ // Remote caches are restored to output dirs when applied
138
+ !cachedResult.remote &&
139
+ // Output files have not been touched since last run
135
140
  (await this.shouldCopyOutputsFromCache(outputs, task.hash));
136
141
  if (shouldCopyOutputsFromCache) {
137
142
  await this.cache.copyFilesFromCache(task.hash, cachedResult, outputs);