From e36df149ffac0d3a9b93886cd17373e5b4137445 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 31 Oct 2025 20:16:36 +0000 Subject: [PATCH 1/4] Initial plan From 989d17df57968b84e24baeeafd61a28b7301bc4d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 31 Oct 2025 20:25:31 +0000 Subject: [PATCH 2/4] Update plugin loading to use 'plugins' property in package.json Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> --- .../client/csharp/SampleService/package.json | 4 +- .../src/StartUp/GeneratorHandler.cs | 20 +++- .../test/StartUp/GeneratorHandlerTests.cs | 94 ++++++++++++++++++- 3 files changed, 111 insertions(+), 7 deletions(-) diff --git a/docs/samples/client/csharp/SampleService/package.json b/docs/samples/client/csharp/SampleService/package.json index cc47cb4f876..3b622e021f2 100644 --- a/docs/samples/client/csharp/SampleService/package.json +++ b/docs/samples/client/csharp/SampleService/package.json @@ -1,6 +1,8 @@ { "dependencies": { - "@typespec/http-client-csharp": "1.0.0-alpha.20250923.2", + "@typespec/http-client-csharp": "1.0.0-alpha.20250923.2" + }, + "plugins": { "logging-plugin": "file:../plugins/logging" } } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/StartUp/GeneratorHandler.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/StartUp/GeneratorHandler.cs index 7c68b51533a..b2b4b0aec60 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/StartUp/GeneratorHandler.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/StartUp/GeneratorHandler.cs @@ -102,21 +102,31 @@ internal static IList GetOrderedPluginDlls(string pluginDirectoryStart) } using var doc = JsonDocument.Parse(File.ReadAllText(packagePath)); - if (!doc.RootElement.TryGetProperty("dependencies", out var deps)) + if (!doc.RootElement.TryGetProperty("plugins", out var plugins)) { return dllPathsInOrder; } - var packageNamesInOrder = deps.EnumerateObject().Select(p => p.Name).ToList(); + var packageNamesInOrder = plugins.EnumerateObject().Select(p => p.Name).ToList(); + + // We need to construct the emitter independently as the CodeModelGenerator is not yet initialized. + using var emitter = new Emitter(Console.OpenStandardOutput()); foreach (var package in packageNamesInOrder) { var packageDistPath = Path.Combine(rootDirectory, NodeModulesDir, package, "dist"); - if (Directory.Exists(packageDistPath)) + if (!Directory.Exists(packageDistPath)) { - var dlls = Directory.EnumerateFiles(packageDistPath, "*.dll", SearchOption.AllDirectories); - dllPathsInOrder.AddRange(dlls); + throw new InvalidOperationException($"Plugin '{package}' specified in package.json but its dist directory was not found at '{packageDistPath}'."); } + + var dlls = Directory.EnumerateFiles(packageDistPath, "*.dll", SearchOption.AllDirectories).ToList(); + if (dlls.Count == 0) + { + throw new InvalidOperationException($"Plugin '{package}' specified in package.json but no DLL files were found in '{packageDistPath}'."); + } + + dllPathsInOrder.AddRange(dlls); } return dllPathsInOrder; diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/StartUp/GeneratorHandlerTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/StartUp/GeneratorHandlerTests.cs index 45f98adace2..a1b9f6346b0 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/StartUp/GeneratorHandlerTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/StartUp/GeneratorHandlerTests.cs @@ -167,7 +167,7 @@ public void GetOrderedPluginDlls() ""name"": ""dummy-project"", ""version"": ""1.0.0"", ""description"": ""Dummy project for testing purposes."", - ""dependencies"": { ""plugin-1"": ""^1.0.0"", ""plugin-2"": ""^2.0.0"" } + ""plugins"": { ""plugin-1"": ""^1.0.0"", ""plugin-2"": ""^2.0.0"" } }"); File.WriteAllText(Path.Combine(plugin1Directory, "Plugin1.dll"), "Dummy DLL content"); @@ -184,5 +184,97 @@ public void GetOrderedPluginDlls() File.Delete(Path.Combine(plugin2Directory, "Plugin2.dll")); } } + + [Test] + public void GetOrderedPluginDlls_ThrowsIfPluginDirectoryNotFound() + { + var testRoot = TestContext.CurrentContext.TestDirectory; + var pluginDirectory = Path.Combine(testRoot, "node_modules", "missing-plugin", "dist"); + try + { + File.WriteAllText(Path.Combine(testRoot, "package.json"), @"{ + ""name"": ""dummy-project"", + ""version"": ""1.0.0"", + ""description"": ""Dummy project for testing purposes."", + ""plugins"": { ""missing-plugin"": ""^1.0.0"" } + }"); + + var ex = Assert.Throws(() => + GeneratorHandler.GetOrderedPluginDlls(pluginDirectory)); + + Assert.That(ex!.Message, Does.Contain("missing-plugin")); + Assert.That(ex.Message, Does.Contain("dist directory was not found")); + } + finally + { + // Cleanup + var packageJsonPath = Path.Combine(testRoot, "package.json"); + if (File.Exists(packageJsonPath)) + { + File.Delete(packageJsonPath); + } + } + } + + [Test] + public void GetOrderedPluginDlls_ThrowsIfPluginDllNotFound() + { + var testRoot = TestContext.CurrentContext.TestDirectory; + var pluginDirectory = Path.Combine(testRoot, "node_modules", "empty-plugin", "dist"); + try + { + Directory.CreateDirectory(pluginDirectory); + + File.WriteAllText(Path.Combine(testRoot, "package.json"), @"{ + ""name"": ""dummy-project"", + ""version"": ""1.0.0"", + ""description"": ""Dummy project for testing purposes."", + ""plugins"": { ""empty-plugin"": ""^1.0.0"" } + }"); + + var ex = Assert.Throws(() => + GeneratorHandler.GetOrderedPluginDlls(pluginDirectory)); + + Assert.That(ex!.Message, Does.Contain("empty-plugin")); + Assert.That(ex.Message, Does.Contain("no DLL files were found")); + } + finally + { + // Cleanup + var packageJsonPath = Path.Combine(testRoot, "package.json"); + if (File.Exists(packageJsonPath)) + { + File.Delete(packageJsonPath); + } + } + } + + [Test] + public void GetOrderedPluginDlls_ReturnsEmptyListWhenNoPluginsProperty() + { + var testRoot = TestContext.CurrentContext.TestDirectory; + try + { + File.WriteAllText(Path.Combine(testRoot, "package.json"), @"{ + ""name"": ""dummy-project"", + ""version"": ""1.0.0"", + ""description"": ""Dummy project for testing purposes."", + ""dependencies"": { ""some-dep"": ""^1.0.0"" } + }"); + + var dlls = GeneratorHandler.GetOrderedPluginDlls(testRoot); + + Assert.AreEqual(0, dlls.Count); + } + finally + { + // Cleanup + var packageJsonPath = Path.Combine(testRoot, "package.json"); + if (File.Exists(packageJsonPath)) + { + File.Delete(packageJsonPath); + } + } + } } } From 92b31337d357c03a331a38d6a30651ce4c13bc1b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 31 Oct 2025 20:28:58 +0000 Subject: [PATCH 3/4] Remove unused emitter variable from GetOrderedPluginDlls Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> --- .../src/StartUp/GeneratorHandler.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/StartUp/GeneratorHandler.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/StartUp/GeneratorHandler.cs index b2b4b0aec60..dfa43667339 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/StartUp/GeneratorHandler.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/StartUp/GeneratorHandler.cs @@ -109,9 +109,6 @@ internal static IList GetOrderedPluginDlls(string pluginDirectoryStart) var packageNamesInOrder = plugins.EnumerateObject().Select(p => p.Name).ToList(); - // We need to construct the emitter independently as the CodeModelGenerator is not yet initialized. - using var emitter = new Emitter(Console.OpenStandardOutput()); - foreach (var package in packageNamesInOrder) { var packageDistPath = Path.Combine(rootDirectory, NodeModulesDir, package, "dist"); From 9d7debf62ff05015d67a89bbf883d6a3531fb3a2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Nov 2025 19:38:01 +0000 Subject: [PATCH 4/4] Revert changes to SampleService package.json Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> --- docs/samples/client/csharp/SampleService/package.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/samples/client/csharp/SampleService/package.json b/docs/samples/client/csharp/SampleService/package.json index 3b622e021f2..cc47cb4f876 100644 --- a/docs/samples/client/csharp/SampleService/package.json +++ b/docs/samples/client/csharp/SampleService/package.json @@ -1,8 +1,6 @@ { "dependencies": { - "@typespec/http-client-csharp": "1.0.0-alpha.20250923.2" - }, - "plugins": { + "@typespec/http-client-csharp": "1.0.0-alpha.20250923.2", "logging-plugin": "file:../plugins/logging" } }