diff --git a/eng/pipelines/ci.yml b/eng/pipelines/ci.yml index 7be82bebfb6..cdddcc923c0 100644 --- a/eng/pipelines/ci.yml +++ b/eng/pipelines/ci.yml @@ -74,10 +74,8 @@ jobs: - script: | inv regenerate displayName: 'Regenerate Code' - - script: | - git add -A # 'add' first so 'diff' includes untracked files - git diff --staged -w - displayName: 'Diff regeneration' + - script: node ./eng/scripts/check-for-changed-files.js + displayName: Fail on regeneration diff - task: UsePythonVersion@0 displayName: 'Use Python $(PythonVersion)' inputs: diff --git a/eng/scripts/check-for-changed-files.js b/eng/scripts/check-for-changed-files.js new file mode 100644 index 00000000000..3fd1827da29 --- /dev/null +++ b/eng/scripts/check-for-changed-files.js @@ -0,0 +1,23 @@ +// @ts-check + +const { run } = require("./helpers.js"); + +const proc = run("git", ["status", "--porcelain"], { + encoding: "utf-8", + stdio: [null, "pipe", "pipe"], +}); + +if (proc.stdout) { + console.log(proc.stdout); +} + +if (proc.stderr) { + console.error(proc.stderr); +} + +if (proc.stdout || proc.stderr) { + console.error( + `ERROR: There are diffs in regeneration. Please run 'inv regenerate' and re-run. You may also have to remove 'node_modules' and re-run 'npm install' to get the latest testserver.`, + ); + process.exit(1); +} \ No newline at end of file diff --git a/eng/scripts/helpers.js b/eng/scripts/helpers.js new file mode 100644 index 00000000000..aac104cb2bd --- /dev/null +++ b/eng/scripts/helpers.js @@ -0,0 +1,83 @@ +// @ts-check +const { spawn, spawnSync } = require("child_process"); +const { resolve } = require("path"); + +const repoRoot = resolve(__dirname, "../.."); +const prettier = resolve( + repoRoot, + "packages/extensions/core/node_modules/.bin/prettier" +); +const tsc = resolve(repoRoot, "packages/extensions/core/node_modules/.bin/tsc"); + +const isCmdOnWindows = ["rush", "npm", "code", "code-insiders", tsc, prettier]; + +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; +} + +class CommandFailedError extends Error { + constructor(msg, proc) { + super(msg); + this.proc = proc; + } +} + +function runPrettier(...args) { + run( + prettier, + [ + ...args, + "--config", + ".prettierrc.yml", + "--ignore-path", + ".prettierignore", + "**/*.{ts,js,cjs,mjs,json,yml,yaml,cadl,md}", + ], + { + cwd: repoRoot, + } + ); +} + +module.exports = { + repoRoot, + prettier, + tsc, + run, + runPrettier, + CommandFailedError, +};