Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | import { getProjects, type ProjectConfiguration, type TargetConfiguration } from '@nx/devkit'; import * as fs from 'fs'; import { FsTree } from 'nx/src/generators/tree'; import { argv } from 'yargs'; import { COLORS } from '../utils/colors'; import { logger } from '../utils/logger'; /** * Project root directory. */ const root = process.cwd(); interface IPackageJson { scripts: Record<string, string>; husky: { hooks: Record<string, string>; }; dependencies: Record<string, string>; devDependencies: Record<string, string>; engines: { node: string; npm: string; }; } type TCli = 'yarn' | 'nx'; /** * Prints arguments usage tip if no applicable arguments were used. */ const printSearchArgumentTip = () => { const search = (argv as { [key: string]: string })['search']; if (typeof search !== 'string') { // eslint-disable-next-line no-console -- needed here to print output in the terminal console.log( `\n${COLORS.CYAN}%s${COLORS.DEFAULT} ${COLORS.YELLOW}%s${COLORS.DEFAULT}\n ${COLORS.CYAN}%s${COLORS.DEFAULT} ${COLORS.YELLOW}%s${COLORS.DEFAULT}\n`, 'Use --search flag to filter available commands, e.g.', 'yarn workspace:help --search=build', 'Some common --search flag values:', 'start generate install build lint test e2e affected analyze firebase nx workspace', ); } }; /** * Prints package scripts. * @param scripts package scripts object. */ const printPackageScripts = (scripts: Record<string, string>, cli: TCli) => { const search = (argv as { [key: string]: string | undefined })['search']?.replace(/[^a-z-]/g, ''); const scriptKeys = typeof search !== 'string' ? Object.keys(scripts) : Object.keys(scripts).filter(key => new RegExp(search).test(key)); for (const key of scriptKeys) { // eslint-disable-next-line no-console -- needed here to print output in the terminal console.log( `$ ${COLORS.CYAN}${cli}${COLORS.DEFAULT} ${COLORS.CYAN}%s${COLORS.DEFAULT}: ${COLORS.YELLOW}%s${COLORS.DEFAULT}`, `${key}`, `${scripts[key]}`, ); } }; /** * Parses package.json and prints root level commands. */ const printPackageCommands = () => { fs.readFile(`${root}/package.json`, 'utf8', (error, data) => { if (error !== null) { logger.printError(error); process.exit(1); } const parsedPackageJson: IPackageJson = JSON.parse(data); logger.printInfo('', 'Root commands'); const scripts = parsedPackageJson.scripts; printPackageScripts(scripts, 'yarn'); }); }; /** * Parses workspace.json and prints project level commands. */ const printNxCommands = () => { const tree = new FsTree(root, true); const projects = [...getProjects(tree).values()]; let allCommands: Record<string, string> = {}; for (let i = 0, max = projects.length; i < max; i += 1) { const config = projects[i]; const projectName = config.name; const projectDir = config.root; const projectJsonPath = `${projectDir}/project.json`; const result: NodeJS.ErrnoException | string = fs.readFileSync(projectJsonPath, 'utf8'); if (typeof result !== 'string') { logger.printError(result); process.exit(1); } const projectConfig: ProjectConfiguration = JSON.parse(result); const targets = projectConfig.targets; const targetKeys = typeof targets !== 'undefined' ? Object.keys(targets) : []; // aggregate custom commands based on nx:run-commands if (typeof targets !== 'undefined') { const commands = targetKeys .filter(key => targets[key].executor === 'nx:run-commands') .reduce((acc: Record<string, string>, key) => { const target: TargetConfiguration<{ commands?: Array<{ command: string }>; }> = targets[key]; const commandsConfig = target.options?.commands; acc[`run ${projectName}:${key}`] = typeof commandsConfig !== 'undefined' ? commandsConfig[0].command : ''; return acc; }, {}); allCommands = { ...allCommands, ...commands }; } // aggregate commands based on executors if (typeof targets !== 'undefined') { const commands = targetKeys .filter(key => targets[key].executor !== 'nx:run-commands') .reduce((acc: Record<string, string>, key) => { acc[`run ${projectName}:${key}`] = `npx nx ${key} ${projectConfig.name}`; return acc; }, {}); allCommands = { ...allCommands, ...commands }; } } logger.printInfo('', 'Project commands'); printPackageScripts(allCommands, 'nx'); printSearchArgumentTip(); }; printPackageCommands(); printNxCommands(); |