Skip to content

Commit e4bf857

Browse files
[tsp-client] Report diagnostic errors and exit with an error (#8844)
* report error diagnostics and exit * release prep * update logic * wording * update changelog date --------- Co-authored-by: Catalina Peralta <caperal@microsoft.com>
1 parent 4148bf2 commit e4bf857

5 files changed

Lines changed: 63 additions & 21 deletions

File tree

tools/tsp-client/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Release
22

3+
## 2024-08-15 - 0.12.0
4+
5+
- Check for error diagnostics during TypeSpec compilation and exit with error if found. (#8815, #8777, #8555)
6+
37
## 2024-08-13 - 0.11.2
48

59
- Fix `--version` flag. (#8814)

tools/tsp-client/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tools/tsp-client/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@azure-tools/typespec-client-generator-cli",
3-
"version": "0.11.2",
3+
"version": "0.12.0",
44
"description": "A tool to generate Azure SDKs from TypeSpec",
55
"main": "dist/index.js",
66
"homepage": "https://github.com/Azure/azure-sdk-tools/tree/main/tools/tsp-client#readme",

tools/tsp-client/src/commands.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ export async function generateCommand(argv: any) {
268268
args.push("--force");
269269
}
270270
await npmCommand(srcDir, args);
271-
await compileTsp({
271+
const success = await compileTsp({
272272
emitterPackage: emitter,
273273
outputPath: outputDir,
274274
resolvedMainFilePath,
@@ -282,6 +282,11 @@ export async function generateCommand(argv: any) {
282282
Logger.debug("Cleaning up temp directory");
283283
await removeDirectory(tempRoot);
284284
}
285+
286+
if (!success) {
287+
Logger.error("Failed to generate client");
288+
process.exit(1);
289+
}
285290
}
286291

287292
export async function compareCommand(argv: any, args: string[]) {

tools/tsp-client/src/typespec.ts

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1-
import { resolvePath, getDirectoryPath, ResolveCompilerOptionsOptions, formatDiagnostic } from "@typespec/compiler";
2-
import { ModuleResolutionResult, resolveModule, ResolveModuleHost } from "@typespec/compiler/module-resolver";
1+
import {
2+
resolvePath,
3+
getDirectoryPath,
4+
ResolveCompilerOptionsOptions,
5+
formatDiagnostic,
6+
} from "@typespec/compiler";
7+
import {
8+
ModuleResolutionResult,
9+
resolveModule,
10+
ResolveModuleHost,
11+
} from "@typespec/compiler/module-resolver";
312
import { Logger } from "./log.js";
413
import { readFile, readdir, realpath, stat } from "fs/promises";
514
import { pathToFileURL } from "url";
@@ -19,7 +28,9 @@ export function resolveTspConfigUrl(configUrl: string): {
1928
} {
2029
let resolvedConfigUrl = configUrl;
2130

22-
const res = configUrl.match('^https://(?<urlRoot>github|raw.githubusercontent).com/(?<repo>[^/]*/azure-rest-api-specs(-pr)?)/(tree/|blob/)?(?<commit>[0-9a-f]{40})/(?<path>.*)/tspconfig.yaml$')
31+
const res = configUrl.match(
32+
"^https://(?<urlRoot>github|raw.githubusercontent).com/(?<repo>[^/]*/azure-rest-api-specs(-pr)?)/(tree/|blob/)?(?<commit>[0-9a-f]{40})/(?<path>.*)/tspconfig.yaml$",
33+
);
2334
if (res && res.groups) {
2435
if (res.groups["urlRoot"]! === "github") {
2536
resolvedConfigUrl = configUrl.replace("github.com", "raw.githubusercontent.com");
@@ -30,24 +41,23 @@ export function resolveTspConfigUrl(configUrl: string): {
3041
commit: res.groups!["commit"]!,
3142
repo: res.groups!["repo"]!,
3243
path: res.groups!["path"]!,
33-
}
44+
};
3445
} else {
3546
throw new Error(`Invalid tspconfig.yaml url: ${configUrl}`);
3647
}
3748
}
3849

39-
4050
export async function discoverMainFile(srcDir: string): Promise<string> {
41-
Logger.debug(`Discovering entry file in ${srcDir}`)
51+
Logger.debug(`Discovering entry file in ${srcDir}`);
4252
let entryTsp = "";
43-
const files = await readdir(srcDir, {recursive: true });
53+
const files = await readdir(srcDir, { recursive: true });
4454
for (const file of files) {
4555
if (file.includes("client.tsp") || file.includes("main.tsp")) {
4656
entryTsp = file;
4757
Logger.debug(`Found entry file: ${entryTsp}`);
4858
return entryTsp;
4959
}
50-
};
60+
}
5161
throw new Error(`No main.tsp or client.tsp found`);
5262
}
5363

@@ -73,7 +83,7 @@ export async function compileTsp({
7383
"emitter-output-dir": outputDir,
7484
},
7585
};
76-
const emitterOverrideOptions = overrideOptions[emitterPackage] ?? {[emitterPackage]: {}};
86+
const emitterOverrideOptions = overrideOptions[emitterPackage] ?? { [emitterPackage]: {} };
7787
if (saveInputs) {
7888
emitterOverrideOptions["save-inputs"] = "true";
7989
}
@@ -98,21 +108,44 @@ export async function compileTsp({
98108
});
99109
Logger.debug(`Compiler options: ${JSON.stringify(options)}`);
100110
if (diagnostics.length > 0) {
111+
let errorDiagnostic = false;
101112
// This should not happen, but if it does, we should log it.
102-
Logger.error("Diagnostics were reported while resolving compiler options. Use the `--debug` flag to see the diagnostic output.")
103-
diagnostics.forEach((diagnostic) => { Logger.debug(formatDiagnostic(diagnostic)); });
104-
return false;
113+
Logger.warn(
114+
"Diagnostics were reported while resolving compiler options. Use the `--debug` flag to see if there is warning diagnostic output.",
115+
);
116+
for (const diagnostic of diagnostics) {
117+
if (diagnostic.severity === "error") {
118+
Logger.error(formatDiagnostic(diagnostic));
119+
errorDiagnostic = true;
120+
} else {
121+
Logger.debug(formatDiagnostic(diagnostic));
122+
}
123+
}
124+
if (errorDiagnostic) {
125+
return false;
126+
}
105127
}
106128

107129
const program = await compile(NodeHost, resolvedMainFilePath, options);
108130

109131
if (program.diagnostics.length > 0) {
110-
Logger.error("Diagnostics were reported during compilation. Use the `--debug` flag to see the diagnostic output.");
111-
program.diagnostics.forEach((diagnostic) => { Logger.debug(formatDiagnostic(diagnostic)); });
112-
return false;
113-
} else {
114-
Logger.success("generation complete");
132+
let errorDiagnostic = false;
133+
Logger.warn(
134+
"Diagnostics were reported during compilation. Use the `--debug` flag to see if there is warning diagnostic output.",
135+
);
136+
for (const diagnostic of program.diagnostics) {
137+
if (diagnostic.severity === "error") {
138+
Logger.error(formatDiagnostic(diagnostic));
139+
errorDiagnostic = true;
140+
} else {
141+
Logger.debug(formatDiagnostic(diagnostic));
142+
}
143+
}
144+
if (errorDiagnostic) {
145+
return false;
146+
}
115147
}
148+
Logger.success("generation complete");
116149
return true;
117150
}
118151

0 commit comments

Comments
 (0)