Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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));
            }
        }