Skip to content

Commit f1d2465

Browse files
author
Linh Phan
committed
2 parents 29c3f4f + a1545e8 commit f1d2465

15 files changed

Lines changed: 343 additions & 159 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
changeKind: internal
3+
packages:
4+
- "@typespec/http-client-python"
5+
---
6+
7+
Fix `run_batch.py` passing string `"true"`/`"false"` values to pygen, which caused `keep-setup-py="false"` to be treated as truthy and generate `setup.py` instead of `pyproject.toml` for all regenerated test packages.

packages/http-client-csharp/emitter/src/emit-generate.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ import {
1919
configurationFileName,
2020
tspOutputFileName,
2121
} from "./constants.js";
22+
import { execAsync, execCSharpGenerator } from "./lib/exec-utils.js";
2223
import { createDiagnostic } from "./lib/lib.js";
23-
import { execAsync, execCSharpGenerator } from "./lib/utils.js";
2424
import { CSharpEmitterContext } from "./sdk-context.js";
2525

2626
export interface GenerateOptions {

packages/http-client-csharp/emitter/src/emitter.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@
22
// Licensed under the MIT License. See License.txt in the project root for license information.
33

44
import { createSdkContext, SdkContext } from "@azure-tools/typespec-client-generator-core";
5-
import { createDiagnosticCollector, Diagnostic, EmitContext, Program } from "@typespec/compiler";
6-
import { resolve } from "path";
5+
import {
6+
createDiagnosticCollector,
7+
Diagnostic,
8+
EmitContext,
9+
Program,
10+
resolvePath,
11+
} from "@typespec/compiler";
712
import { serializeCodeModel } from "./code-model-writer.js";
813
import { generate } from "./emit-generate.js";
914
import { createModel } from "./lib/client-model-builder.js";
@@ -49,7 +54,7 @@ export async function emitCodeModel(
4954

5055
// Resolve plugin paths to absolute if specified
5156
if (options["plugins"]) {
52-
options["plugins"] = options["plugins"].map((p) => resolve(outputFolder, p));
57+
options["plugins"] = options["plugins"].map((p) => resolvePath(outputFolder, p));
5358
}
5459

5560
/* set the log level. */
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
// Node.js-only helpers that wrap `child_process`. These are kept in a separate
5+
// file so that browser bundles (which do not support `child_process`) do not
6+
// pull them in transitively via `lib/utils.ts`.
7+
8+
import { NoTarget, Type } from "@typespec/compiler";
9+
import { spawn, SpawnOptions } from "child_process";
10+
import { CSharpEmitterContext } from "../sdk-context.js";
11+
12+
export async function execCSharpGenerator(
13+
context: CSharpEmitterContext,
14+
options: {
15+
generatorPath: string;
16+
outputFolder: string;
17+
generatorName: string;
18+
newProject: boolean;
19+
debug: boolean;
20+
},
21+
): Promise<{ exitCode: number; stderr: string; proc: any }> {
22+
const command = "dotnet";
23+
const args = [
24+
"--roll-forward",
25+
"Major",
26+
options.generatorPath,
27+
options.outputFolder,
28+
"-g",
29+
options.generatorName,
30+
];
31+
if (options.newProject) {
32+
args.push("--new-project");
33+
}
34+
if (options.debug) {
35+
args.push("--debug");
36+
}
37+
context.logger.info(`${command} ${args.join(" ")}`);
38+
39+
const child = spawn(command, args, { stdio: "pipe" });
40+
41+
const stderr: Buffer[] = [];
42+
return new Promise((resolve, reject) => {
43+
let buffer = "";
44+
45+
child.stdout?.on("data", (data) => {
46+
buffer += data.toString();
47+
let index;
48+
while ((index = buffer.indexOf("\n")) !== -1) {
49+
const message = buffer.slice(0, index);
50+
buffer = buffer.slice(index + 1);
51+
processJsonRpc(context, message);
52+
}
53+
});
54+
55+
child.stderr?.on("data", (data) => {
56+
stderr.push(data);
57+
});
58+
59+
child.on("error", (error) => {
60+
reject(error);
61+
});
62+
63+
child.on("exit", (exitCode) => {
64+
resolve({
65+
exitCode: exitCode ?? -1,
66+
stderr: Buffer.concat(stderr).toString(),
67+
proc: child,
68+
});
69+
});
70+
});
71+
}
72+
73+
function processJsonRpc(context: CSharpEmitterContext, message: string) {
74+
const response = JSON.parse(message);
75+
const method = response.method;
76+
const params = response.params;
77+
switch (method) {
78+
case "trace":
79+
context.logger.trace(params.level, params.message);
80+
break;
81+
case "diagnostic":
82+
let crossLanguageDefinitionId: string | undefined;
83+
if ("crossLanguageDefinitionId" in params) {
84+
crossLanguageDefinitionId = params.crossLanguageDefinitionId;
85+
}
86+
// Use program.reportDiagnostic for diagnostics from C# so that we don't
87+
// have to duplicate the codes in the emitter.
88+
context.program.reportDiagnostic({
89+
code: params.code,
90+
message: params.message,
91+
severity: params.severity,
92+
target: findTarget(crossLanguageDefinitionId) ?? NoTarget,
93+
});
94+
break;
95+
}
96+
97+
function findTarget(crossLanguageDefinitionId: string | undefined): Type | undefined {
98+
if (crossLanguageDefinitionId === undefined) {
99+
return undefined;
100+
}
101+
return context.__typeCache.crossLanguageDefinitionIds.get(crossLanguageDefinitionId);
102+
}
103+
}
104+
105+
export async function execAsync(
106+
command: string,
107+
args: string[] = [],
108+
options: SpawnOptions = {},
109+
): Promise<{ exitCode: number; stdio: string; stdout: string; stderr: string; proc: any }> {
110+
const child = spawn(command, args, options);
111+
112+
return new Promise((resolve, reject) => {
113+
child.on("error", (error) => {
114+
reject(error);
115+
});
116+
const stdio: Buffer[] = [];
117+
const stdout: Buffer[] = [];
118+
const stderr: Buffer[] = [];
119+
child.stdout?.on("data", (data) => {
120+
stdout.push(data);
121+
stdio.push(data);
122+
});
123+
child.stderr?.on("data", (data) => {
124+
stderr.push(data);
125+
stdio.push(data);
126+
});
127+
128+
child.on("exit", (exitCode) => {
129+
resolve({
130+
exitCode: exitCode ?? -1,
131+
stdio: Buffer.concat(stdio).toString(),
132+
stdout: Buffer.concat(stdout).toString(),
133+
stderr: Buffer.concat(stderr).toString(),
134+
proc: child,
135+
});
136+
});
137+
});
138+
}

packages/http-client-csharp/emitter/src/lib/utils.ts

Lines changed: 1 addition & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -7,139 +7,10 @@ import {
77
SdkModelPropertyType,
88
isReadOnly as tcgcIsReadOnly,
99
} from "@azure-tools/typespec-client-generator-core";
10-
import { getNamespaceFullName, Namespace, NoTarget, Type } from "@typespec/compiler";
10+
import { getNamespaceFullName, Namespace } from "@typespec/compiler";
1111
import { Visibility } from "@typespec/http";
12-
import { spawn, SpawnOptions } from "child_process";
1312
import { CSharpEmitterContext } from "../sdk-context.js";
1413

15-
export async function execCSharpGenerator(
16-
context: CSharpEmitterContext,
17-
options: {
18-
generatorPath: string;
19-
outputFolder: string;
20-
generatorName: string;
21-
newProject: boolean;
22-
debug: boolean;
23-
},
24-
): Promise<{ exitCode: number; stderr: string; proc: any }> {
25-
const command = "dotnet";
26-
const args = [
27-
"--roll-forward",
28-
"Major",
29-
options.generatorPath,
30-
options.outputFolder,
31-
"-g",
32-
options.generatorName,
33-
];
34-
if (options.newProject) {
35-
args.push("--new-project");
36-
}
37-
if (options.debug) {
38-
args.push("--debug");
39-
}
40-
context.logger.info(`${command} ${args.join(" ")}`);
41-
42-
const child = spawn(command, args, { stdio: "pipe" });
43-
44-
const stderr: Buffer[] = [];
45-
return new Promise((resolve, reject) => {
46-
let buffer = "";
47-
48-
child.stdout?.on("data", (data) => {
49-
buffer += data.toString();
50-
let index;
51-
while ((index = buffer.indexOf("\n")) !== -1) {
52-
const message = buffer.slice(0, index);
53-
buffer = buffer.slice(index + 1);
54-
processJsonRpc(context, message);
55-
}
56-
});
57-
58-
child.stderr?.on("data", (data) => {
59-
stderr.push(data);
60-
});
61-
62-
child.on("error", (error) => {
63-
reject(error);
64-
});
65-
66-
child.on("exit", (exitCode) => {
67-
resolve({
68-
exitCode: exitCode ?? -1,
69-
stderr: Buffer.concat(stderr).toString(),
70-
proc: child,
71-
});
72-
});
73-
});
74-
}
75-
76-
function processJsonRpc(context: CSharpEmitterContext, message: string) {
77-
const response = JSON.parse(message);
78-
const method = response.method;
79-
const params = response.params;
80-
switch (method) {
81-
case "trace":
82-
context.logger.trace(params.level, params.message);
83-
break;
84-
case "diagnostic":
85-
let crossLanguageDefinitionId: string | undefined;
86-
if ("crossLanguageDefinitionId" in params) {
87-
crossLanguageDefinitionId = params.crossLanguageDefinitionId;
88-
}
89-
// Use program.reportDiagnostic for diagnostics from C# so that we don't
90-
// have to duplicate the codes in the emitter.
91-
context.program.reportDiagnostic({
92-
code: params.code,
93-
message: params.message,
94-
severity: params.severity,
95-
target: findTarget(crossLanguageDefinitionId) ?? NoTarget,
96-
});
97-
break;
98-
}
99-
100-
function findTarget(crossLanguageDefinitionId: string | undefined): Type | undefined {
101-
if (crossLanguageDefinitionId === undefined) {
102-
return undefined;
103-
}
104-
return context.__typeCache.crossLanguageDefinitionIds.get(crossLanguageDefinitionId);
105-
}
106-
}
107-
108-
export async function execAsync(
109-
command: string,
110-
args: string[] = [],
111-
options: SpawnOptions = {},
112-
): Promise<{ exitCode: number; stdio: string; stdout: string; stderr: string; proc: any }> {
113-
const child = spawn(command, args, options);
114-
115-
return new Promise((resolve, reject) => {
116-
child.on("error", (error) => {
117-
reject(error);
118-
});
119-
const stdio: Buffer[] = [];
120-
const stdout: Buffer[] = [];
121-
const stderr: Buffer[] = [];
122-
child.stdout?.on("data", (data) => {
123-
stdout.push(data);
124-
stdio.push(data);
125-
});
126-
child.stderr?.on("data", (data) => {
127-
stderr.push(data);
128-
stdio.push(data);
129-
});
130-
131-
child.on("exit", (exitCode) => {
132-
resolve({
133-
exitCode: exitCode ?? -1,
134-
stdio: Buffer.concat(stdio).toString(),
135-
stdout: Buffer.concat(stdout).toString(),
136-
stderr: Buffer.concat(stderr).toString(),
137-
proc: child,
138-
});
139-
});
140-
});
141-
}
142-
14314
export function getClientNamespaceString(context: CSharpEmitterContext): string | undefined {
14415
const packageName = context.emitContext.options["package-name"];
14516
const serviceNamespaces = listAllServiceNamespaces(context);

packages/http-client-csharp/emitter/test/Unit/emitter.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { EmitContext, Program } from "@typespec/compiler";
44
import { TestHost } from "@typespec/compiler/testing";
55
import { beforeEach, describe, expect, it, vi } from "vitest";
66
import { generate } from "../../src/emit-generate.js";
7-
import { execAsync, execCSharpGenerator } from "../../src/lib/utils.js";
7+
import { execAsync, execCSharpGenerator } from "../../src/lib/exec-utils.js";
88
import { CSharpEmitterOptions } from "../../src/options.js";
99
import { CodeModel } from "../../src/type/code-model.js";
1010
import {
@@ -54,7 +54,7 @@ describe("$onEmit tests", () => {
5454
}),
5555
}));
5656

57-
vi.mock("../../src/lib/utils.js", () => ({
57+
vi.mock("../../src/lib/exec-utils.js", () => ({
5858
execCSharpGenerator: vi.fn(),
5959
execAsync: vi.fn(),
6060
}));

packages/http-client-csharp/emitter/test/Unit/utils.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { listAllServiceNamespaces } from "@azure-tools/typespec-client-generator
22
import * as childProcess from "child_process";
33
import { EventEmitter } from "events";
44
import { beforeEach, describe, expect, it, vi } from "vitest";
5-
import { execCSharpGenerator, getClientNamespaceStringHelper } from "../../src/lib/utils.js";
5+
import { execCSharpGenerator } from "../../src/lib/exec-utils.js";
6+
import { getClientNamespaceStringHelper } from "../../src/lib/utils.js";
67
import { CSharpEmitterContext } from "../../src/sdk-context.js";
78
import {
89
createCSharpSdkContext,

packages/http-client-csharp/emitter/test/Unit/validate-dotnet-sdk.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Diagnostic, Program } from "@typespec/compiler";
44
import { TestHost } from "@typespec/compiler/testing";
55
import { strictEqual } from "assert";
66
import { beforeEach, describe, expect, it, Mock, vi } from "vitest";
7-
import { execAsync } from "../../src/lib/utils.js";
7+
import { execAsync } from "../../src/lib/exec-utils.js";
88
import {
99
createCSharpSdkContext,
1010
createEmitterContext,
@@ -33,7 +33,7 @@ describe("Test _validateDotNetSdk", () => {
3333
);
3434
// Restore all mocks before each test
3535
vi.restoreAllMocks();
36-
vi.mock("../../src/lib/utils.js", () => ({
36+
vi.mock("../../src/lib/exec-utils.js", () => ({
3737
execCSharpGenerator: vi.fn(),
3838
execAsync: vi.fn(),
3939
}));

0 commit comments

Comments
 (0)