Skip to content

Commit 143033b

Browse files
committed
Code review feedback.
1 parent dd3e9d9 commit 143033b

11 files changed

Lines changed: 70 additions & 97 deletions

File tree

.github/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"private": true,
3+
"type": "module"
4+
}

.github/shared/src/exec.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const execFileImpl = promisify(child_process.execFile);
77
* @typedef {Object} ExecOptions
88
* @property {string} [cwd] Current working directory. Default: process.cwd().
99
* @property {import('./logger.js').ILogger} [logger]
10+
* @property {boolean} [logOutput] Log captured stdout/stderr at info level. Default: false.
1011
* @property {number} [maxBuffer] Max bytes allowed on stdout or stderr. Default: 16 * 1024 * 1024.
1112
*/
1213

@@ -54,6 +55,7 @@ export async function execFile(file, args, options = {}) {
5455
const {
5556
cwd,
5657
logger,
58+
logOutput = false,
5759
// Node default is 1024 * 1024, which is too small for some git commands returning many entities or large file content.
5860
// To support "git show", should be larger than the largest swagger file in the repo (2.5 MB as of 2/28/2025).
5961
maxBuffer = 16 * 1024 * 1024,
@@ -70,11 +72,27 @@ export async function execFile(file, args, options = {}) {
7072

7173
logger?.debug(`stdout: '${result.stdout}'`);
7274
logger?.debug(`stderr: '${result.stderr}'`);
75+
if (logOutput) {
76+
if (result.stdout) {
77+
logger?.info(result.stdout.trimEnd());
78+
}
79+
if (result.stderr) {
80+
logger?.info(result.stderr.trimEnd());
81+
}
82+
}
7383

7484
return result;
7585
} catch (error) {
7686
/* v8 ignore next */
7787
logger?.debug(`error: '${JSON.stringify(error)}'`);
88+
if (logOutput && isExecError(error)) {
89+
if (error.stdout) {
90+
logger?.info(error.stdout.trimEnd());
91+
}
92+
if (error.stderr) {
93+
logger?.info(error.stderr.trimEnd());
94+
}
95+
}
7896

7997
throw error;
8098
}

.github/workflows/src/api-md-consistency/adapter_config.js

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
#!/usr/bin/env node
22

3-
const fs = require("fs");
4-
const path = require("path");
3+
import fs from "fs";
4+
import path from "path";
5+
import { fileURLToPath, pathToFileURL } from "url";
6+
7+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
58

69
const DEFAULT_CONFIG = {
710
adapter: "python",
811
};
912

10-
function loadWorkflowConfig() {
13+
export function loadWorkflowConfig() {
1114
const configPath = path.join(__dirname, "api_md_workflow.config.json");
1215
if (!fs.existsSync(configPath)) {
1316
return { ...DEFAULT_CONFIG };
@@ -33,17 +36,11 @@ function loadWorkflowConfig() {
3336
};
3437
}
3538

36-
function loadAdapter(name) {
39+
export async function loadAdapter(name) {
3740
const adapterPath = path.join(__dirname, "adapters", `${name}.js`);
3841
if (!fs.existsSync(adapterPath)) {
3942
throw new Error(`ERROR: adapter '${name}' not found at ${adapterPath}`);
4043
}
4144

42-
// eslint-disable-next-line global-require, import/no-dynamic-require
43-
return require(adapterPath);
45+
return import(pathToFileURL(adapterPath).href);
4446
}
45-
46-
module.exports = {
47-
loadWorkflowConfig,
48-
loadAdapter,
49-
};

.github/workflows/src/api-md-consistency/adapters/python.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#!/usr/bin/env node
22

3-
const fs = require("fs");
4-
const path = require("path");
5-
const { spawnSync } = require("child_process");
3+
import fs from "fs";
4+
import path from "path";
5+
import { spawnSync } from "child_process";
66

77
function run(cmd, args, options = {}) {
88
const logger = options.logger || console;
@@ -152,9 +152,10 @@ function generateApiForPackage({
152152
// Fields in api.metadata.yml that must match between working tree and committed version.
153153
// pythonVersion is excluded because it varies across CI environments.
154154
const metadataFieldsToValidate = ["apiMdSha256", "parserVersion"];
155+
const name = "python";
155156

156-
module.exports = {
157-
name: "python",
157+
export {
158+
name,
158159
isPackageDir,
159160
findPackageDir,
160161
readVersion,

.github/workflows/src/api-md-consistency/api-md-consistency.js

Lines changed: 9 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
const fs = require("fs");
2-
const path = require("path");
3-
const { pathToFileURL } = require("url");
1+
import fs from "fs";
2+
import path from "path";
3+
import { execFile } from "../../../shared/src/exec.js";
44

5-
const SHARED_SRC_ROOT = path.resolve(__dirname, "..", "..", "..", "shared", "src");
6-
const sharedModuleCache = new Map();
75
const ANSI = {
86
bold: "\u001b[1m",
97
cyan: "\u001b[36m",
@@ -15,45 +13,12 @@ function styleLog(text, ...styles) {
1513
return `${styles.join("")}${text}${ANSI.reset}`;
1614
}
1715

18-
async function loadSharedModule(fileName) {
19-
if (sharedModuleCache.has(fileName)) {
20-
return sharedModuleCache.get(fileName);
21-
}
22-
23-
const filePath = path.join(SHARED_SRC_ROOT, fileName);
24-
const modulePromise = import(pathToFileURL(filePath).href);
25-
sharedModuleCache.set(fileName, modulePromise);
26-
return modulePromise;
27-
}
28-
2916
async function runNode(scriptRelativePath, workspace, core) {
30-
const { execFile, isExecError } = await loadSharedModule("exec.js");
31-
32-
try {
33-
const result = await execFile("node", [scriptRelativePath], {
34-
cwd: workspace,
35-
logger: core,
36-
});
37-
38-
if (result.stdout) {
39-
core.info(result.stdout.trimEnd());
40-
}
41-
if (result.stderr) {
42-
core.info(result.stderr.trimEnd());
43-
}
44-
} catch (error) {
45-
if (isExecError(error)) {
46-
if (error.stdout) {
47-
core.info(error.stdout.trimEnd());
48-
}
49-
if (error.stderr) {
50-
core.info(error.stderr.trimEnd());
51-
}
52-
}
53-
54-
const status = isExecError(error) && Number.isInteger(error.code) ? error.code : 1;
55-
throw new Error(`Command failed (${status}): node ${scriptRelativePath}`);
56-
}
17+
await execFile("node", [scriptRelativePath], {
18+
cwd: workspace,
19+
logger: core,
20+
logOutput: true,
21+
});
5722
}
5823

5924
function readLines(fileRelativePath, workspace) {
@@ -90,7 +55,7 @@ function formatIssueSection(title, apiFiles) {
9055
return lines.join("\n");
9156
}
9257

93-
module.exports = async function apiMdConsistency({ core }) {
58+
export default async function apiMdConsistency({ core }) {
9459
const workspace = process.env.GITHUB_WORKSPACE || process.cwd();
9560

9661
await runNode(".github/workflows/src/api-md-consistency/find_affected.js", workspace, core);

.github/workflows/src/api-md-consistency/common.js

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,19 @@
11
#!/usr/bin/env node
22

3-
const fs = require("fs");
4-
const path = require("path");
5-
const { pathToFileURL } = require("url");
3+
import fs from "fs";
4+
import path from "path";
5+
import { fileURLToPath } from "url";
6+
import { execFile, isExecError } from "../../../shared/src/exec.js";
7+
import { defaultLogger } from "../../../shared/src/logger.js";
68

9+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
710
const REPO_ROOT = path.resolve(__dirname, "..", "..", "..", "..");
8-
const SHARED_SRC_ROOT = path.join(REPO_ROOT, ".github", "shared", "src");
9-
const sharedModuleCache = new Map();
10-
11-
async function loadSharedModule(fileName) {
12-
if (sharedModuleCache.has(fileName)) {
13-
return sharedModuleCache.get(fileName);
14-
}
15-
16-
const filePath = path.join(SHARED_SRC_ROOT, fileName);
17-
const modulePromise = import(pathToFileURL(filePath).href);
18-
sharedModuleCache.set(fileName, modulePromise);
19-
return modulePromise;
20-
}
2111

2212
async function getDefaultLogger() {
23-
const { defaultLogger } = await loadSharedModule("logger.js");
2413
return defaultLogger;
2514
}
2615

2716
async function runAsync(cmd, args, options = {}) {
28-
const { execFile, isExecError } = await loadSharedModule("exec.js");
2917
const check = options.check ?? true;
3018
const logger = options.logger ?? (await getDefaultLogger());
3119

@@ -100,9 +88,8 @@ function requireEnv(name) {
10088
return value;
10189
}
10290

103-
module.exports = {
91+
export {
10492
REPO_ROOT,
105-
loadSharedModule,
10693
getDefaultLogger,
10794
runAsync,
10895
readLines,

.github/workflows/src/api-md-consistency/find_affected.js

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
11
#!/usr/bin/env node
22

3-
const {
3+
import {
44
REPO_ROOT,
55
appendGithubOutput,
66
envPath,
77
getDefaultLogger,
8-
loadSharedModule,
98
requireEnv,
109
runAsync,
1110
writeLines,
12-
} = require("./common");
13-
const { loadAdapter, loadWorkflowConfig } = require("./adapter_config");
11+
} from "./common.js";
12+
import { loadAdapter, loadWorkflowConfig } from "./adapter_config.js";
13+
import { includesSegment } from "../../../shared/src/path.js";
1414

1515
async function main() {
16-
const { includesSegment } = await loadSharedModule("path.js");
17-
1816
const config = loadWorkflowConfig();
1917
const adapterName = config.adapter;
20-
const adapter = loadAdapter(adapterName);
18+
const adapter = await loadAdapter(adapterName);
2119
if (typeof adapter.isPackageDir !== "function") {
2220
throw new Error(`ERROR: adapter '${adapterName}' does not implement isPackageDir(repoRoot, packageDirRelative).`);
2321
}

.github/workflows/src/api-md-consistency/find_mismatches.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#!/usr/bin/env node
22

3-
const fs = require("fs");
3+
import fs from "fs";
44

5-
const { appendGithubOutput, envPath, getDefaultLogger, readLines, runAsync, writeLines } = require("./common");
6-
const { loadAdapter, loadWorkflowConfig } = require("./adapter_config");
5+
import { appendGithubOutput, envPath, getDefaultLogger, readLines, runAsync, writeLines } from "./common.js";
6+
import { loadAdapter, loadWorkflowConfig } from "./adapter_config.js";
77

88
/**
99
* Parse a simple key: value YAML file into an object.
@@ -22,7 +22,7 @@ function parseSimpleYaml(text) {
2222

2323
async function main() {
2424
const config = loadWorkflowConfig();
25-
const adapter = loadAdapter(config.adapter);
25+
const adapter = await loadAdapter(config.adapter);
2626

2727
// Fields to compare in api.metadata.yml. If the adapter doesn't specify,
2828
// compare all fields (strict default for languages that don't opt out).

.github/workflows/src/api-md-consistency/regenerate.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
#!/usr/bin/env node
22

3-
const path = require("path");
3+
import path from "path";
44

5-
const { REPO_ROOT, envPath, getDefaultLogger, readLines } = require("./common");
6-
const { loadAdapter, loadWorkflowConfig } = require("./adapter_config");
5+
import { REPO_ROOT, envPath, getDefaultLogger, readLines } from "./common.js";
6+
import { loadAdapter, loadWorkflowConfig } from "./adapter_config.js";
77

88
async function main() {
99
const logger = await getDefaultLogger();
1010
const config = loadWorkflowConfig();
11-
const adapter = loadAdapter(config.adapter);
11+
const adapter = await loadAdapter(config.adapter);
1212
if (typeof adapter.generateApiForPackage !== "function") {
1313
throw new Error(
1414
`ERROR: adapter '${config.adapter}' does not implement generateApiForPackage({ repoRoot, packageName, runtimeExecutable }).`,

eng/tools/azure-sdk-tools/azpysdk/apistub.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,10 @@ def register(
8181
dest="install_deps",
8282
default=False,
8383
action="store_true",
84-
help="Install dev requirements and apiview dependencies before running. Skipped by default for faster local iteration.",
84+
help=(
85+
"Install dev requirements and apiview dependencies before running. "
86+
"Skipped by default for faster local iteration, but always enabled when --isolate is used."
87+
),
8588
)
8689
p.set_defaults(func=self.run)
8790

0 commit comments

Comments
 (0)