8
8
9
9
import { isJsonObject , json } from '@angular-devkit/core' ;
10
10
import { execSync , spawn } from 'node:child_process' ;
11
- import { existsSync , promises as fs , realpathSync , rmSync } from 'node:fs' ;
11
+ import { promises as fs , readdirSync , realpathSync , rmSync } from 'node:fs' ;
12
12
import { tmpdir } from 'node:os' ;
13
13
import { join } from 'node:path' ;
14
14
import { PackageManager } from '../../lib/config/workspace-schema' ;
15
15
import { AngularWorkspace , getProjectByCwd } from './config' ;
16
16
import { memoize } from './memoize' ;
17
17
18
+ /**
19
+ * A map of package managers to their corresponding lockfile names.
20
+ */
21
+ const LOCKFILE_NAMES : Readonly < Record < PackageManager , string | readonly string [ ] > > = {
22
+ [ PackageManager . Yarn ] : 'yarn.lock' ,
23
+ [ PackageManager . Pnpm ] : 'pnpm-lock.yaml' ,
24
+ [ PackageManager . Bun ] : [ 'bun.lockb' , 'bun.lock' ] ,
25
+ [ PackageManager . Npm ] : 'package-lock.json' ,
26
+ } ;
27
+
18
28
interface PackageManagerOptions {
19
29
saveDev : string ;
20
30
install : string ;
@@ -29,7 +39,13 @@ export interface PackageManagerUtilsContext {
29
39
root : string ;
30
40
}
31
41
42
+ /**
43
+ * Utilities for interacting with various package managers.
44
+ */
32
45
export class PackageManagerUtils {
46
+ /**
47
+ * @param context The context for the package manager utilities, including workspace and global configuration.
48
+ */
33
49
constructor ( private readonly context : PackageManagerUtilsContext ) { }
34
50
35
51
/** Get the package manager name. */
@@ -216,10 +232,12 @@ export class PackageManagerUtils {
216
232
return packageManager ;
217
233
}
218
234
219
- const hasNpmLock = this . hasLockfile ( PackageManager . Npm ) ;
220
- const hasYarnLock = this . hasLockfile ( PackageManager . Yarn ) ;
221
- const hasPnpmLock = this . hasLockfile ( PackageManager . Pnpm ) ;
222
- const hasBunLock = this . hasLockfile ( PackageManager . Bun ) ;
235
+ const filesInRoot = readdirSync ( this . context . root ) ;
236
+
237
+ const hasNpmLock = this . hasLockfile ( PackageManager . Npm , filesInRoot ) ;
238
+ const hasYarnLock = this . hasLockfile ( PackageManager . Yarn , filesInRoot ) ;
239
+ const hasPnpmLock = this . hasLockfile ( PackageManager . Pnpm , filesInRoot ) ;
240
+ const hasBunLock = this . hasLockfile ( PackageManager . Bun , filesInRoot ) ;
223
241
224
242
// PERF NOTE: `this.getVersion` spawns the package a the child_process which can take around ~300ms at times.
225
243
// Therefore, we should only call this method when needed. IE: don't call `this.getVersion(PackageManager.Pnpm)` unless truly needed.
@@ -265,25 +283,18 @@ export class PackageManagerUtils {
265
283
return PackageManager . Npm ;
266
284
}
267
285
268
- private hasLockfile ( packageManager : PackageManager ) : boolean {
269
- let lockfileName : string ;
270
- switch ( packageManager ) {
271
- case PackageManager . Yarn :
272
- lockfileName = 'yarn.lock' ;
273
- break ;
274
- case PackageManager . Pnpm :
275
- lockfileName = 'pnpm-lock.yaml' ;
276
- break ;
277
- case PackageManager . Bun :
278
- lockfileName = 'bun.lockb' ;
279
- break ;
280
- case PackageManager . Npm :
281
- default :
282
- lockfileName = 'package-lock.json' ;
283
- break ;
284
- }
285
-
286
- return existsSync ( join ( this . context . root , lockfileName ) ) ;
286
+ /**
287
+ * Checks if a lockfile for a specific package manager exists in the root directory.
288
+ * @param packageManager The package manager to check for.
289
+ * @param filesInRoot An array of file names in the root directory.
290
+ * @returns True if the lockfile exists, false otherwise.
291
+ */
292
+ private hasLockfile ( packageManager : PackageManager , filesInRoot : string [ ] ) : boolean {
293
+ const lockfiles = LOCKFILE_NAMES [ packageManager ] ;
294
+
295
+ return typeof lockfiles === 'string'
296
+ ? filesInRoot . includes ( lockfiles )
297
+ : lockfiles . some ( ( lockfile ) => filesInRoot . includes ( lockfile ) ) ;
287
298
}
288
299
289
300
private getConfiguredPackageManager ( ) : PackageManager | undefined {
0 commit comments