Skip to content

Commit

Permalink
Stop logging the proc info when a command fails (#2716)
Browse files Browse the repository at this point in the history
Stop logging the proc info which had no value and because rush decide it
is so important to crop the logs and only show the end we never had
meaningful info
Before

![image](https://github.com/microsoft/typespec/assets/1031227/438962ed-cf83-4517-b8bd-2f1d86180add)

Now

![image](https://github.com/microsoft/typespec/assets/1031227/5e738b2b-43e0-4a70-a4b5-c392803e2a94)

---------

Co-authored-by: Brian Terlson <[email protected]>
  • Loading branch information
timotheeguerin and bterlson authored Jan 4, 2024
1 parent 8d55283 commit 53aa383
Show file tree
Hide file tree
Showing 14 changed files with 129 additions and 96 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@typespec/internal-build-utils",
"comment": "Add `runOrExit` helper to have a cleaner script runner without caring about the failure",
"type": "none"
}
],
"packageName": "@typespec/internal-build-utils"
}
3 changes: 3 additions & 0 deletions common/config/rush/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 35 additions & 26 deletions e2e/e2e-tests.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,42 @@
// @ts-check
import { existsSync, readdirSync, rmSync, writeFileSync } from "fs";
import { join } from "path";
import { repoRoot, run } from "../eng/scripts/helpers.js";
import { repoRoot } from "../eng/scripts/helpers.js";
import { runOrExit } from "../packages/internal-build-utils/dist/src/index.js";

const e2eTestDir = join(repoRoot, "e2e");
const npxCmd = process.platform === "win32" ? "npx.cmd" : "npx";

function main() {
async function main() {
printInfo();
cleanE2EDirectory();
const packages = packPackages();
await cleanE2EDirectory();
const packages = await packPackages();

console.log("Check packages exists");
run("ls", [`${repoRoot}/common/temp/artifacts/packages`]);
await runOrExit("ls", [`${repoRoot}/common/temp/artifacts/packages`]);

console.log("Check cli is working");
runTypeSpec(packages["@typespec/compiler"], ["--help"], { cwd: e2eTestDir });
await runTypeSpec(packages["@typespec/compiler"], ["--help"], { cwd: e2eTestDir });
console.log("Cli is working");

testBasicLatest(packages);
testBasicCurrentTgz(packages);
await testBasicLatest(packages);
await testBasicCurrentTgz(packages);
}
main();
await main();

function printInfo() {
console.log("-".repeat(100));
console.log("Npm Version: ");
run("npm", ["-v"]);
runOrExit("npm", ["-v"]);
console.log("-".repeat(100));
}

function cleanE2EDirectory() {
run("git", ["clean", "-xfd"], { cwd: e2eTestDir });
async function cleanE2EDirectory() {
await runOrExit("git", ["clean", "-xfd"], { cwd: e2eTestDir });
}

function packPackages() {
run("rush", ["publish", "--publish", "--pack", "--include-all"]);
async function packPackages() {
await runOrExit("rush", ["publish", "--publish", "--pack", "--include-all"]);
const outputFolder = join(repoRoot, "common/temp/artifacts/packages");
const files = readdirSync(outputFolder);
console.log("Built packages:", files);
Expand All @@ -58,31 +59,35 @@ function packPackages() {
};
}

function runTypeSpec(compilerTgz, args, options) {
run(npxCmd, ["-y", "-p", compilerTgz, "tsp", ...args], { ...options });
async function runTypeSpec(compilerTgz, args, options) {
await runOrExit(npxCmd, ["-y", "-p", compilerTgz, "tsp", ...args], { ...options });
}

function testBasicLatest(packages) {
async function testBasicLatest(packages) {
const basicLatestDir = join(e2eTestDir, "basic-latest");
const outputDir = join(basicLatestDir, "tsp-output");
console.log("Clearing basic-latest output");
rmSync(outputDir, { recursive: true, force: true });
console.log("Cleared basic-latest output");

console.log("Installing basic-latest dependencies");
runTypeSpec(packages["@typespec/compiler"], ["install"], { cwd: basicLatestDir });
await runTypeSpec(packages["@typespec/compiler"], ["install"], { cwd: basicLatestDir });
console.log("Installed basic-latest dependencies");

console.log("Running tsp compile .");
runTypeSpec(packages["@typespec/compiler"], ["compile", ".", "--emit", "@typespec/openapi3"], {
cwd: basicLatestDir,
});
await runTypeSpec(
packages["@typespec/compiler"],
["compile", ".", "--emit", "@typespec/openapi3"],
{
cwd: basicLatestDir,
}
);
console.log("Completed tsp compile .");

expectOpenApiOutput(outputDir);
}

function testBasicCurrentTgz(packages) {
async function testBasicCurrentTgz(packages) {
const basicCurrentDir = join(e2eTestDir, "basic-current");
const outputDir = join(basicCurrentDir, "tsp-output");
console.log("Clearing basic-current");
Expand All @@ -106,13 +111,17 @@ function testBasicCurrentTgz(packages) {
console.log("Generated package.json for basic-current");

console.log("Installing basic-current dependencies");
runTypeSpec(packages["@typespec/compiler"], ["install"], { cwd: basicCurrentDir });
await runTypeSpec(packages["@typespec/compiler"], ["install"], { cwd: basicCurrentDir });
console.log("Installed basic-current dependencies");

console.log(`Running tsp compile . in "${basicCurrentDir}"`);
runTypeSpec(packages["@typespec/compiler"], ["compile", ".", "--emit", "@typespec/openapi3"], {
cwd: basicCurrentDir,
});
await runTypeSpec(
packages["@typespec/compiler"],
["compile", ".", "--emit", "@typespec/openapi3"],
{
cwd: basicCurrentDir,
}
);
console.log("Completed tsp compile .");

expectOpenApiOutput(outputDir);
Expand Down
5 changes: 3 additions & 2 deletions eng/scripts/check-for-changed-files.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { run } from "./helpers.js";
// @ts-check
import { runOrExit } from "../../packages/internal-build-utils/dist/src/common.js";

const proc = run("git", ["status", "--porcelain"], {
const proc = await runOrExit("git", ["status", "--porcelain"], {
encoding: "utf-8",
stdio: [null, "pipe", "pipe"],
});
Expand Down
11 changes: 6 additions & 5 deletions eng/scripts/check-format.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
// @ts-check
import {
CommandFailedError,
ensureDotnetVersion,
runDotnetFormat,
} from "../../packages/internal-build-utils/dist/src/index.js";
import { CommandFailedError, runPrettier } from "./helpers.js";
import { runPrettier } from "./helpers.js";

try {
runPrettier("--list-different");
ensureDotnetVersion({ exitWithSuccessInDevBuilds: true });
runDotnetFormat("--verify-no-changes");
await runPrettier("--list-different");
await ensureDotnetVersion({ exitWithSuccessInDevBuilds: true });
await runDotnetFormat("--verify-no-changes");
} catch (err) {
if (err instanceof CommandFailedError) {
console.error(
"\nERROR: Files above are not formatted correctly. Run `rush format` and commit the changes."
);
process.exit(err.proc?.status ?? 1);
process.exit(err.proc?.exitCode ?? 1);
}
throw err;
}
4 changes: 2 additions & 2 deletions eng/scripts/cspell.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// @ts-check
import { resolve } from "path";
import { run, xplatCmd } from "../../packages/internal-build-utils/dist/src/index.js";
import { runOrExit, xplatCmd } from "../../packages/internal-build-utils/dist/src/index.js";
import { repoRoot } from "./helpers.js";
export const cspell = xplatCmd(
resolve(repoRoot, "packages/internal-build-utils/node_modules/.bin/cspell")
);

await run(
await runOrExit(
cspell,
[
"--no-progress",
Expand Down
8 changes: 5 additions & 3 deletions eng/scripts/dogfood.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { npmForEach, run } from "./helpers.js";
run("rush", ["update"]);
run("rush", ["build"]);
// @ts-check
import { runOrExit } from "../../packages/internal-build-utils/dist/src/common.js";
import { npmForEach } from "./helpers.js";
await runOrExit("rush", ["update"]);
await runOrExit("rush", ["build"]);
npmForEach("dogfood");
4 changes: 3 additions & 1 deletion eng/scripts/format.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
// @ts-check
import {
ensureDotnetVersion,
exitOnFailedCommand,
runDotnetFormat,
} from "../../packages/internal-build-utils/dist/src/index.js";
import { runPrettier } from "./helpers.js";
runPrettier("--write");

await exitOnFailedCommand(() => runPrettier("--write"));

await ensureDotnetVersion({ exitWithSuccessInDevBuilds: true });
await runDotnetFormat();
55 changes: 6 additions & 49 deletions eng/scripts/helpers.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { spawn, spawnSync } from "child_process";
// @ts-check
import { readFileSync } from "fs";
import { dirname, join, resolve } from "path";
import { fileURLToPath } from "url";
import { run, runOrExit } from "../../packages/internal-build-utils/dist/src/index.js";

function read(filename) {
const txt = readFileSync(filename, "utf-8")
Expand Down Expand Up @@ -41,7 +42,7 @@ export function npmForEachDependency(cmd, projectDir, options) {
forEachProject((name, location, project) => {
if (project.scripts[cmd] || cmd === "pack") {
const args = cmd === "pack" ? [cmd] : ["run", cmd];
run("npm", args, { cwd: location, ...options });
runOrExit("npm", args, { cwd: location, ...options });
}
}, deps);
}
Expand All @@ -55,57 +56,13 @@ export function npmForEach(cmd, options) {

if (project.scripts[cmd] || cmd === "pack") {
const args = cmd === "pack" ? [cmd] : ["run", cmd];
run("npm", args, { cwd: location, ...options });
runOrExit("npm", args, { cwd: location, ...options });
}
});
}

// We could use { shell: true } to let Windows find .cmd, but that causes other issues.
// It breaks ENOENT checking for command-not-found and also handles command/args with spaces
// poorly.
const isCmdOnWindows = ["rush", "npm", "code", "code-insiders", "docusaurus", tsc, prettier];

export class CommandFailedError extends Error {
constructor(msg, proc) {
super(msg);
this.proc = proc;
}
}

export function run(command, args, options) {
console.log();
console.log(`> ${command} ${args.join(" ")}`);

options = {
stdio: "inherit",
sync: true,
throwOnNonZeroExit: true,
...options,
};

if (process.platform === "win32" && isCmdOnWindows.includes(command)) {
command += ".cmd";
}

const proc = (options.sync ? spawnSync : spawn)(command, args, options);
if (proc.error) {
if (options.ignoreCommandNotFound && proc.error.code === "ENOENT") {
console.log(`Skipped: Command \`${command}\` not found.`);
} else {
throw proc.error;
}
} else if (options.throwOnNonZeroExit && proc.status !== undefined && proc.status !== 0) {
throw new CommandFailedError(
`Command \`${command} ${args.join(" ")}\` failed with exit code ${proc.status}`,
proc
);
}

return proc;
}

export function runPrettier(...args) {
run(
export async function runPrettier(...args) {
await run(
prettier,
[
...args,
Expand Down
6 changes: 4 additions & 2 deletions eng/scripts/merge-coverage.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// @ts-check
import { copyFileSync, existsSync, mkdirSync, readdirSync } from "fs";
import { join } from "path";
import { forEachProject, repoRoot, run } from "./helpers.js";
import { runOrExit } from "../../packages/internal-build-utils/dist/src/index.js";
import { forEachProject, repoRoot } from "./helpers.js";

// Create folder to collect all coverage files
const rootCoverageTmp = join(repoRoot, "coverage", "tmp");
Expand All @@ -18,7 +20,7 @@ forEachProject((name, location, project) => {
});

// Generate merged report
run(
await runOrExit(
"npm",
[
"exec",
Expand Down
4 changes: 3 additions & 1 deletion eng/scripts/watch.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
import { repoRoot, run, tsc } from "./helpers.js";
import { run } from "../../packages/internal-build-utils/dist/src/index.js";
import { repoRoot, tsc } from "./helpers.js";

run(tsc, ["--build", "./tsconfig.ws.json", "--watch"], { cwd: repoRoot, sync: false });
Loading

0 comments on commit 53aa383

Please sign in to comment.