Skip to content

Commit f491a67

Browse files
authored
Merge branch 'main' into copilot/add-python-test-case
2 parents ec9d375 + d3cdadd commit f491a67

26 files changed

Lines changed: 459 additions & 24 deletions

File tree

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
changeKind: feature
3+
packages:
4+
- "@typespec/http-specs"
5+
---
6+
7+
Add scenario for an operation whose successful response is either a model body (`200`) or no content (`204`).
8+
9+
```tsp
10+
op getBody(): {
11+
@statusCode statusCode: 200;
12+
@body layout: BlobLayout;
13+
} | {
14+
@statusCode statusCode: 204;
15+
};
16+
```
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
changeKind: feature
3+
packages:
4+
- "@typespec/http-client"
5+
---
6+
7+
Add diagnostic and dependency metadata to `@experimental`.
8+
9+
```typespec
10+
@experimental(#{ diagnosticId: "C", dependsOn: #["A", "B"] })
11+
op bar(): void;
12+
```
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
changeKind: fix
3+
packages:
4+
- "@typespec/playground"
5+
---
6+
7+
Preserve a sample's preferred emitter and compiler options when loading it in the playground.

docker/Dockerfile

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,16 @@ COPY . /app
1212
# && tdnf clean all
1313

1414
WORKDIR /app
15-
RUN npm install -g pnpm
16-
RUN pnpm install --filter "@typespec/compiler..."
15+
16+
# Install exact version of pnpm to avoid problems with private registries
17+
RUN --mount=type=secret,id=npmrc \
18+
NPM_CONFIG_USERCONFIG=/run/secrets/npmrc \
19+
npm install -g $(node -p "require('./package.json').packageManager")
20+
21+
RUN --mount=type=secret,id=npmrc \
22+
NPM_CONFIG_USERCONFIG=/run/secrets/npmrc \
23+
pnpm install --filter "@typespec/compiler..."
24+
1725
RUN pnpm --filter "@typespec/compiler..." run build
1826

1927
WORKDIR /app/packages/compiler
@@ -26,6 +34,8 @@ FROM mcr.microsoft.com/azurelinux/base/nodejs:24
2634

2735
COPY --from=builder /app/packages/compiler/*.tgz /tmp/compiler.tgz
2836

29-
RUN npm install -g /tmp/compiler.tgz && rm /tmp/compiler.tgz
37+
RUN --mount=type=secret,id=npmrc \
38+
NPM_CONFIG_USERCONFIG=/run/secrets/npmrc \
39+
npm install --verbose -g /tmp/compiler.tgz && rm /tmp/compiler.tgz
3040

3141
ENTRYPOINT ["tsp"]

eng/tsp-core/pipelines/publish.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,11 @@ extends:
9898
azureContainerRegistry: azsdkengsys.azurecr.io
9999
command: login
100100

101+
- template: /eng/common/pipelines/templates/steps/create-authenticated-npmrc.yml
102+
101103
- script: |
102104
docker build -f ./docker/Dockerfile \
105+
--secret id=npmrc,src="$HOME/.npmrc" \
103106
-t $(imageName):latest \
104107
.
105108
displayName: "Build"

packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/EnumProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public static EnumProvider Create(InputEnumType input, TypeProvider? declaringTy
2929
return input.IsExtensible ? extensibleEnumProvider : fixedEnumProvider;
3030
}
3131

32-
protected EnumProvider(InputEnumType? input)
32+
protected EnumProvider(InputEnumType? input) : base(input)
3333
{
3434
_inputType = input;
3535
_deprecated = input?.Deprecation;

packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using Microsoft.TypeSpec.Generator.EmitterRpc;
1010
using Microsoft.TypeSpec.Generator.Expressions;
1111
using Microsoft.TypeSpec.Generator.Input;
12+
using Microsoft.TypeSpec.Generator.Input.Extensions;
1213
using Microsoft.TypeSpec.Generator.Primitives;
1314
using Microsoft.TypeSpec.Generator.SourceInput;
1415
using Microsoft.TypeSpec.Generator.Statements;
@@ -49,10 +50,30 @@ protected TypeProvider() : this(null)
4950
_declaringTypeName.Value);
5051

5152
private protected virtual TypeProvider? BuildLastContractView(string? generatedTypeName = null, string? generatedTypeNamespace = null)
52-
=> CodeModelGenerator.Instance.SourceInputModel.FindForTypeInLastContract(
53-
generatedTypeNamespace ?? CustomCodeView?.Type.Namespace ?? BuildNamespace(),
54-
generatedTypeName ?? CustomCodeView?.Name ?? BuildName(),
53+
{
54+
var typeNamespace = generatedTypeNamespace ?? CustomCodeView?.Type.Namespace ?? BuildNamespace();
55+
var typeName = generatedTypeName ?? CustomCodeView?.Name ?? BuildName();
56+
var lastContractView = CodeModelGenerator.Instance.SourceInputModel.FindForTypeInLastContract(
57+
typeNamespace,
58+
typeName,
59+
_declaringTypeName.Value);
60+
if (lastContractView is not null || _inputType is null || _inputType.IsExactName)
61+
{
62+
return lastContractView;
63+
}
64+
65+
var originalName = _inputType.Name.ToIdentifierName();
66+
var normalizedOriginalName = originalName.NormalizeCSharpAcronyms();
67+
if (normalizedOriginalName == originalName || typeName != normalizedOriginalName)
68+
{
69+
return null;
70+
}
71+
72+
return CodeModelGenerator.Instance.SourceInputModel.FindForTypeInLastContract(
73+
typeNamespace,
74+
originalName,
5575
_declaringTypeName.Value);
76+
}
5677

5778
private static string? GetDeclaringTypeName(TypeProvider? declaringTypeProvider)
5879
{
@@ -801,9 +822,11 @@ private void ResetMembersBasedOnIdentityChange(string? name = null, string? @nam
801822
_customCodeView = new(BuildCustomCodeView(name ?? Type.Name, @namespace ?? Type.Namespace));
802823
name = _customCodeView.Value?.Name ?? name ?? Type.Name;
803824
@namespace = _customCodeView.Value?.Type.Namespace ?? @namespace ?? Type.Namespace;
804-
_lastContractView = new(BuildLastContractView(
825+
var lastContractView = BuildLastContractView(
805826
name,
806-
@namespace));
827+
@namespace);
828+
_lastContractView = new(lastContractView);
829+
name = _customCodeView.Value?.Name ?? lastContractView?.Name ?? name;
807830
// recalculate declaration modifiers and constructors
808831
_declarationModifiers = null;
809832
// constructors might change based on declaration modifier changes

packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/EnumProviders/EnumProviderTests.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,26 @@ await MockHelpers.LoadMockGeneratorAsync(
128128
Assert.AreEqual("IpKind", enumType.Name);
129129
}
130130

131+
[Test]
132+
public async Task BuildEnumType_BackCompatTakesPrecedenceAfterNamespaceUpdate()
133+
{
134+
await MockHelpers.LoadMockGeneratorAsync(
135+
createCSharpTypeCore: (inputType) => typeof(string),
136+
lastContractCompilation: async () => await Helpers.GetCompilationFromDirectoryAsync());
137+
var input = InputFactory.StringEnum(
138+
"IpKind",
139+
[("Value", "value")],
140+
clientNamespace: "Sample");
141+
142+
var enumType = EnumProvider.Create(input);
143+
Assert.AreEqual("IPKind", enumType.Name);
144+
145+
enumType.Update(@namespace: "Sample.Models");
146+
147+
Assert.AreEqual("IpKind", enumType.Name);
148+
Assert.IsNotNull(enumType.LastContractView);
149+
}
150+
131151
// Validates the api version enum
132152
[TestCase]
133153
public void BuildEnumType_ValidateApiVersionEnum()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace Sample.Models
2+
{
3+
public enum IpKind
4+
{
5+
Value
6+
}
7+
}

packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/ModelProviderTests.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,36 @@ await MockHelpers.LoadMockGeneratorAsync(
105105
Assert.IsNotNull(modelProvider.Properties.SingleOrDefault(p => p.Name == "IpAddressProperty"));
106106
}
107107

108+
[Test]
109+
public async Task TestBuildName_BackCompatTakesPrecedenceAfterNamespaceUpdate()
110+
{
111+
var inputModel = InputFactory.Model(
112+
"IpAddress",
113+
@namespace: "Sample",
114+
properties:
115+
[
116+
InputFactory.Property("dbName", InputPrimitiveType.String),
117+
InputFactory.Property("osProfile", InputPrimitiveType.String),
118+
InputFactory.Property("IpAddress", InputPrimitiveType.String)
119+
]);
120+
await MockHelpers.LoadMockGeneratorAsync(
121+
inputModelTypes: [inputModel],
122+
lastContractCompilation: async () => await Helpers.GetCompilationFromDirectoryAsync());
123+
124+
var modelProvider = CodeModelGenerator.Instance.TypeFactory.CreateModel(inputModel);
125+
126+
Assert.IsNotNull(modelProvider);
127+
Assert.AreEqual("IPAddress", modelProvider!.Name);
128+
129+
modelProvider.Update(@namespace: "Sample.Models");
130+
131+
Assert.AreEqual("IpAddress", modelProvider.Name);
132+
Assert.IsNotNull(modelProvider.LastContractView);
133+
Assert.IsNotNull(modelProvider.Properties.SingleOrDefault(p => p.Name == "DbName"));
134+
Assert.IsNotNull(modelProvider.Properties.SingleOrDefault(p => p.Name == "OSProfile"));
135+
Assert.IsNotNull(modelProvider.Properties.SingleOrDefault(p => p.Name == "IpAddressProperty"));
136+
}
137+
108138
// Validates that the property body's setter is correctly set based on the property type
109139
[TestCaseSource(nameof(BuildProperties_ValidatePropertySettersTestCases))]
110140
public void TestBuildProperties_ValidatePropertySetters(InputModelProperty inputModelProperty, CSharpType type, bool hasSetter)

0 commit comments

Comments
 (0)