[ts-http-runtime] add azure diff check tool (#31285)
### Packages impacted by this PR
- `@typespec/ts-http-runtime`
### Describe the problem that is addressed by this PR
We have had issues with the unbranded Core package becoming out of sync
with the Azure packages. This PR adds a report which is a diff between
the Azure Core packages and the unbranded package and causes the lint
step to fail if there are any differences between Azure and unbranded
that do not appear in the report. Running the `lint:fix` script will
update the diff report. This will mean that:
- Making an Azure Core change without a corresponding change to
unbranded package, either in the source code or in the diff report, will
result in a CI failure
- Changes to the diff report can be reviewed so that any differences
between Azure and unbranded implementations of a feature can be easily
compared
Why use the lint script (and lint:fix)? This is already run by CI, so by
using it we don't need to make any changes to pipeline steps to get this
working. This script is a one-off and so I just want to do the bare
minimum to get things working 😄
This commit is contained in:
Родитель
0b6bbeab42
Коммит
31b76c94f5
|
@ -25104,7 +25104,7 @@ packages:
|
|||
dev: false
|
||||
|
||||
file:projects/ts-http-runtime.tgz:
|
||||
resolution: {integrity: sha512-MD9tMIfpTC9zx97D7IF1ZXzk/qijL6n58lc0C8cfeQ7y8DQHUx4TGBLW43aDOABJrMO9Oo3M3PCVGS2yVfkOpA==, tarball: file:projects/ts-http-runtime.tgz}
|
||||
resolution: {integrity: sha512-wtRhN//7rN8fYN7MR3Gm1g2YY0+GxVwAGSx4aLNkxM7zSNggwYOBwqmT8fDlDSkiewqYbW5jHNWOtwMd4mRecA==, tarball: file:projects/ts-http-runtime.tgz}
|
||||
name: '@rush-temp/ts-http-runtime'
|
||||
version: 0.0.0
|
||||
dependencies:
|
||||
|
@ -25119,6 +25119,7 @@ packages:
|
|||
playwright: 1.48.1
|
||||
rimraf: 5.0.10
|
||||
tslib: 2.8.0
|
||||
tsx: 4.19.1
|
||||
typescript: 5.6.3
|
||||
vitest: 2.1.3(@types/node@18.19.57)(@vitest/browser@2.1.3)
|
||||
transitivePeerDependencies:
|
||||
|
|
|
@ -62,8 +62,8 @@
|
|||
"integration-test": "npm run integration-test:node && npm run integration-test:browser",
|
||||
"integration-test:browser": "echo skipped",
|
||||
"integration-test:node": "echo skipped",
|
||||
"lint": "eslint package.json api-extractor.json src test",
|
||||
"lint:fix": "eslint package.json api-extractor.json src test --fix --fix-type [problem,suggestion]",
|
||||
"lint": "tsx scripts/azure-diff.ts; eslint package.json api-extractor.json src test",
|
||||
"lint:fix": "tsx scripts/azure-diff.ts --update && eslint package.json api-extractor.json src test --fix --fix-type [problem,suggestion]",
|
||||
"pack": "npm pack 2>&1",
|
||||
"test": "npm run clean && dev-tool run build-package && npm run unit-test:node && dev-tool run bundle && npm run unit-test:browser && npm run integration-test",
|
||||
"test:browser": "npm run clean && npm run unit-test:browser && npm run integration-test:browser",
|
||||
|
@ -108,7 +108,8 @@
|
|||
"playwright": "^1.41.2",
|
||||
"rimraf": "^5.0.5",
|
||||
"typescript": "~5.6.2",
|
||||
"vitest": "^2.0.5"
|
||||
"vitest": "^2.0.5",
|
||||
"tsx": "^4.19.1"
|
||||
},
|
||||
"tshy": {
|
||||
"exports": {
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,156 @@
|
|||
import { parseArgs } from "node:util";
|
||||
import fs from "node:fs/promises";
|
||||
import { spawn, SpawnOptions } from "node:child_process";
|
||||
import { exit } from "node:process";
|
||||
import path from "node:path";
|
||||
|
||||
/**
|
||||
* Mapping of locations of Azure source files to their location in the unbranded package.
|
||||
*/
|
||||
const AZURE_SOURCES = {
|
||||
// core-rest-pipeline is placed at the root of the unbranded package; this also covers subfolders of
|
||||
// core-rest-pipeline including policies/ and retryStrategies/.
|
||||
"../core-rest-pipeline/src/": "./src/",
|
||||
"../core-util/src/": "./src/util/",
|
||||
"../core-auth/src/": "./src/auth/",
|
||||
"../abort-controller/src/": "./src/abort-controller/",
|
||||
"../core-client-rest/src/": "./src/client/",
|
||||
"../core-tracing/src/": "./src/tracing/",
|
||||
"../logger/src/": "./src/logger/",
|
||||
};
|
||||
|
||||
const {
|
||||
values: {
|
||||
update = false,
|
||||
"output-path": outputPath = "./review/azure-core-comparison.diff",
|
||||
verbose = false,
|
||||
},
|
||||
} = parseArgs({
|
||||
options: {
|
||||
update: {
|
||||
type: "boolean",
|
||||
},
|
||||
"output-path": {
|
||||
type: "string",
|
||||
short: "o",
|
||||
},
|
||||
verbose: {
|
||||
type: "boolean",
|
||||
short: "v",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
interface RunResult {
|
||||
exitCode?: number;
|
||||
signal?: NodeJS.Signals;
|
||||
stdout: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the given CLI command and captures the output
|
||||
*/
|
||||
async function run(
|
||||
commandAndArgs: [string, ...string[]],
|
||||
options: SpawnOptions = {},
|
||||
): Promise<RunResult> {
|
||||
let stdout = "";
|
||||
const [command, ...args] = commandAndArgs;
|
||||
|
||||
const proc = spawn(command, args, options);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
proc.on("error", reject);
|
||||
proc.on("exit", (exitCode, signal) => {
|
||||
resolve({
|
||||
exitCode: exitCode ?? undefined,
|
||||
signal: signal ?? undefined,
|
||||
stdout,
|
||||
});
|
||||
});
|
||||
proc.stdout?.on("data", (data) => {
|
||||
stdout += data.toString();
|
||||
if (verbose) {
|
||||
process.stdout.write(data);
|
||||
}
|
||||
});
|
||||
|
||||
if (verbose) {
|
||||
proc.stderr?.on("data", (data) => process.stderr.write(data));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a diff representing code changes between the Azure core packages and the unbranded package.
|
||||
*
|
||||
* This is done by using a temp folder/git repo. The Azure core files are copied into the temp folder following
|
||||
* the mappings defined in AZURE_SOURCES. This is then committed, and then the temp folder is cleaned out and the unbranded
|
||||
* Core is copied in. The diff (as reported by `git diff`) between the committed Azure core files and the unbranded replacement
|
||||
* is returned.
|
||||
*/
|
||||
async function calculatePatchFileContents(): Promise<string> {
|
||||
const tmpDir = await fs.mkdtemp(".azure-diff-tool");
|
||||
|
||||
try {
|
||||
// Initialize temp git repo
|
||||
await run(["git", "init"], { cwd: tmpDir });
|
||||
|
||||
// Copy over the Azure Core files to where are expected to be in the unbranded Core package
|
||||
for (const [azurePath, newLocation] of Object.entries(AZURE_SOURCES)) {
|
||||
await fs.cp(azurePath, path.join(tmpDir, newLocation), { recursive: true });
|
||||
}
|
||||
|
||||
// Commit the Azure files, then remove everything so that they can be replaced by the unbranded files
|
||||
await run(["git", "add", "."], { cwd: tmpDir });
|
||||
await run(["git", "commit", "-m", "Placeholder commit"], { cwd: tmpDir });
|
||||
await fs.rm(path.join(tmpDir, "src"), { recursive: true, force: true });
|
||||
|
||||
// Copy the unbranded files into the temp repo
|
||||
await fs.cp("./src/", path.join(tmpDir, "src"), { recursive: true });
|
||||
|
||||
// Staging the unbranded files and using `git diff --staged` means that the diff will also show files
|
||||
// that have been removed and moved.
|
||||
await run(["git", "add", "."], { cwd: tmpDir });
|
||||
const { stdout } = await run(
|
||||
["git", "diff", "--ignore-all-space", "--staged", "--find-renames"],
|
||||
{ cwd: tmpDir },
|
||||
);
|
||||
return stdout;
|
||||
} finally {
|
||||
await fs.rm(tmpDir, { recursive: true, force: true });
|
||||
}
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
const expectedContent = await calculatePatchFileContents();
|
||||
|
||||
if (update) {
|
||||
await fs.writeFile(outputPath, expectedContent, "utf-8");
|
||||
} else {
|
||||
const content = await fs.readFile(outputPath, "utf-8");
|
||||
|
||||
if (content === expectedContent) {
|
||||
console.log("✅ No changes to Azure to unbranded diff report");
|
||||
} else {
|
||||
console.error("❌ There have been changes to the Azure-unbranded diff report.");
|
||||
console.error(
|
||||
" This happens when you make a change to Azure Core without making the same change in the unbranded Core package.",
|
||||
);
|
||||
console.error(" To fix:");
|
||||
console.error(
|
||||
" - Run `rushx lint:fix` in the ts-http-runtime package to update review/azure-core-comparison.diff, then have a look and see what's changed.",
|
||||
);
|
||||
console.error(" - Apply your Core changes to the ts-http-runtime package as appropriate.");
|
||||
console.error(
|
||||
" - Run `rushx lint:fix` again package to update the diff report, and commit the changes.",
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
Загрузка…
Ссылка в новой задаче