Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 64 additions & 8 deletions packages/angular/cli/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Use of this source code is governed by an MIT-style license that can be
# found in the LICENSE file at https://angular.dev/license

load("@aspect_rules_esbuild//esbuild:defs.bzl", "esbuild")
load("@aspect_rules_ts//ts:defs.bzl", "ts_config")
load("@npm//:defs.bzl", "npm_link_all_packages")
load("//tools:defaults.bzl", "jasmine_test", "npm_package", "ts_project")
load("//tools:ng_cli_schema_generator.bzl", "cli_json_schema")
Expand All @@ -14,6 +16,24 @@ package(default_visibility = ["//visibility:public"])

npm_link_all_packages()

ts_config(
name = "tsconfig-build",
src = "tsconfig-build.json",
deps = [
"//:build-tsconfig",
],
)

ts_config(
name = "tsconfig-test",
src = "tsconfig-test.json",
deps = [
":tsconfig-build",
"//:node_modules/@types/jasmine",
"//:node_modules/@types/node",
],
)

genrule(
name = "angular_best_practices",
srcs = [
Expand All @@ -25,19 +45,19 @@ genrule(
""",
)

RUNTIME_ASSETS = glob(
PACKAGE_ASSETS = glob(
include = [
"bin/**/*",
"src/**/*.md",
],
exclude = [
"lib/config/workspace-schema.json",
],
) + [
"//packages/angular/cli:lib/config/schema.json",
":angular_best_practices",
]

RUNTIME_ASSETS = PACKAGE_ASSETS + glob(["src/**/*.md"]) + [":angular_best_practices"]

ts_project(
name = "angular-cli",
srcs = glob(
Expand All @@ -54,6 +74,7 @@ ts_project(
"//packages/angular/cli:lib/config/workspace-schema.ts",
],
data = RUNTIME_ASSETS,
tsconfig = ":tsconfig-build",
deps = [
":node_modules/@angular-devkit/architect",
":node_modules/@angular-devkit/core",
Expand All @@ -77,6 +98,30 @@ ts_project(
],
)

esbuild(
name = "bundled_cli",
srcs = [
":angular-cli",
":angular_best_practices",
] + glob(["src/**/*.md"]),
config = {
"packages": "external",
"loader": {
".md": "text",
},
},
entry_points = [
"lib/cli/index.js",
"lib/init.js",
],
format = "esm",
output_dir = True,
platform = "node",
sourcemap = False,
splitting = True,
target = "node22",
)

CLI_SCHEMA_DATA = [
"//packages/angular/build:schemas",
"//packages/angular_devkit/build_angular:schemas",
Expand Down Expand Up @@ -109,6 +154,7 @@ ts_project(
"node_modules/**",
],
),
tsconfig = ":tsconfig-test",
deps = [
":angular-cli",
":node_modules/@angular-devkit/core",
Expand All @@ -124,7 +170,14 @@ ts_project(

jasmine_test(
name = "test",
data = [":angular-cli_test_lib"],
data = [
"package.json",
"test-esm-loader.mjs",
":angular-cli_test_lib",
],
node_options = [
"--import=./test-esm-loader.mjs",
],
)

genrule(
Expand All @@ -144,14 +197,17 @@ npm_package(
"//packages/angular_devkit/schematics:package.json",
"//packages/schematics/angular:package.json",
],
replace_prefixes = {
"bundled_cli/": "lib/",
},
stamp_files = [
"src/utilities/version.js",
"src/utilities/node-version.js",
"bin/version.js",
],
tags = ["release-package"],
deps = RUNTIME_ASSETS + [
deps = PACKAGE_ASSETS + [
":README.md",
":angular-cli",
":bundled_cli",
":index.d.ts",
":license",
],
)
2 changes: 1 addition & 1 deletion packages/angular/cli/bin/ng.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
'use strict';

const path = require('path');
const nodeUtils = require('../src/utilities/node-version');
const nodeUtils = require('./version');

// Error if the external CLI appears to be used inside a google3 context.
if (process.cwd().split(path.sep).includes('google3')) {
Expand Down
64 changes: 64 additions & 0 deletions packages/angular/cli/bin/version.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
'use strict';
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/

/**
* The supported Node.js version for the Angular CLI.
*/
var SUPPORTED_NODE_VERSIONS = '0.0.0-ENGINES-NODE';

/**
* The version of the Angular CLI.
*/
var VERSION = '0.0.0-PLACEHOLDER';

/**
* The supported Node.js versions.
*/
var supportedNodeVersions = SUPPORTED_NODE_VERSIONS.replace(/[\^~<>=]/g, '')
.split('||')
.map(function (v) {
return v.trim();
});

/**
* Checks if the current Node.js version is supported.
* @returns `true` if the current Node.js version is supported, `false` otherwise.
*/
function isNodeVersionSupported() {
if (SUPPORTED_NODE_VERSIONS.charAt(0) === '0') {
return true;
}

var parts = process.versions.node.split('.', 3).map(Number);
var processMajor = parts[0];
var processMinor = parts[1];
var processPatch = parts[2];

for (var i = 0; i < supportedNodeVersions.length; i++) {
var vParts = supportedNodeVersions[i].split('.', 3).map(Number);
var major = vParts[0];
var minor = vParts[1];
var patch = vParts[2];
if (
(major === processMajor && processMinor === minor && processPatch >= patch) ||
(major === processMajor && processMinor > minor)
) {
return true;
}
}

return false;
}

module.exports = {
VERSION: VERSION,
SUPPORTED_NODE_VERSIONS: SUPPORTED_NODE_VERSIONS,
supportedNodeVersions: supportedNodeVersions,
isNodeVersionSupported: isNodeVersionSupported,
};
19 changes: 19 additions & 0 deletions packages/angular/cli/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/

export declare class Version {
readonly full: string;
readonly major: string;
readonly minor: string;
readonly patch: string;
constructor(full: string);
}

export declare const VERSION: Version;

export default function (options: { cliArgs: string[] }): Promise<number>;
9 changes: 7 additions & 2 deletions packages/angular/cli/lib/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import { readFile } from 'node:fs/promises';
import { createRequire } from 'node:module';
import * as path from 'node:path';
import { pathToFileURL } from 'node:url';
import { SemVer, major } from 'semver';
import { disableVersionCheck } from '../src/utilities/environment-options';
import { VERSION } from '../src/utilities/version';
Expand Down Expand Up @@ -71,7 +72,7 @@ let forceExit = false;
// version of ng-cli you have installed in a local package.json
const cwdRequire = createRequire(process.cwd() + '/');
const projectLocalCli = cwdRequire.resolve('@angular/cli');
cli = await import(projectLocalCli);
cli = await import(pathToFileURL(projectLocalCli).href);

const globalVersion = new SemVer(VERSION.full);

Expand Down Expand Up @@ -150,7 +151,11 @@ let forceExit = false;
cli = await import('./cli');
}

if ('default' in cli) {
// Support both ESM and CommonJS local CLI packages. When importing older CommonJS
// packages with an `__esModule` default export, Node.js wraps the exports in an ESM
// namespace requiring the default export to be unwrapped multiple times.
let depth = 0;
while (typeof cli === 'object' && cli !== null && 'default' in cli && depth++ < 3) {
cli = cli['default'];
}

Expand Down
5 changes: 5 additions & 0 deletions packages/angular/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"version": "0.0.0-PLACEHOLDER",
"description": "CLI tool for Angular",
"main": "lib/cli/index.js",
"typings": "index.d.ts",
"type": "module",
Comment thread
clydin marked this conversation as resolved.
"bin": {
"ng": "bin/ng.js"
},
Expand All @@ -11,6 +13,9 @@
"angular-cli",
"Angular CLI"
],
"imports": {
"#version": "./bin/version.js"
},
"dependencies": {
"@angular-devkit/architect": "workspace:0.0.0-EXPERIMENTAL-PLACEHOLDER",
"@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER",
Expand Down
1 change: 0 additions & 1 deletion packages/angular/cli/src/command-builder/command-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { AngularWorkspace } from '../utilities/config';
import { memoize } from '../utilities/memoize';
import { CommandContext, CommandScope, Options, OtherOptions } from './definitions';
import { Option, addSchemaOptionsToCommand } from './utilities/json-schema';
import '../utilities/markdown-loader';

export { CommandScope };
export type { CommandContext, Options, OtherOptions };
Expand Down
2 changes: 1 addition & 1 deletion packages/angular/cli/src/command-builder/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

import { logging } from '@angular-devkit/core';
import type { Argv, CamelCaseKey } from 'yargs';
import type { Argv, CamelCaseKey } from 'yargs' with { 'resolution-mode': 'require' };
import type { PackageManager } from '../package-managers/package-manager';
import { AngularWorkspace } from '../utilities/config';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -420,10 +420,10 @@ export abstract class SchematicsCommandModule
return workspace
? // Workspace
collectionName === DEFAULT_SCHEMATICS_COLLECTION
? // Favor __dirname for @schematics/angular to use the build-in version
[__dirname, process.cwd(), root]
: [process.cwd(), root, __dirname]
? // Favor import.meta.dirname for @schematics/angular to use the build-in version
[import.meta.dirname, process.cwd(), root]
: [process.cwd(), root, import.meta.dirname]
: // Global
[__dirname, process.cwd()];
[import.meta.dirname, process.cwd()];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

import { JsonObject, schema } from '@angular-devkit/core';
import type { Argv } from 'yargs';
import yargs from 'yargs';

import { Option, addSchemaOptionsToCommand, parseJsonSchemaToOptions } from './json-schema';
Expand All @@ -20,7 +21,7 @@ describe('parseJsonSchemaToOptions', () => {
return localYargs.parseAsync(args);
};

let localYargs: yargs.Argv<unknown>;
let localYargs: Argv<unknown>;
let options: Option[];

beforeAll(async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export class SchematicEngineHost extends NodeModulesEngineHost {
// Mimic behavior of ExportStringRef class used in default behavior
const fullPath = path[0] === '.' ? resolve(parentPath ?? process.cwd(), path) : path;

const referenceRequire = createRequire(__filename);
const referenceRequire = createRequire(import.meta.url);
const schematicFile = referenceRequire.resolve(fullPath, { paths: [parentPath] });

if (shouldWrapSchematic(schematicFile, collectionDescription?.encapsulation)) {
Expand Down Expand Up @@ -139,7 +139,7 @@ function wrap(
moduleCache: Map<string, unknown>,
exportName?: string,
): () => unknown {
const hostRequire = createRequire(__filename);
const hostRequire = createRequire(import.meta.url);
const schematicRequire = createRequire(schematicFile);

const customRequire = function (id: string) {
Expand Down
11 changes: 4 additions & 7 deletions packages/angular/cli/src/commands/mcp/resources/instructions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
*/

import type { McpServer } from '@modelcontextprotocol/server';
import { readFile } from 'node:fs/promises';
import { join } from 'node:path';
import bestPracticesText from './best-practices.md';

export function registerInstructionsResource(server: McpServer): void {
server.registerResource(
Expand All @@ -23,10 +22,8 @@ export function registerInstructionsResource(server: McpServer): void {
' typed forms, modern control flow syntax, and other current conventions.',
mimeType: 'text/markdown',
},
async () => {
const text = await readFile(join(__dirname, 'best-practices.md'), 'utf-8');

return { contents: [{ uri: 'instructions://best-practices', text }] };
},
async () => ({
contents: [{ uri: 'instructions://best-practices', text: bestPracticesText }],
}),
);
}
Loading
Loading