Skip to content

Commit 2251d82

Browse files
committed
feat(@angular/cli): allow using Deno as package manager
1 parent f9de11d commit 2251d82

File tree

15 files changed

+81
-21
lines changed

15 files changed

+81
-21
lines changed

packages/angular/cli/lib/config/workspace-schema.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
"packageManager": {
4848
"description": "Specify which package manager tool to use.",
4949
"type": "string",
50-
"enum": ["npm", "yarn", "pnpm", "bun"]
50+
"enum": ["npm", "yarn", "pnpm", "bun", "deno"]
5151
},
5252
"warnings": {
5353
"description": "Control CLI specific console warnings",
@@ -101,7 +101,7 @@
101101
"packageManager": {
102102
"description": "Specify which package manager tool to use.",
103103
"type": "string",
104-
"enum": ["npm", "yarn", "pnpm", "bun"]
104+
"enum": ["npm", "yarn", "pnpm", "bun", "deno"]
105105
},
106106
"warnings": {
107107
"description": "Control CLI specific console warnings",

packages/angular/cli/src/commands/update/schematic/schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
"description": "The preferred package manager configuration files to use for registry settings.",
5858
"type": "string",
5959
"default": "npm",
60-
"enum": ["npm", "yarn", "pnpm", "bun"]
60+
"enum": ["npm", "yarn", "pnpm", "bun", "deno"]
6161
}
6262
},
6363
"required": []

packages/angular/cli/src/utilities/package-manager.ts

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const LOCKFILE_NAMES: Readonly<Record<PackageManager, string | readonly string[]
2323
[PackageManager.Pnpm]: 'pnpm-lock.yaml',
2424
[PackageManager.Bun]: ['bun.lockb', 'bun.lock'],
2525
[PackageManager.Npm]: 'package-lock.json',
26+
[PackageManager.Deno]: 'deno.lock',
2627
};
2728

2829
interface PackageManagerOptions {
@@ -166,6 +167,14 @@ export class PackageManagerUtils {
166167
prefix: '--cwd',
167168
noLockfile: '--no-save',
168169
};
170+
case PackageManager.Deno:
171+
return {
172+
saveDev: '--dev',
173+
install: 'add',
174+
installAll: 'install',
175+
prefix: '--root',
176+
noLockfile: '--no-lock',
177+
};
169178
default:
170179
return {
171180
saveDev: '--save-dev',
@@ -179,12 +188,12 @@ export class PackageManagerUtils {
179188

180189
private async run(
181190
args: string[],
182-
options: { cwd?: string; silent?: boolean } = {},
191+
options: { cwd?: string; silent?: boolean; } = {},
183192
): Promise<boolean> {
184193
const { cwd = process.cwd(), silent = false } = options;
185194

186195
return new Promise((resolve) => {
187-
const bufferedOutput: { stream: NodeJS.WriteStream; data: Buffer }[] = [];
196+
const bufferedOutput: { stream: NodeJS.WriteStream; data: Buffer; }[] = [];
188197

189198
const childProcess = spawn(`${this.name} ${args.join(' ')}`, {
190199
// Always pipe stderr to allow for failures to be reported
@@ -212,7 +221,8 @@ export class PackageManagerUtils {
212221
@memoize
213222
private getVersion(name: PackageManager): string | undefined {
214223
try {
215-
return execSync(`${name} --version`, {
224+
const versionArg = name !== PackageManager.Deno ? '--version' : '-v';
225+
const version = execSync(`${name} ${versionArg}`, {
216226
encoding: 'utf8',
217227
stdio: ['ignore', 'pipe', 'ignore'],
218228
env: {
@@ -222,6 +232,13 @@ export class PackageManagerUtils {
222232
NPM_CONFIG_UPDATE_NOTIFIER: 'false',
223233
},
224234
}).trim();
235+
236+
if (name === PackageManager.Deno) {
237+
// Deno CLI outputs "deno 2.4.4"
238+
return version.replace('deno ', '');
239+
}
240+
241+
return version;
225242
} catch {
226243
return undefined;
227244
}
@@ -239,14 +256,21 @@ export class PackageManagerUtils {
239256
const hasYarnLock = this.hasLockfile(PackageManager.Yarn, filesInRoot);
240257
const hasPnpmLock = this.hasLockfile(PackageManager.Pnpm, filesInRoot);
241258
const hasBunLock = this.hasLockfile(PackageManager.Bun, filesInRoot);
259+
const hasDenoLock = this.hasLockfile(PackageManager.Deno, filesInRoot);
242260

243261
// PERF NOTE: `this.getVersion` spawns the package a the child_process which can take around ~300ms at times.
244262
// Therefore, we should only call this method when needed. IE: don't call `this.getVersion(PackageManager.Pnpm)` unless truly needed.
245263
// The result of this method is not stored in a variable because it's memoized.
246264

247265
if (hasNpmLock) {
248266
// Has NPM lock file.
249-
if (!hasYarnLock && !hasPnpmLock && !hasBunLock && this.getVersion(PackageManager.Npm)) {
267+
if (
268+
!hasYarnLock &&
269+
!hasPnpmLock &&
270+
!hasBunLock &&
271+
!hasDenoLock &&
272+
this.getVersion(PackageManager.Npm)
273+
) {
250274
// Only NPM lock file and NPM binary is available.
251275
return PackageManager.Npm;
252276
}
@@ -261,6 +285,9 @@ export class PackageManagerUtils {
261285
} else if (hasBunLock && this.getVersion(PackageManager.Bun)) {
262286
// Bun lock file and Bun binary is available.
263287
return PackageManager.Bun;
288+
} else if (hasDenoLock && this.getVersion(PackageManager.Deno)) {
289+
// Deno lock file and Deno binary is available.
290+
return PackageManager.Deno;
264291
}
265292
}
266293

@@ -269,13 +296,16 @@ export class PackageManagerUtils {
269296
const hasYarn = !!this.getVersion(PackageManager.Yarn);
270297
const hasPnpm = !!this.getVersion(PackageManager.Pnpm);
271298
const hasBun = !!this.getVersion(PackageManager.Bun);
299+
const hasDeno = !!this.getVersion(PackageManager.Deno);
272300

273-
if (hasYarn && !hasPnpm && !hasBun) {
301+
if (hasYarn && !hasPnpm && !hasBun && !hasDeno) {
274302
return PackageManager.Yarn;
275-
} else if (hasPnpm && !hasYarn && !hasBun) {
303+
} else if (hasPnpm && !hasYarn && !hasBun && !hasDeno) {
276304
return PackageManager.Pnpm;
277-
} else if (hasBun && !hasYarn && !hasPnpm) {
305+
} else if (hasBun && !hasYarn && !hasPnpm && !hasDeno) {
278306
return PackageManager.Bun;
307+
} else if (hasDeno && !hasYarn && !hasPnpm && !hasBun) {
308+
return PackageManager.Deno;
279309
}
280310
}
281311

packages/angular/create/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,9 @@ pnpm create @angular [project-name] [...options]
2929
```
3030
bun create @angular [project-name] [...options]
3131
```
32+
33+
### deno
34+
35+
```
36+
deno init --npm @angular [project-name] [...options]
37+
```

packages/angular/create/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const hasPackageManagerArg = args.some((a) => a.startsWith('--package-manager'))
1717
if (!hasPackageManagerArg) {
1818
// Ex: yarn/1.22.18 npm/? node/v16.15.1 linux x64
1919
const packageManager = process.env['npm_config_user_agent']?.split('/')[0];
20-
if (packageManager && ['npm', 'pnpm', 'yarn', 'bun'].includes(packageManager)) {
20+
if (packageManager && ['npm', 'pnpm', 'yarn', 'bun', 'deno'].includes(packageManager)) {
2121
args.push('--package-manager', packageManager);
2222
}
2323
}

packages/angular_devkit/schematics/tasks/package-manager/executor.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ const packageManagers: { [name: string]: PackageManagerProfile } = {
3939
installPackage: 'add',
4040
},
4141
},
42+
'deno': {
43+
commands: {
44+
installAll: 'install',
45+
installPackage: 'add',
46+
},
47+
},
4248
'pnpm': {
4349
commands: {
4450
installAll: 'install',

packages/angular_devkit/schematics_cli/blank/schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"packageManager": {
1616
"description": "The package manager used to install dependencies.",
1717
"type": "string",
18-
"enum": ["npm", "yarn", "pnpm", "bun"],
18+
"enum": ["npm", "yarn", "pnpm", "bun", "deno"],
1919
"default": "npm"
2020
},
2121
"author": {

packages/angular_devkit/schematics_cli/schematic/schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"packageManager": {
1616
"description": "The package manager used to install dependencies.",
1717
"type": "string",
18-
"enum": ["npm", "yarn", "pnpm", "bun"],
18+
"enum": ["npm", "yarn", "pnpm", "bun", "deno"],
1919
"default": "npm"
2020
}
2121
},

packages/schematics/angular/ng-new/schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@
132132
"packageManager": {
133133
"description": "The package manager used to install dependencies.",
134134
"type": "string",
135-
"enum": ["npm", "yarn", "pnpm", "bun"]
135+
"enum": ["npm", "yarn", "pnpm", "bun", "deno"]
136136
},
137137
"standalone": {
138138
"description": "Creates an application based upon the standalone API, without NgModules.",

packages/schematics/angular/workspace/schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
"packageManager": {
4141
"description": "The package manager to use for installing dependencies.",
4242
"type": "string",
43-
"enum": ["npm", "yarn", "pnpm", "bun"],
43+
"enum": ["npm", "yarn", "pnpm", "bun", "deno"],
4444
"$default": {
4545
"$source": "packageManager"
4646
}

0 commit comments

Comments
 (0)