microsoft/typespec

Public

mirrored fromhttps://github.com/microsoft/typespecAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
61ba17d2d29dedf4553b21a055aa6b442a304688

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

eng/scripts/helpers.js

122lines · modecode

1import { spawn, spawnSync } from "child_process";
2import { readFileSync } from "fs";
3import { dirname, join, resolve } from "path";
4import { fileURLToPath } from "url";
5
6function read(filename) {
7 const txt = readFileSync(filename, "utf-8")
8 .replace(/\r/gm, "")
9 .replace(/\n/gm, "«")
10 .replace(/\/\*.*?\*\//gm, "")
11 .replace(/«/gm, "\n")
12 .replace(/\s+\/\/.*/g, "");
13 return JSON.parse(txt);
14}
15
16export const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), "../..");
17export const prettier = resolve(repoRoot, "packages/compiler/node_modules/.bin/prettier");
18export const tsc = resolve(repoRoot, "packages/compiler/node_modules/.bin/tsc");
19
20const rush = read(`${repoRoot}/rush.json`);
21
22export function forEachProject(onEach, filter) {
23 // load all the projects
24 for (const each of rush.projects) {
25 const packageName = each.packageName;
26 if (filter !== undefined && !filter.includes(packageName)) continue;
27 const projectFolder = resolve(`${repoRoot}/${each.projectFolder}`);
28 const project = JSON.parse(readFileSync(`${projectFolder}/package.json`, "utf-8"));
29 onEach(packageName, projectFolder, project);
30 }
31}
32
33export function npmForEachDependency(cmd, projectDir, options) {
34 const project = JSON.parse(readFileSync(`${projectDir}/package.json`, "utf-8"));
35 const deps = [
36 Object.keys(project.dependencies || {}),
37 Object.keys(project.devDependencies || {}),
38 Object.keys(project.peerDependencies || {}),
39 ].flat();
40
41 forEachProject((name, location, project) => {
42 if (project.scripts[cmd] || cmd === "pack") {
43 const args = cmd === "pack" ? [cmd] : ["run", cmd];
44 run("npm", args, { cwd: location, ...options });
45 }
46 }, deps);
47}
48
49export function npmForEach(cmd, options) {
50 forEachProject((name, location, project) => {
51 if (cmd === "test-official" && !project.scripts[cmd] && project.scripts["test"]) {
52 const pj = join(location, "package.json");
53 throw new Error(`${pj} has a 'test' script, but no 'test-official' script for CI.`);
54 }
55
56 if (project.scripts[cmd] || cmd === "pack") {
57 const args = cmd === "pack" ? [cmd] : ["run", cmd];
58 run("npm", args, { cwd: location, ...options });
59 }
60 });
61}
62
63// We could use { shell: true } to let Windows find .cmd, but that causes other issues.
64// It breaks ENOENT checking for command-not-found and also handles command/args with spaces
65// poorly.
66const isCmdOnWindows = ["rush", "npm", "code", "code-insiders", "docusaurus", tsc, prettier];
67
68export class CommandFailedError extends Error {
69 constructor(msg, proc) {
70 super(msg);
71 this.proc = proc;
72 }
73}
74
75export function run(command, args, options) {
76 console.log();
77 console.log(`> ${command} ${args.join(" ")}`);
78
79 options = {
80 stdio: "inherit",
81 sync: true,
82 throwOnNonZeroExit: true,
83 ...options,
84 };
85
86 if (process.platform === "win32" && isCmdOnWindows.includes(command)) {
87 command += ".cmd";
88 }
89
90 const proc = (options.sync ? spawnSync : spawn)(command, args, options);
91 if (proc.error) {
92 if (options.ignoreCommandNotFound && proc.error.code === "ENOENT") {
93 console.log(`Skipped: Command \`${command}\` not found.`);
94 } else {
95 throw proc.error;
96 }
97 } else if (options.throwOnNonZeroExit && proc.status !== undefined && proc.status !== 0) {
98 throw new CommandFailedError(
99 `Command \`${command} ${args.join(" ")}\` failed with exit code ${proc.status}`,
100 proc
101 );
102 }
103
104 return proc;
105}
106
107export function runPrettier(...args) {
108 run(
109 prettier,
110 [
111 ...args,
112 "--config",
113 ".prettierrc.json",
114 "--ignore-path",
115 ".prettierignore",
116 "**/*.{ts,js,tsx,jsx,cjs,mjs,css,json,yml,yaml,tsp,cadl,md}",
117 ],
118 {
119 cwd: repoRoot,
120 }
121 );
122}
123