public static async Task <ProjectMetadata> GetProjectMetadata( string file, string buildExtensionsDir, string framework, string configuration, string runtime, bool noBuild, IConsoleHost console = null) { Debug.Assert(!string.IsNullOrEmpty(file), "file is null or empty."); if (buildExtensionsDir == null) { buildExtensionsDir = Path.Combine(Path.GetDirectoryName(file), "obj"); } Directory.CreateDirectory(buildExtensionsDir); var targetsPath = Path.Combine( buildExtensionsDir, Path.GetFileName(file) + ".NSwag.targets"); var type = typeof(ProjectMetadata).GetTypeInfo(); using (var input = type.Assembly.GetManifestResourceStream($"NSwag.Commands.Commands.SwaggerGeneration.AspNetCore.AspNetCore.targets")) using (var output = File.Open(targetsPath, FileMode.Create, FileAccess.Write, FileShare.Write)) { // NB: Copy always in case it changes input.CopyTo(output); } IDictionary <string, string> metadata; var metadataFile = Path.GetTempFileName(); try { var args = new List <string> { "msbuild", "/nologo", "/verbosity:quiet", "/p:NSwagOutputMetadataFile=" + metadataFile }; if (!noBuild) { args.Add("/t:Build"); } args.Add("/t:" + GetMetadataTarget); if (framework != null) { args.Add("/p:TargetFramework=" + framework); } if (configuration != null) { args.Add("/p:Configuration=" + configuration); } if (runtime != null) { args.Add("/p:RuntimeIdentifier=" + runtime); } if (file != null) { args.Add(file); } var exitCode = await Exe.RunAsync("dotnet", args, console : console).ConfigureAwait(false); if (exitCode != 0) { throw new InvalidOperationException("Unable to retrieve project metadata. Ensure it's an MSBuild-based .NET Core project." + "If you're using custom BaseIntermediateOutputPath or MSBuildProjectExtensionsPath values, Use the --msbuildprojectextensionspath option."); } if (console != null) { console.WriteMessage("Done executing command" + Environment.NewLine); console.WriteMessage("Output:" + Environment.NewLine + File.ReadAllText(metadataFile)); } metadata = File.ReadLines(metadataFile).Select(l => l.Split(new[] { ':' }, 2)) .ToDictionary(s => s[0], s => s[1].TrimStart()); } finally { File.Delete(metadataFile); } var platformTarget = metadata[nameof(PlatformTarget)]; if (platformTarget.Length == 0) { platformTarget = metadata["Platform"]; } var projectMetadata = new ProjectMetadata(file, framework, configuration, runtime) { AssemblyName = metadata[nameof(AssemblyName)], OutputPath = metadata[nameof(OutputPath)], PlatformTarget = platformTarget, ProjectDepsFilePath = metadata[nameof(ProjectDepsFilePath)], ProjectDir = metadata[nameof(ProjectDir)], ProjectRuntimeConfigFilePath = metadata[nameof(ProjectRuntimeConfigFilePath)], TargetFileName = metadata[nameof(TargetFileName)], TargetFrameworkIdentifier = metadata[nameof(TargetFrameworkIdentifier)], }; projectMetadata.ProjectDir = Path.GetFullPath(projectMetadata.ProjectDir); projectMetadata.OutputPath = Path.GetFullPath(Path.Combine(projectMetadata.ProjectDir, projectMetadata.OutputPath)); return(projectMetadata); }
public override async Task <object> RunAsync(CommandLineProcessor processor, IConsoleHost host) { // Run with .csproj if (!string.IsNullOrEmpty(Project)) { var verboseHost = Verbose ? host : null; var projectFile = ProjectMetadata.FindProject(Project); var projectMetadata = await ProjectMetadata.GetProjectMetadata( projectFile, MSBuildProjectExtensionsPath, TargetFramework, Configuration, Runtime, NoBuild, verboseHost).ConfigureAwait(false); if (!File.Exists(Path.Combine(projectMetadata.OutputPath, projectMetadata.TargetFileName))) { throw new InvalidOperationException($"Project outputs could not be located in " + $"'{projectMetadata.OutputPath}'. Ensure that the project has been built."); } var cleanupFiles = new List <string>(); var args = new List <string>(); string executable; #if NET451 var toolDirectory = AppDomain.CurrentDomain.BaseDirectory; if (!Directory.Exists(toolDirectory)) { toolDirectory = Path.GetDirectoryName(typeof(AspNetCoreToSwaggerCommand).GetTypeInfo().Assembly.Location); } if (projectMetadata.TargetFrameworkIdentifier == ".NETFramework") { string binaryName; var is32BitProject = string.Equals(projectMetadata.PlatformTarget, "x86", StringComparison.OrdinalIgnoreCase); if (is32BitProject) { if (Environment.Is64BitProcess) { throw new InvalidOperationException($"The ouput of {projectFile} is a 32-bit application and requires NSwag.Console.x86 to be processed."); } binaryName = LauncherBinaryName + ".x86.exe"; } else { if (!Environment.Is64BitProcess) { throw new InvalidOperationException($"The ouput of {projectFile} is a 64-bit application and requires NSwag.Console to be processed."); } binaryName = LauncherBinaryName + ".exe"; } var executableSource = Path.Combine(toolDirectory, binaryName); if (!File.Exists(executableSource)) { throw new InvalidOperationException($"Unable to locate {binaryName} in {toolDirectory}."); } executable = Path.Combine(projectMetadata.OutputPath, binaryName); File.Copy(executableSource, executable, overwrite: true); cleanupFiles.Add(executable); var appConfig = Path.Combine(projectMetadata.OutputPath, projectMetadata.TargetFileName + ".config"); if (File.Exists(appConfig)) { var copiedAppConfig = Path.ChangeExtension(executable, ".exe.config"); File.Copy(appConfig, copiedAppConfig, overwrite: true); cleanupFiles.Add(copiedAppConfig); } } #elif NETSTANDARD var toolDirectory = AppContext.BaseDirectory; if (!Directory.Exists(toolDirectory)) { toolDirectory = Path.GetDirectoryName(typeof(AspNetCoreToSwaggerCommand).GetTypeInfo().Assembly.Location); } if (projectMetadata.TargetFrameworkIdentifier == ".NETCoreApp") { executable = "dotnet"; args.Add("exec"); args.Add("--depsfile"); args.Add(projectMetadata.ProjectDepsFilePath); args.Add("--runtimeconfig"); args.Add(projectMetadata.ProjectRuntimeConfigFilePath); var binaryName = LauncherBinaryName + ".dll"; var executorBinary = Path.Combine(toolDirectory, binaryName); if (!File.Exists(executorBinary)) { throw new InvalidOperationException($"Unable to locate {binaryName} in {toolDirectory}."); } args.Add(executorBinary); } #endif else { throw new InvalidOperationException($"Unsupported target framework '{projectMetadata.TargetFrameworkIdentifier}'."); } var commandFile = Path.GetTempFileName(); var outputFile = Path.GetTempFileName(); File.WriteAllText(commandFile, JsonConvert.SerializeObject(this)); cleanupFiles.Add(commandFile); cleanupFiles.Add(outputFile); args.Add(commandFile); args.Add(outputFile); args.Add(projectMetadata.AssemblyName); args.Add(toolDirectory); try { var exitCode = await Exe.RunAsync(executable, args, verboseHost).ConfigureAwait(false); if (exitCode != 0) { throw new InvalidOperationException($"Swagger generation failed with non-zero exit code '{exitCode}'."); } host?.WriteMessage($"Output written to {outputFile}.{Environment.NewLine}"); var documentJson = File.ReadAllText(outputFile); var document = await SwaggerDocument.FromJsonAsync(documentJson, expectedSchemaType : OutputType).ConfigureAwait(false); await this.TryWriteDocumentOutputAsync(host, () => document).ConfigureAwait(false); return(document); } finally { TryDeleteFiles(cleanupFiles); } } else { return(await base.RunAsync(processor, host)); } }