diff --git a/tools/eslint-to-code-pushup.mjs b/tools/eslint-to-code-pushup.mjs deleted file mode 100644 index 43d2115d9..000000000 --- a/tools/eslint-to-code-pushup.mjs +++ /dev/null @@ -1,175 +0,0 @@ -import { - createProjectGraphAsync, - readProjectsConfigurationFromProjectGraph, -} from '@nx/devkit'; -import { ESLint } from 'eslint'; -import minimatch from 'minimatch'; -import fs from 'node:fs/promises'; -import path from 'node:path'; - -// replace these patterns as needed -const TEST_FILE_PATTERNS = [ - '*.spec.ts', - '*.test.ts', - '**/test/**/*', - '**/mock/**/*', - '**/mocks/**/*', - '*.cy.ts', - '*.stories.ts', -]; - -const graph = await createProjectGraphAsync({ exitOnError: true }); -const projects = Object.values( - readProjectsConfigurationFromProjectGraph(graph).projects, -) - .filter(project => 'lint' in (project.targets ?? {})) - .sort((a, b) => a.root.localeCompare(b.root)); - -for (let i = 0; i < projects.length; i++) { - const project = projects[i]; - - /** @type {import('@nx/eslint/src/executors/lint/schema').Schema} */ - const options = project.targets.lint.options; - - const eslintrc = options.eslintConfig ?? `${project.root}/.eslintrc.json`; - const patterns = options.lintFilePatterns ?? project.root; - - console.info( - `Processing Nx ${project.projectType ?? 'project'} "${project.name}" (${ - i + 1 - }/${projects.length}) ...`, - ); - - const eslint = new ESLint({ - overrideConfigFile: eslintrc, - useEslintrc: false, - errorOnUnmatchedPattern: false, - resolvePluginsRelativeTo: options.resolvePluginsRelativeTo ?? undefined, - ignorePath: options.ignorePath ?? undefined, - rulePaths: options.rulesdir ?? [], - }); - - const results = await eslint.lintFiles(patterns); - - /** @type {Set} */ - const failingRules = new Set(); - /** @type {Set} */ - const failingRulesTestsOnly = new Set(); - /** @type {Map} */ - const errorCounts = new Map(); - /** @type {Map} */ - const warningCounts = new Map(); - - for (const result of results) { - const isTestFile = TEST_FILE_PATTERNS.some(pattern => - minimatch(result.filePath, pattern), - ); - for (const { ruleId, severity } of result.messages) { - if (isTestFile) { - if (!failingRules.has(ruleId)) { - failingRulesTestsOnly.add(ruleId); - } - } else { - failingRules.add(ruleId); - failingRulesTestsOnly.delete(ruleId); - } - if (severity === 1) { - warningCounts.set(ruleId, (warningCounts.get(ruleId) ?? 0) + 1); - } else { - errorCounts.set(ruleId, (errorCounts.get(ruleId) ?? 0) + 1); - } - } - } - - /** @param {string} ruleId */ - const formatCounts = ruleId => - [ - { kind: 'error', count: errorCounts.get(ruleId) }, - { kind: 'warning', count: warningCounts.get(ruleId) }, - ] - .filter(({ count }) => count > 0) - .map(({ kind, count }) => - count === 1 ? `1 ${kind}` : `${count} ${kind}s`, - ) - .join(', '); - - if (failingRules.size > 0) { - console.info(`• ${failingRules.size} rules need to be disabled`); - failingRules.forEach(ruleId => { - console.info(` - ${ruleId} (${formatCounts(ruleId)})`); - }); - } - if (failingRulesTestsOnly.size > 0) { - console.info( - `• ${failingRulesTestsOnly.size} rules need to be disabled only for test files`, - ); - failingRulesTestsOnly.forEach(ruleId => { - console.info(` - ${ruleId} (${formatCounts(ruleId)})`); - }); - } - - if (failingRules.size === 0 && failingRulesTestsOnly.size === 0) { - console.info('• no rules need to be disabled, nothing to do here\n'); - continue; - } - - const cpEslintrc = - 'code-pushup.' + path.basename(eslintrc).replace(/^\./, ''); - - /** @param {Set} rules */ - const formatRules = (rules, indentLevel = 2) => - Array.from(rules.values()) - .sort((a, b) => { - if (a.includes('/') !== b.includes('/')) { - return a.includes('/') ? 1 : -1; - } - return a.localeCompare(b); - }) - .map( - (ruleId, i, arr) => - ' '.repeat(indentLevel) + - `"${ruleId}": "off"${ - i === arr.length - 1 ? '' : ',' - } // ${formatCounts(ruleId)}`, - ) - .join('\n') - .replace(/,$/, ''); - - /** @type {import('eslint').Linter.Config} */ - const config = `{ - "extends": ["./${cpEslintrc}"], - // temporarily disable failing rules so \`nx lint\` passes - // number of errors/warnings per rule recorded at ${new Date().toString()} - "rules": { -${formatRules(failingRules)} - } - ${ - !failingRulesTestsOnly.size - ? '' - : `, - "overrides": [ - { - "files": ${JSON.stringify(TEST_FILE_PATTERNS)}, - "rules": { -${formatRules(failingRulesTestsOnly, 4)} - } - } - ]` - } -}`; - - const content = /\.c?[jt]s$/.test(eslintrc) - ? `module.exports = ${config}` - : config; - - const cpEslintrcPath = path.join(project.root, cpEslintrc); - await fs.copyFile(eslintrc, cpEslintrcPath); - console.info(`• copied ${eslintrc} to ${cpEslintrcPath}`); - - await fs.writeFile(eslintrc, content); - console.info( - `• replaced ${eslintrc} to extend ${cpEslintrc} and disable failing rules\n`, - ); -} - -process.exit(0); diff --git a/tools/eslint.config.js b/tools/eslint.config.js deleted file mode 100644 index 2ac01fcbb..000000000 --- a/tools/eslint.config.js +++ /dev/null @@ -1,12 +0,0 @@ -import tseslint from 'typescript-eslint'; -import baseConfig from '../eslint.config.js'; - -export default tseslint.config(...baseConfig, { - files: ['**/*.ts'], - parserOptions: { - project: ['tools/tsconfig.tools.json'], - }, - rules: { - '@nx/enforce-module-boundaries': 'off', - }, -}); diff --git a/tools/scripts/publish.mjs b/tools/scripts/publish.mjs deleted file mode 100644 index 79c31e3d3..000000000 --- a/tools/scripts/publish.mjs +++ /dev/null @@ -1,59 +0,0 @@ -/** - * This is a minimal script to publish your package to "npm". - * This is meant to be used as-is or customize as you see fit. - * - * This script is executed on "dist/path/to/library" as "cwd" by default. - * - * You might need to authenticate with NPM before running this script. - */ -import devkit from '@nx/devkit'; -import { execSync } from 'child_process'; -import { readFileSync, writeFileSync } from 'fs'; - -const { readCachedProjectGraph } = devkit; - -function invariant(condition, message) { - if (!condition) { - console.error(message); - process.exit(1); - } -} - -// Executing publish script: node path/to/publish.mjs {name} --version {version} --tag {tag} -// Default "tag" to "next" so we won't publish the "latest" tag by accident. -const [, , name, version, tag = 'next'] = process.argv; - -// A simple SemVer validation to validate the version -const validVersion = /^\d+\.\d+\.\d+(-\w+\.\d+)?/; -invariant( - version && validVersion.test(version), - `No version provided or version did not match Semantic Versioning, expected: #.#.#-tag.# or #.#.#, got ${version}.`, -); - -const graph = readCachedProjectGraph(); -const project = graph.nodes[name]; - -invariant( - project, - `Could not find project "${name}" in the workspace. Is the project.json configured correctly?`, -); - -const outputPath = project.data?.targets?.build?.options?.outputPath; -invariant( - outputPath, - `Could not find "build.options.outputPath" of project "${name}". Is project.json configured correctly?`, -); - -process.chdir(outputPath); - -// Updating the version in "package.json" before publishing -try { - const json = JSON.parse(readFileSync(`package.json`).toString()); - json.version = version; - writeFileSync(`package.json`, JSON.stringify(json, null, 2)); -} catch { - console.error('Error reading package.json file from library build output.'); -} - -// Execute "npm publish" to publish -execSync(`npm publish --access public --tag ${tag}`); diff --git a/tools/src/constants.ts b/tools/src/constants.ts deleted file mode 100644 index b2192fbc2..000000000 --- a/tools/src/constants.ts +++ /dev/null @@ -1 +0,0 @@ -export const TOOLS_TSCONFIG_PATH = 'tools/tsconfig.tools.json'; diff --git a/tools/src/debug/README.md b/tools/src/debug/README.md deleted file mode 100644 index 4a70a9270..000000000 --- a/tools/src/debug/README.md +++ /dev/null @@ -1,142 +0,0 @@ -# DEBUG Nx Plugin - -A plugin that provides a set of tools to debug your Nx workspace. - -## Usage - -Register the plugin in your `nx.json` - -```jsonc -// nx.json -{ - //... - "plugins": ["tools/src/debug/debug.plugin.ts"], -} -``` - -### Options - -You can configure the plugin by providing options object in addition to the plugin path - -**Options:** - -| Name | Type | Default | Description | -| ---------- | -------- | --------------------------- | ------------------------- | -| `tsconfig` | `string` | `tools/tsconfig.tools.json` | The tsconfig file to use. | - -Example: - -```jsonc -// nx.json -{ - //... - "plugins": [ - { - "plugin": "tools/src/debug/debug.plugin.ts", - "options": { - "tsconfig": "tools/tsconfig.tools.json", - }, - }, - ], -} -``` - -### Targets - -#### `list-process` - -Lists all the processes running in the workspace. - -Options: - -| Name | Type | Default | Description | -| --------------- | -------- | ----------- | ---------------------------- | -| `pidFilter` | `number` | `undefined` | Filter processes by PID. | -| `commandFilter` | `string` | `undefined` | Filter processes by command. | -| `slice` | `number` | `undefined` | Slice the list of processes. | - -Example: - -- `nx run :list-process` -- `nx run :list-process --pidFilter=1234` -- `nx run :list-process --commandFilter=verdaccio` -- `nx run :list-process --commandFilter=verdaccio --pidFilter=1234` -- `nx run :list-process --commandFilter=verdaccio --slice=5` - -#### `kill-process` - -Kills a process by its PID or filter - -Options: - -| Name | Type | Default | Description | -| --------------- | -------- | ----------- | ---------------------------- | -| `pidFilter` | `number` | `undefined` | Filter processes by PID. | -| `commandFilter` | `string` | `undefined` | Filter processes by command. | - -Example: - -- `nx run :kill-process --pidFilter=1234` -- `nx run :kill-process --commandFilter=verdaccio` - -## Scripts - -### `list-process.ts` - -Lists all the processes running in the workspace. - -Options: - -| Name | Type | Default | Description | -| --------------- | -------- | ----------- | ---------------------------- | -| `pidFilter` | `number` | `undefined` | Filter processes by PID. | -| `commandFilter` | `string` | `undefined` | Filter processes by command. | -| `slice` | `number` | `undefined` | Slice the list of processes. | - -Example: - -- `tsx --tsconfig=tools/tsconfig.tools.json tools/src/debug/bin/list-process.ts` -- `tsx --tsconfig=tools/tsconfig.tools.json tools/src/debug/bin/list-process.ts --pidFilter=1234` -- `tsx --tsconfig=tools/tsconfig.tools.json tools/src/debug/bin/list-process.ts --commandFilter=verdaccio` - -### `kill-process.ts` - -Kills a process by its PID or command string. - -Options: - -| Name | Type | Default | Description | -| --------------- | --------- | ----------- | ---------------------------- | -| `pidFilter` | `number` | `undefined` | Filter processes by PID. | -| `commandFilter` | `string` | `undefined` | Filter processes by command. | -| `slice` | `number` | `undefined` | Slice the list of processes. | -| `verbose` | `boolean` | `undefined` | Log the process to kill. | - -Example: - -- `tsx --tsconfig=tools/tsconfig.tools.json tools/src/debug/bin/kill-process.ts --pidFilter=1234` -- `tsx --tsconfig=tools/tsconfig.tools.json tools/src/debug/bin/kill-process.ts --commandFilter=verdaccio --pidFilter=1234` -- `tsx --tsconfig=tools/tsconfig.tools.json tools/src/debug/bin/kill-process.ts --commandFilter=verdaccio --pidFilter=1234 --verbose` - -### `clean-npmrc.ts` - -Cleans the `.npmrc` file in the workspace. - -Options: - -| Name | Type | Default | Description | -| ------------ | ---------------------- | ------- | --------------------------------------------- | -| `userconfig` | `string` | none | The path to the `.npmrc` file. | -| `entryMatch` | `string` \| `string[]` | none | The entries to remove from the `.npmrc` file. | - -Example: - -- `tsx --tsconfig=tools/tsconfig.tools.json tools/src/debug/bin/clean-npmrc.ts --entryMatch=secretVerddacioToken` -- `tsx --tsconfig=tools/tsconfig.tools.json tools/src/debug/bin/clean-npmrc.ts --userconfig=.npmrc --entryMatch=secretVerddacioToken` - -Log npm config settings: - -- `npm config list` -- `npm config list -l` -- `npm config list -l --location=global` -- `npm config list -l --userconfig=path/to/file.npmrc` diff --git a/tools/src/debug/bin/clean-npmrc.ts b/tools/src/debug/bin/clean-npmrc.ts deleted file mode 100644 index 476c42818..000000000 --- a/tools/src/debug/bin/clean-npmrc.ts +++ /dev/null @@ -1,29 +0,0 @@ -import yargs, { type Options } from 'yargs'; -import { hideBin } from 'yargs/helpers'; -import { cleanNpmrc } from '../utils.js'; -import type { CleanNpmrcBinOptions } from './types.js'; - -const argv = yargs(hideBin(process.argv)) - .version(false) - .options({ - userconfig: { type: 'string' }, - entryMatch: { type: 'array' }, - verbose: { type: 'boolean' }, - force: { type: 'boolean' }, - } satisfies Record) - .coerce('entriesToRemove', entriesToRemove => - Array.isArray(entriesToRemove) ? entriesToRemove : [entriesToRemove], - ).argv; - -const { userconfig, entryMatch = [] } = argv as CleanNpmrcBinOptions; - -if (entryMatch.length === 0) { - throw new Error( - 'This would remove all entries. Please provide a entry filter --entryMatch. (or pass --force if you really want to remove ALL entries)', - ); -} - -cleanNpmrc({ - ...(userconfig ? { userconfig } : {}), - entryMatch, -}); diff --git a/tools/src/debug/bin/kill-process.ts b/tools/src/debug/bin/kill-process.ts deleted file mode 100644 index 8884e0dd5..000000000 --- a/tools/src/debug/bin/kill-process.ts +++ /dev/null @@ -1,36 +0,0 @@ -import yargs from 'yargs'; -import { hideBin } from 'yargs/helpers'; -import { type PID, killProcesses } from '../utils.js'; -import type { KillProcessesBinOptions } from './types.js'; - -const { commandMatch, pid, verbose, force } = yargs(hideBin(process.argv)) - .version(false) - .options({ - force: { type: 'boolean', default: false }, - verbose: { type: 'boolean' }, - pid: { type: 'string', array: true, default: [] }, - commandMatch: { type: 'string', array: true, default: [] }, - }) - .coerce('commandMatch', (commandMatch: string[]) => - commandMatch.flatMap(p => p.split(',')).filter(p => p !== ''), - ) - .coerce('pid', (pid: string[]) => - pid.flatMap(p => p.split(',')).filter(p => p !== ''), - ).argv as Omit & { - pid: PID[]; - commandMatch: string[]; -}; -if (verbose && commandMatch.length > 0) { - console.log(`Command Filter: ${commandMatch.join(', ')}`); -} -if (verbose && pid.length > 0) { - console.log(`PID Filter: ${pid.join(', ')}`); -} - -if (pid.length === 0 && commandMatch.length === 0 && !force) { - throw new Error( - 'This would kill all processes. Please provide a PID or a command filter and a PID filter. (or pass --force if you really want to kill ALL processes)', - ); -} - -killProcesses({ commandMatch, pid, verbose }); diff --git a/tools/src/debug/bin/list-process.ts b/tools/src/debug/bin/list-process.ts deleted file mode 100644 index e54895d46..000000000 --- a/tools/src/debug/bin/list-process.ts +++ /dev/null @@ -1,47 +0,0 @@ -import yargs from 'yargs'; -import { hideBin } from 'yargs/helpers'; -import { type PID, listProcess } from '../utils.js'; -import type { ListProcessesBinOptions } from './types.js'; - -const { commandMatch, pid, verbose, slice } = yargs(hideBin(process.argv)) - .version(false) - .options({ - verbose: { type: 'boolean' }, - commandMatch: { type: 'string', array: true, default: [] }, - pid: { type: 'string', array: true, default: [] }, - slice: { type: 'number', default: 9 }, - }) - .coerce('commandMatch', (commandMatch: string[]) => - commandMatch.flatMap(p => p.split(',')).filter(p => p !== ''), - ) - .coerce('pid', (pid: string[]) => - pid.flatMap(p => p.split(',')).filter(p => p !== ''), - ).argv as Omit & { - pid: PID[]; - commandMatch: string[]; -} & { - slice: number; -}; - -if (verbose && commandMatch.length > 0) { - console.log(`Command Match: ${commandMatch.join(', ')}`); -} -if (verbose && pid.length > 0) { - console.log(`Command Match: ${pid.join(', ')}`); -} - -const processesToLog = listProcess({ commandMatch, pid }).slice(-slice); // show only last N processes - -if (processesToLog.length === 0) { - console.info( - `No processes found. Filter: ${JSON.stringify( - { commandMatch, pid }, - null, - 2, - )}`, - ); -} - -processesToLog.forEach(({ pid, command }) => { - console.log(`${pid}: ${command}`); -}); diff --git a/tools/src/debug/bin/types.ts b/tools/src/debug/bin/types.ts deleted file mode 100644 index a0fa9a131..000000000 --- a/tools/src/debug/bin/types.ts +++ /dev/null @@ -1,15 +0,0 @@ -// options for `bin/list-processes` -import type { CleanNpmrcOptions, ProcessListOption } from '../utils.js'; - -export type ListProcessesBinOptions = ProcessListOption & { - slice?: number; -}; - -export type KillProcessesBinOptions = ProcessListOption & { - force: boolean; -}; - -export type CleanNpmrcBinOptions = CleanNpmrcOptions & { - force: boolean; - verbose: boolean; -}; diff --git a/tools/src/debug/constants.ts b/tools/src/debug/constants.ts deleted file mode 100644 index b9be694d4..000000000 --- a/tools/src/debug/constants.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const LIST_PROCESS_BIN = 'tools/src/debug/bin/list-process.ts'; -export const KILL_PROCESS_BIN = 'tools/src/debug/bin/kill-process.ts'; diff --git a/tools/src/debug/debug.plugin.ts b/tools/src/debug/debug.plugin.ts deleted file mode 100644 index f1a6f307b..000000000 --- a/tools/src/debug/debug.plugin.ts +++ /dev/null @@ -1,83 +0,0 @@ -import type { CreateNodes, CreateNodesContext } from '@nx/devkit'; -import { dirname } from 'node:path'; -import { objectToCliArgs } from '../../../packages/nx-plugin/src/executors/internal/cli.js'; -import { TOOLS_TSCONFIG_PATH } from '../constants.js'; -import { KILL_PROCESS_BIN, LIST_PROCESS_BIN } from './constants.js'; - -type CreateNodesOptions = { - tsconfig?: string; - listProcessBin?: string; - killProcessBin?: string; - verbose?: boolean; -}; - -export const createNodes: CreateNodes = [ - '**/project.json', - ( - projectConfigurationFile: string, - opts: undefined | unknown, - context: CreateNodesContext, - ) => { - const root = dirname(projectConfigurationFile); - - if (root !== '.') { - return {}; - } - - const { - tsconfig = TOOLS_TSCONFIG_PATH, - listProcessBin = LIST_PROCESS_BIN, - killProcessBin = KILL_PROCESS_BIN, - verbose = false, - } = (opts ?? {}) as CreateNodesOptions; - - return { - projects: { - [root]: { - targets: { - 'clean-npmrc': { - command: `tsx --tsconfig={args.tsconfig} tools/src/debug/bin/clean-npmrc.ts ${objectToCliArgs( - { - verbose: '{args.verbose}', - userconfig: '{args.userconfig}', - entryMatch: '{args.entryMatch}', - }, - ).join(' ')}`, - options: { - tsconfig, - verbose, - }, - }, - 'list-process': { - command: `tsx --tsconfig={args.tsconfig} ${listProcessBin} ${objectToCliArgs( - { - verbose: '{args.verbose}', - slice: '{args.slice}', - pid: '{args.pid}', - commandMatch: '{args.commandMatch}', - }, - ).join(' ')}`, - options: { - tsconfig, - slice: 9, - }, - }, - 'kill-process': { - command: `tsx --tsconfig={args.tsconfig} ${killProcessBin} ${objectToCliArgs( - { - verbose: '{args.verbose}', - force: '{args.force}', - pid: '{args.pid}', - commandMatch: '{args.commandMatch}', - }, - ).join(' ')}`, - options: { - tsconfig, - }, - }, - }, - }, - }, - }; - }, -]; diff --git a/tools/src/debug/utils.ts b/tools/src/debug/utils.ts deleted file mode 100644 index 62ae90c28..000000000 --- a/tools/src/debug/utils.ts +++ /dev/null @@ -1,188 +0,0 @@ -import { execSync } from 'node:child_process'; -import { readFile, writeFile } from 'node:fs/promises'; -import path from 'node:path'; -import * as os from 'os'; - -export type PID = string | number; -export type ProcessListOption = { - pid?: PID | PID[]; - commandMatch?: string | string[]; - verbose?: boolean; -}; - -export function listProcess({ pid, commandMatch }: ProcessListOption = {}): { - pid: string; - command: string; -}[] { - const pids = pid ? (Array.isArray(pid) ? pid : [pid]) : []; - const commands = ( - commandMatch - ? Array.isArray(commandMatch) - ? commandMatch - : [commandMatch] - : [] - ).map(command => { - // normalize command string - return command.trim().replace(/\\/g, '').replace(/"/g, ''); - }); - let listProcessCommand: string; - - const platform = os.platform(); - if (platform === 'darwin' || platform === 'linux') { - listProcessCommand = 'ps -eo pid,command'; - } else if (platform === 'win32') { - listProcessCommand = 'wmic process get ProcessId,CommandLine'; - } else { - throw new Error('Unsupported platform: ' + platform); - } - - const processList = execSync(listProcessCommand) - .toString() - /** - * Before: - * 63595: nx start-verdaccio-server - * 63598: node ./node_modules/nx/src/tasks-runner/fork.js /var/folders/8k/xw46d2r95dx_s4n7t52sn8vc0000gn/T/5d4fb7ed27f13663ee6d/fp63595.sock @code-pushup/cli-source:start-verdaccio-server - * 27560: verdaccio - * 63648: tsx --tsconfig=tools/tsconfig.tools.json tools/src/debug/bin/list-process.ts --verbose=true --slice=9 --pid= --commandMatch=verdaccio - * 63649: /usr/local/bin/node --require ./node_modules/tsx/dist/preflight.cjs --loader file:///Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/tsx/dist/loader.mjs tools/src/debug/bin/list-process.ts --verbose=true --slice=9 --pid= --commandMatch=verdaccio - * 63643: nx list-process --commandMatch verdaccio --verbose - * - * After: - * 63595: nx start-verdaccio-server - * 63598: node ./node_modules/nx/src/tasks-runner/fork.js /var/folders/8k/xw46d2r95dx_s4n7t52sn8vc0000gn/T/5d4fb7ed27f13663ee6d/fp63595.sock @code-pushup/cli-source:start-verdaccio-server - * 63607: verdaccio - */ - // split stdout into lines - .trim() - .split('\n') - .filter(line => line.trim() !== '') - .filter( - line => - !line.includes('tools/src/debug/bin/list-process.ts') && - !line.includes('nx list-process'), - ); - - return processList - .map(line => { - const parts = line - .trim() - .split(/\s+/) - .map(part => part.trim()); - return { - pid: parts[0] ?? '', - command: parts.slice(1).join(' '), - }; - }) - .map(({ pid, command }) => ({ - pid, - command: command - .replace(process.cwd(), '.') - .replace(`node ./${path.join('node_modules', '.bin')}/`, ''), - })) - .filter(({ pid, command }) => { - if (pids.length === 0 && commands.length === 0) { - return true; - } - - if (pids.length > 0) { - // filter for exact matches - return pids.some(p => p === pid); - } - - // filter for exact matches - return commands.some(commandPart => command.includes(commandPart)); - }); -} - -export function killProcessPid(pid: number | string, command?: string): void { - const commandString = command ? `, command: ${command}` : ''; - try { - // @TODO sometimes pid is NaN, figure out if this is caused by trying to kill a process that is already stopped - if (Number.isNaN(Number(pid))) { - console.info( - `Can't kill process as pid is not a number. \nPID: ${pid} for command ${commandString}`, - ); - } else { - process.kill(Number(pid), 'SIGKILL'); - console.info(`Killed process with PID: ${pid} ${commandString}`); - } - } catch (error) { - console.error( - `Failed to kill process with PID: ${pid} ${commandString}`, - error, - ); - } -} - -export function killProcesses(opt: ProcessListOption): void { - const processes = listProcess(opt); - - if (processes.length > 0) { - processes.forEach(proc => { - killProcessPid(proc.pid, proc.command); - }); - } else { - console.info(`No processes found. Filter: ${JSON.stringify(opt, null, 2)}`); - } -} - -export type NpmScope = 'global' | 'user' | 'project'; - -export function getNpmrcPath(scope: NpmScope = 'user'): string { - try { - const npmConfigArg = scope === 'global' ? 'globalconfig' : 'userconfig'; - return execSync(`npm config get ${npmConfigArg}`).toString().trim(); - } catch (error) { - throw new Error(`Failed to retrieve .npmrc path: ${error}`); - } -} - -export type CleanNpmrcOptions = { - userconfig?: string; - entryMatch: string | string[]; -}; - -export async function cleanNpmrc(options: CleanNpmrcOptions): Promise { - const { userconfig = getNpmrcPath(), entryMatch: rawEntriesToRemove = [] } = - options; - const entriesToRemove = Array.isArray(rawEntriesToRemove) - ? rawEntriesToRemove - : [rawEntriesToRemove]; - - try { - const fileContent = await readFile(userconfig, 'utf-8'); - - const filteredEntries: string[] = []; - const updatedContent = fileContent - .split('\n') - .filter(line => { - if (entriesToRemove.length <= 0) { - return true; - } - - const trimmedLine = line.trim(); - // Ignore empty lines or comments - if (!trimmedLine || trimmedLine.startsWith('#')) { - return true; - } - - const isMatch = entriesToRemove.some(key => trimmedLine.includes(key)); - isMatch && filteredEntries.push(trimmedLine); - return !isMatch; - }) - .join('\n'); - await writeFile(userconfig, updatedContent, 'utf-8'); - console.log( - `Successfully cleaned ${userconfig} with filter ${entriesToRemove.join( - ', ', - )}.`, - ); - if (filteredEntries.length > 0) { - console.log(`Removed keys: \n${filteredEntries.join(', ')}`); - } else { - console.log(`No entries removed.`); - } - } catch (error) { - console.error(`Error processing ${userconfig}:`, error); - } -} diff --git a/tools/src/utils.ts b/tools/src/utils.ts deleted file mode 100644 index e8ccdb3ff..000000000 --- a/tools/src/utils.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { - type ProjectGraph, - type TargetConfiguration, - readCachedProjectGraph, -} from '@nx/devkit'; - -export function someTargetsPresent( - targets: Record, - targetNames: string | string[], -): boolean { - const searchTargets = Array.isArray(targetNames) - ? targetNames - : [targetNames]; - return Object.keys(targets).some(target => searchTargets.includes(target)); -} - -export function invariant(condition: string | boolean, message: string) { - if (!condition) { - console.error(message); - process.exit(1); - } -} - -// A simple SemVer validation to validate the version -const validVersion = /^\d+\.\d+\.\d+(-\w+\.\d+)?/; -export function parseVersion(rawVersion: string) { - if (rawVersion != null && rawVersion !== '') { - invariant( - rawVersion && validVersion.test(rawVersion), - `No version provided or version did not match Semantic Versioning, expected: #.#.#-tag.# or #.#.#, got ${rawVersion}.`, - ); - return rawVersion; - } else { - return undefined; - } -} - -export async function getAllDependencies( - projectName: string, -): Promise { - // TODO check if the caching problems are introduced by readCachedProjectGraph - const projectGraph: ProjectGraph = await readCachedProjectGraph(); - - // Helper function to recursively collect dependencies - const collectDependencies = ( - project: string, - visited: Set = new Set(), - ): Set => { - // If the project has already been visited, return the accumulated set - if (visited.has(project)) { - return visited; - } - - // Add the current project to the visited set - const updatedVisited = new Set(visited).add(project); - - // Get the direct dependencies of the current project - const dependencies = projectGraph.dependencies[project] || []; - - // Recursively collect dependencies of all direct dependencies - return dependencies.reduce((acc, dependency) => { - return collectDependencies(dependency.target, acc); - }, updatedVisited); - }; - - // Get all dependencies, then remove the original project (optional) - const allDependencies = collectDependencies(projectName); - allDependencies.delete(projectName); - - return Array.from(allDependencies).filter(dep => !dep.startsWith('npm:')); -} diff --git a/tools/tsconfig.tools.json b/tools/tsconfig.tools.json deleted file mode 100644 index 387fcedf7..000000000 --- a/tools/tsconfig.tools.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../tsconfig.base.json", - "compilerOptions": { - "outDir": "../dist/out-tsc/tools", - "rootDir": ".", - "module": "ESNext", - "target": "es5", - "types": ["node"], - "importHelpers": false - }, - "include": ["**/*.ts"], - "exclude": ["eslint-formatter-multi/**/*"] -}