diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0642e0b7ff65..4dabb694f83e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -301,15 +301,3 @@ changes to be accepted, the CLA must be signed. It's a quick process, we promise [js-style-guide]: https://google.github.io/styleguide/jsguide.html [stackoverflow]: https://stackoverflow.com/questions/tagged/angular-devkit -## Updating the Public API -Our Public API surface is tracked using golden files. - -You check all golden files by running: -```bash -pnpm public-api:check -``` - -If you modified the public API, the test will fail. To update the golden files you need to run: -```bash -pnpm public-api:update -``` diff --git a/goldens/public-api/manage.js b/goldens/public-api/manage.js deleted file mode 100644 index 569f2a6bd1e3..000000000000 --- a/goldens/public-api/manage.js +++ /dev/null @@ -1,54 +0,0 @@ -const {exec} = require('shelljs'); -const {Parser: parser} = require('yargs/helpers'); - -// Remove all command line flags from the arguments. -const argv = parser(process.argv.slice(2)); -// The command the user would like to run, either 'accept' or 'test' -const USER_COMMAND = argv._[0]; -// The shell command to query for all Public API guard tests. -const BAZEL_PUBLIC_API_TARGET_QUERY_CMD = - `pnpm -s bazel query --output label 'kind(nodejs_test, ...) intersect attr("tags", "api_guard", ...)'` -// Bazel targets for testing Public API goldens -process.stdout.write('Gathering all Public API targets'); -const ALL_PUBLIC_API_TESTS = exec(BAZEL_PUBLIC_API_TARGET_QUERY_CMD, {silent: true}) - .trim() - .split('\n') - .map(test => test.trim()); -process.stdout.clearLine(); -process.stdout.cursorTo(0); -// Bazel targets for generating Public API goldens -const ALL_PUBLIC_API_ACCEPTS = ALL_PUBLIC_API_TESTS.map(test => `${test}.accept`); - -/** - * Run the provided bazel commands on each provided target individually. - */ -function runBazelCommandOnTargets(command, targets, present) { - for (const target of targets) { - process.stdout.write(`${present}: ${target}`); - const commandResult = exec(`pnpm -s bazel ${command} ${target}`, {silent: true}); - process.stdout.clearLine(); - process.stdout.cursorTo(0); - if (commandResult.code) { - console.error(`Failed ${command}: ${target}`); - console.group(); - console.error(commandResult.stdout || commandResult.stderr); - console.groupEnd(); - } else { - console.log(`Successful ${command}: ${target}`); - } - } -} - -switch (USER_COMMAND) { - case 'accept': - runBazelCommandOnTargets('run', ALL_PUBLIC_API_ACCEPTS, 'Running'); - break; - case 'test': - runBazelCommandOnTargets('test', ALL_PUBLIC_API_TESTS, 'Testing'); - break; - default: - console.warn('Invalid command provided.'); - console.warn(); - console.warn(`Run this script with either "accept" and "test"`); - break; -} diff --git a/package.json b/package.json index 114d23740dc1..0a7e561dd329 100644 --- a/package.json +++ b/package.json @@ -21,9 +21,7 @@ "postinstall": "pnpm -s webdriver-update && husky", "//webdriver-update-README": "ChromeDriver version must match Puppeteer Chromium version, see https://github.com/GoogleChrome/puppeteer/releases http://chromedriver.chromium.org/downloads", "webdriver-update": "webdriver-manager update --standalone false --gecko false --versions.chrome 106.0.5249.21", - "public-api:check": "node goldens/public-api/manage.js test", "ng-dev": "node --no-warnings=ExperimentalWarning --loader ts-node/esm/transpile-only node_modules/@angular/ng-dev/bundles/cli.mjs", - "public-api:update": "node goldens/public-api/manage.js accept", "ts-circular-deps": "pnpm -s ng-dev ts-circular-deps --config ./scripts/circular-deps-test.conf.mjs", "check-tooling-setup": "tsc --project .ng-dev/tsconfig.json", "diff-release-package": "node --no-warnings=ExperimentalWarning --loader ts-node/esm/transpile-only scripts/diff-release-package.mts" @@ -89,7 +87,6 @@ "@types/progress": "^2.0.3", "@types/resolve": "^1.17.1", "@types/semver": "^7.3.12", - "@types/shelljs": "^0.8.11", "@types/watchpack": "^2.4.4", "@types/yargs": "^17.0.20", "@types/yargs-parser": "^21.0.0", @@ -134,7 +131,6 @@ "rollup-plugin-dts": "6.2.3", "rollup-plugin-sourcemaps2": "0.5.4", "semver": "7.7.3", - "shelljs": "^0.10.0", "source-map-support": "0.5.21", "tar": "^7.0.0", "ts-node": "^10.9.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3b97a55c8d64..61a35355c7a8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -148,9 +148,6 @@ importers: '@types/semver': specifier: ^7.3.12 version: 7.7.1 - '@types/shelljs': - specifier: ^0.8.11 - version: 0.8.17 '@types/watchpack': specifier: ^2.4.4 version: 2.4.4 @@ -283,9 +280,6 @@ importers: semver: specifier: 7.7.3 version: 7.7.3 - shelljs: - specifier: ^0.10.0 - version: 0.10.0 source-map-support: specifier: 0.5.21 version: 0.5.21 @@ -3633,9 +3627,6 @@ packages: '@types/serve-static@1.15.9': resolution: {integrity: sha512-dOTIuqpWLyl3BBXU3maNQsS4A3zuuoYRNIvYSxxhebPfXg2mzWQEPne/nlJ37yOse6uGgR386uTpdsx4D0QZWA==} - '@types/shelljs@0.8.17': - resolution: {integrity: sha512-IDksKYmQA2W9MkQjiyptbMmcQx+8+Ol6b7h6dPU5S05JyiQDSb/nZKnrMrZqGwgV6VkVdl6/SPCKPDlMRvqECg==} - '@types/sockjs@0.3.36': resolution: {integrity: sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==} @@ -8092,10 +8083,6 @@ packages: resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} engines: {node: '>= 0.4'} - shelljs@0.10.0: - resolution: {integrity: sha512-Jex+xw5Mg2qMZL3qnzXIfaxEtBaC4n7xifqaqtrZDdlheR70OGkydrPJWT0V1cA1k3nanC86x9FwAmQl6w3Klw==} - engines: {node: '>=18'} - side-channel-list@1.0.0: resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} engines: {node: '>= 0.4'} @@ -12225,11 +12212,6 @@ snapshots: '@types/node': 22.18.11 '@types/send': 0.17.5 - '@types/shelljs@0.8.17': - dependencies: - '@types/node': 22.18.11 - glob: 11.0.3 - '@types/sockjs@0.3.36': dependencies: '@types/node': 22.18.11 @@ -17652,11 +17634,6 @@ snapshots: shell-quote@1.8.3: {} - shelljs@0.10.0: - dependencies: - execa: 5.1.1 - fast-glob: 3.3.3 - side-channel-list@1.0.0: dependencies: es-errors: 1.3.0 diff --git a/scripts/build-packages-dist.mts b/scripts/build-packages-dist.mts index 441a3a2a021a..9a4fa1c764b9 100644 --- a/scripts/build-packages-dist.mts +++ b/scripts/build-packages-dist.mts @@ -14,9 +14,17 @@ import { BuiltPackage } from '@angular/ng-dev'; import { execSync } from 'node:child_process'; -import { chmodSync, copyFileSync, mkdirSync, rmSync } from 'node:fs'; +import { + chmodSync, + copyFileSync, + cpSync, + existsSync, + lstatSync, + mkdirSync, + readdirSync, + rmSync, +} from 'node:fs'; import { dirname, join } from 'node:path'; -import sh from 'shelljs'; /** Name of the Bazel tag that will be used to find release package targets. */ const releaseTargetTag = 'release-package'; @@ -89,14 +97,15 @@ function buildReleasePackages( // Archive output is created by the npm_package_archive target const archiveOutputPath = directoryOutputPath + '_archive.tgz'; - if (sh.test('-d', directoryOutputPath)) { - sh.chmod('-R', 'u+w', directoryOutputPath); - sh.rm('-rf', directoryOutputPath); + if (existsSync(directoryOutputPath)) { + chmodRecursiveSync(directoryOutputPath, '0755'); + rmSync(directoryOutputPath, { recursive: true, force: true }); } - try { + + if (existsSync(archiveOutputPath)) { chmodSync(archiveOutputPath, '0755'); rmSync(archiveOutputPath, { force: true }); - } catch {} + } }); // Build both the npm_package and npm_package_archive targets for each package @@ -123,8 +132,8 @@ function buildReleasePackages( mkdirSync(dirname(targetFolder), { recursive: true }); // Copy package contents to target directory - sh.cp('-R', directoryOutputPath, targetFolder); - sh.chmod('-R', 'u+w', targetFolder); + cpSync(directoryOutputPath, targetFolder, { recursive: true }); + chmodRecursiveSync(targetFolder, '0755'); // Copy archive of package to target directory const archiveTargetPath = join(distPath, `${pkgName.replace('/', '_')}.tgz`); @@ -176,3 +185,25 @@ function exec(command: string, captureStdout?: true) { return stdout.toString().trim(); } } + +/** + * Recursively changes the permissions (mode) of a directory and all its contents (files and subdirectories). + * @param startPath The starting directory path. + * @param mode The new permissions mode (e.g., 0755). + */ +function chmodRecursiveSync(startPath: string, mode: string): void { + chmodSync(startPath, mode); + + const files = readdirSync(startPath); + + for (const file of files) { + const filePath = join(startPath, file); + const stat = lstatSync(filePath); + + if (stat.isDirectory()) { + chmodRecursiveSync(filePath, mode); + } else { + chmodSync(filePath, mode); + } + } +} diff --git a/scripts/diff-release-package.mts b/scripts/diff-release-package.mts index 2bf01aded3cd..8ec6b6df48db 100644 --- a/scripts/diff-release-package.mts +++ b/scripts/diff-release-package.mts @@ -18,10 +18,9 @@ import { GitClient } from '@angular/ng-dev'; import childProcess from 'node:child_process'; -import fs from 'node:fs'; +import fs, { chmodSync, lstatSync, readdirSync } from 'node:fs'; import os from 'node:os'; -import path from 'node:path'; -import sh from 'shelljs'; +import path, { join } from 'node:path'; // Do not remove `.git` as we use Git for comparisons later. // Also preserve `uniqueId` as it's irrelevant for the diff and not included via Bazel. @@ -130,6 +129,28 @@ async function deleteDir(dirPath: string) { } // Needed as Bazel artifacts are readonly and cannot be deleted otherwise. - sh.chmod('-R', 'u+w', dirPath); + chmodRecursiveSync(dirPath, '0755'); await fs.promises.rm(dirPath, { recursive: true, force: true, maxRetries: 3 }); } + +/** + * Recursively changes the permissions (mode) of a directory and all its contents (files and subdirectories). + * @param startPath The starting directory path. + * @param mode The new permissions mode (e.g., 0755). + */ +function chmodRecursiveSync(startPath: string, mode: string): void { + chmodSync(startPath, mode); + + const files = readdirSync(startPath); + + for (const file of files) { + const filePath = join(startPath, file); + const stat = lstatSync(filePath); + + if (stat.isDirectory()) { + chmodRecursiveSync(filePath, mode); + } else { + chmodSync(filePath, mode); + } + } +} diff --git a/scripts/templates/contributing.ejs b/scripts/templates/contributing.ejs index b5bb997911ce..745d6d3500d2 100644 --- a/scripts/templates/contributing.ejs +++ b/scripts/templates/contributing.ejs @@ -291,15 +291,3 @@ changes to be accepted, the CLA must be signed. It's a quick process, we promise [js-style-guide]: https://google.github.io/styleguide/jsguide.html [stackoverflow]: https://stackoverflow.com/questions/tagged/angular-devkit -## Updating the Public API -Our Public API surface is tracked using golden files. - -You check all golden files by running: -```bash -pnpm public-api:check -``` - -If you modified the public API, the test will fail. To update the golden files you need to run: -```bash -pnpm public-api:update -```