Skip to content

Commit fa5e4bd

Browse files
Support model-namespace option (Azure#49518)
* Support model-namespace option * PR fb * Flip default * regen
1 parent 32912cb commit fa5e4bd

File tree

200 files changed

+455
-398
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

200 files changed

+455
-398
lines changed

eng/Packages.Data.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@
206206
</ItemGroup>
207207

208208
<ItemGroup Condition="'$(IsGeneratorLibrary)' == 'true'">
209-
<PackageReference Update="Microsoft.TypeSpec.Generator.ClientModel" Version="1.0.0-alpha.20250418.3" />
209+
<PackageReference Update="Microsoft.TypeSpec.Generator.ClientModel" Version="1.0.0-alpha.20250421.4" />
210210
<PackageReference Update="System.ClientModel" Version="1.3.0" />
211211
</ItemGroup>
212212

eng/packages/http-client-csharp-mgmt/package.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
{
22
"name": "@azure-typespec/http-client-csharp-mgmt",
33
"version": "1.0.0",
4+
"author": "Microsoft Corporation",
5+
"description": "TypeSpec library for emitting Azure management libraries for C#.",
6+
"readme": "https://github.com/Azure/azure-sdk-for-net/blob/main/eng/packages/http-client-csharp-mgmt/README.md",
7+
"license": "MIT",
8+
"repository": {
9+
"type": "git",
10+
"url": "git+https://github.com/azure-sdk/azure-sdk-for-net.git"
11+
},
12+
"bugs": {
13+
"url": "https://github.com/azure-sdk/azure-sdk-for-net/issues"
14+
},
415
"type": "module",
516
"main": "dist/emitter/index.js",
617
"exports": {

eng/packages/http-client-csharp/README.md

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# @azure-typespec/http-client-csharp
22

3+
TypeSpec library for emitting Azure libraries for C#.
4+
35
## Install
46

57
```bash
@@ -59,12 +61,6 @@ Defines the strategy on how to handle unreferenced types. The default value is `
5961

6062
Set to `true` to overwrite the csproj if it already exists. The default value is `false`.
6163

62-
### `clear-output-folder`
63-
64-
**Type:** `boolean`
65-
66-
Indicates if you want to clear the output folder before generating. The default value is `true`.
67-
6864
### `save-inputs`
6965

7066
**Type:** `boolean`
@@ -135,4 +131,4 @@ The C# namespace to use for the generated code. This will override the TypeSpec
135131

136132
**Type:** `boolean`
137133

138-
Whether to put models under a separate 'Models' sub-namespace. This only applies if the 'namespace' option is set. The default value is 'true' when the 'namespace' option is set. Otherwise, each model will be in the corresponding namespace defined in the TypeSpec.
134+
Whether to put models under a separate 'Models' sub-namespace. This only applies if the 'namespace' option is set. The default value is 'false'.

eng/packages/http-client-csharp/docs/emitter.md

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,6 @@ Defines the strategy on how to handle unreferenced types. The default value is `
5555

5656
Set to `true` to overwrite the csproj if it already exists. The default value is `false`.
5757

58-
### `clear-output-folder`
59-
60-
**Type:** `boolean`
61-
62-
Indicates if you want to clear the output folder before generating. The default value is `true`.
63-
6458
### `save-inputs`
6559

6660
**Type:** `boolean`
@@ -131,4 +125,4 @@ The C# namespace to use for the generated code. This will override the TypeSpec
131125

132126
**Type:** `boolean`
133127

134-
Whether to put models under a separate 'Models' sub-namespace. This only applies if the 'namespace' option is set. The default value is 'true' when the 'namespace' option is set. Otherwise, each model will be in the corresponding namespace defined in the TypeSpec.
128+
Whether to put models under a separate 'Models' sub-namespace. This only applies if the 'namespace' option is set. The default value is 'false'.

eng/packages/http-client-csharp/docs/index.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ toc_max_heading_level: 3
77

88
import { Tabs, TabItem } from '@astrojs/starlight/components';
99

10+
TypeSpec library for emitting Azure libraries for C#.
11+
1012
## Install
1113

1214
<Tabs>
Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License. See License.txt in the project root for license information.
33

4-
import { EmitContext } from "@typespec/compiler";
4+
import { EmitContext, NoTarget } from "@typespec/compiler";
55

66
import { $onEmit as $onMTGEmit } from "@typespec/http-client-csharp";
77
import { AzureEmitterOptions } from "./options.js";
8+
import { $lib } from "./lib/lib.js";
89

910
export async function $onEmit(context: EmitContext<AzureEmitterOptions>) {
1011
context.options["generator-name"] ??= "AzureClientGenerator";
@@ -13,5 +14,14 @@ export async function $onEmit(context: EmitContext<AzureEmitterOptions>) {
1314
name: "MIT License",
1415
company: "Microsoft Corporation"
1516
};
17+
18+
// warn if use-model-namespaces is true, but namespace is not set
19+
if (context.options["model-namespace"] && !context.options["namespace"]) {
20+
$lib.reportDiagnostic(context.program, {
21+
code: "invalid-model-namespace-usage",
22+
target: NoTarget,
23+
});
24+
}
25+
1626
await $onMTGEmit(context);
1727
}

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,29 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License. See License.txt in the project root for license information.
33

4-
import { createTypeSpecLibrary } from "@typespec/compiler";
4+
import {
5+
createTypeSpecLibrary,
6+
DiagnosticDefinition,
7+
DiagnosticMessages
8+
} from "@typespec/compiler";
59
import { $lib as httpClientCSharpLib } from "@typespec/http-client-csharp";
610
import { AzureEmitterOptionsSchema } from "../options.js";
711

12+
const diags: { [code: string]: DiagnosticDefinition<DiagnosticMessages> } = {
13+
...httpClientCSharpLib.diagnostics,
14+
"invalid-model-namespace-usage": {
15+
severity: "warning",
16+
messages: {
17+
default:
18+
"The 'model-namespace' option is set to true, but the 'namespace' option is not set. " +
19+
"'model-namespace' can only be true, if the 'namespace' option is."
20+
}
21+
}
22+
};
23+
824
export const $lib = createTypeSpecLibrary({
925
name: "@azure-typespec/http-client-csharp",
10-
diagnostics: httpClientCSharpLib.diagnostics,
26+
diagnostics: diags,
1127
emitter: {
1228
options: AzureEmitterOptionsSchema
1329
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export const AzureEmitterOptionsSchema: JSONSchemaType<AzureEmitterOptions> = {
2828
nullable: true,
2929
description:
3030
"Whether to put models under a separate 'Models' sub-namespace. This only applies if the 'namespace' option is set. " +
31-
" The default value is 'true' when the 'namespace' option is set. Otherwise, each model will be in the corresponding namespace defined in the TypeSpec."
31+
" The default value is 'false'."
3232
}
3333
},
3434
required: []
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { Program } from "@typespec/compiler";
2+
import { beforeEach, describe, it } from "vitest";
3+
import {
4+
createEmitterContext,
5+
createEmitterTestHost,
6+
typeSpecCompile
7+
} from "./test-util.js";
8+
import { AzureEmitterOptions } from "../../src/options.js";
9+
import { $onEmit } from "../../src/emitter.js";
10+
import { strictEqual } from "assert";
11+
12+
describe("Configuration tests", async () => {
13+
let program: Program;
14+
15+
beforeEach(async () => {
16+
const runner = await createEmitterTestHost();
17+
program = await typeSpecCompile(
18+
`
19+
`,
20+
runner
21+
);
22+
});
23+
24+
it("Diagnostic is logged when model-namespace is set without namespace", async () => {
25+
const options: AzureEmitterOptions = {
26+
"model-namespace": true
27+
};
28+
const context = createEmitterContext(program, options);
29+
$onEmit(context);
30+
strictEqual(program.diagnostics.length, 1);
31+
strictEqual(
32+
program.diagnostics[0].code,
33+
"@azure-typespec/http-client-csharp/invalid-model-namespace-usage"
34+
);
35+
});
36+
it("Diagnostic is NOT logged when model-namespace AND namespace are set", async () => {
37+
const options: AzureEmitterOptions = {
38+
"model-namespace": true,
39+
namespace: "Azure.Testing"
40+
};
41+
const context = createEmitterContext(program, options);
42+
$onEmit(context);
43+
strictEqual(program.diagnostics.length, 0);
44+
});
45+
it("Diagnostic is NOT logged when NEITHER model-namespace NOR namespace are set", async () => {
46+
const context = createEmitterContext(program);
47+
$onEmit(context);
48+
strictEqual(program.diagnostics.length, 0);
49+
});
50+
});

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

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { HttpTestLibrary } from "@typespec/http/testing";
1616
import { RestTestLibrary } from "@typespec/rest/testing";
1717
import { VersioningTestLibrary } from "@typespec/versioning/testing";
1818
import { XmlTestLibrary } from "@typespec/xml/testing";
19+
import { AzureEmitterOptions } from "../../src/options.js";
1920

2021
export async function createEmitterTestHost(): Promise<TestHost> {
2122
return createTestHost({
@@ -89,12 +90,13 @@ export async function typeSpecCompile(
8990
}
9091

9192
export function createEmitterContext(
92-
program: Program
93+
program: Program,
94+
options: AzureEmitterOptions = {}
9395
): EmitContext<CSharpEmitterOptions> {
9496
return {
9597
program: program,
9698
emitterOutputDir: "./",
97-
options: {
99+
options: options ?? {
98100
outputFile: "tspCodeModel.json",
99101
logFile: "log.json",
100102
"new-project": false,
@@ -109,7 +111,7 @@ export function createEmitterContext(
109111

110112
/* We always need to pass in the emitter name now that it is required so making a helper to do this. */
111113
export async function createCSharpSdkContext(
112-
program: EmitContext<CSharpEmitterOptions>,
114+
program: EmitContext<AzureEmitterOptions>,
113115
sdkContextOptions: CreateSdkContextOptions = {}
114116
): Promise<CSharpEmitterContext> {
115117
const context = await createSdkContext(
@@ -125,7 +127,19 @@ export async function createCSharpSdkContext(
125127
types: new Map(),
126128
models: new Map(),
127129
enums: new Map(),
128-
clients: new Map()
130+
clients: new Map(),
131+
properties: new Map(),
132+
responses: new Map(),
133+
updateSdkClientReferences: (sdkClient, inputClient) => {
134+
},
135+
updateSdkPropertyReferences: (sdkProperty, inputProperty) => {
136+
},
137+
updateSdkResponseReferences: (sdkResponse, response) => {
138+
},
139+
updateSdkTypeReferences: (sdkType, inputType) => {
140+
},
141+
updateTypeCache: (typeName, type) => {
142+
}
129143
}
130144
};
131145
}

0 commit comments

Comments
 (0)