Пример #1
0
        public static Project FromFile(
            string projectFile,
            string buildExtensionsDirectory,
            string framework     = null,
            string configuration = null,
            string runtime       = null)
        {
            if (string.IsNullOrEmpty(projectFile))
            {
                throw new ArgumentNullException(nameof(projectFile));
            }

            if (string.IsNullOrEmpty(buildExtensionsDirectory))
            {
                buildExtensionsDirectory = Path.Combine(Path.GetDirectoryName(projectFile), "obj");
            }

            IODirectory.CreateDirectory(buildExtensionsDirectory);

            var assembly    = typeof(Project).Assembly;
            var targetsPath = Path.Combine(
                buildExtensionsDirectory,
                $"{Path.GetFileName(projectFile)}.{ResourceFilename}");

            using (var input = assembly.GetManifestResourceStream(MSBuildResourceName))
            {
                using (var output = File.OpenWrite(targetsPath))
                {
                    // NB: Copy always in case it changes
                    Reporter.WriteVerbose(Resources.FormatWritingFile(targetsPath));
                    input.CopyTo(output);
                }
            }

            IDictionary <string, string> metadata;
            var metadataPath = Path.GetTempFileName();

            try
            {
                var args = new List <string>
                {
                    "msbuild",
                    "/target:WriteServiceProjectReferenceMetadata",
                    "/verbosity:quiet",
                    "/nologo",
                    $"/property:ServiceProjectReferenceMetadataPath={metadataPath}",
                    projectFile,
                };

                if (!string.IsNullOrEmpty(framework))
                {
                    args.Add($"/property:TargetFramework={framework}");
                }

                if (!string.IsNullOrEmpty(configuration))
                {
                    args.Add($"/property:Configuration={configuration}");
                }

                if (!string.IsNullOrEmpty(runtime))
                {
                    args.Add($"/property:RuntimeIdentifier={runtime}");
                }

                var exitCode = Exe.Run("dotnet", args);
                if (exitCode != 0)
                {
                    throw new CommandException(Resources.GetMetadataFailed);
                }

                metadata = File
                           .ReadLines(metadataPath)
                           .Select(l => l.Split(new[] { ':' }, 2))
                           .ToDictionary(s => s[0], s => s[1].TrimStart());
            }
            finally
            {
                File.Delete(metadataPath);
                File.Delete(targetsPath);
            }

            var project = new Project
            {
                DefaultDocumentName = metadata[nameof(DefaultDocumentName)],
                DefaultMethod       = metadata[nameof(DefaultMethod)],
                DefaultService      = metadata[nameof(DefaultService)],

                AssemblyName                 = metadata[nameof(AssemblyName)],
                Configuration                = metadata[nameof(Configuration)],
                OutputPath                   = metadata[nameof(OutputPath)],
                Platform                     = metadata[nameof(Platform)],
                PlatformTarget               = metadata[nameof(PlatformTarget)] ?? metadata[nameof(Platform)],
                ProjectAssetsFile            = metadata[nameof(ProjectAssetsFile)],
                ProjectDepsFilePath          = metadata[nameof(ProjectDepsFilePath)],
                ProjectDirectory             = metadata[nameof(ProjectDirectory)],
                ProjectExtensionsPath        = metadata[nameof(ProjectExtensionsPath)],
                ProjectName                  = metadata[nameof(ProjectName)],
                ProjectRuntimeConfigFilePath = metadata[nameof(ProjectRuntimeConfigFilePath)],
                RuntimeFrameworkVersion      = metadata[nameof(RuntimeFrameworkVersion)],
                RuntimeIdentifier            = metadata[nameof(RuntimeIdentifier)],
                TargetFramework              = metadata[nameof(TargetFramework)],
                TargetFrameworkMoniker       = metadata[nameof(TargetFrameworkMoniker)],
                TargetPath                   = metadata[nameof(TargetPath)],
            };

            if (string.IsNullOrEmpty(project.OutputPath))
            {
                throw new CommandException(
                          Resources.FormatGetMetadataValueFailed(nameof(OutputPath), nameof(OutputPath)));
            }

            if (string.IsNullOrEmpty(project.ProjectDirectory))
            {
                throw new CommandException(
                          Resources.FormatGetMetadataValueFailed(nameof(ProjectDirectory), "MSBuildProjectDirectory"));
            }

            if (string.IsNullOrEmpty(project.TargetPath))
            {
                throw new CommandException(
                          Resources.FormatGetMetadataValueFailed(nameof(TargetPath), nameof(TargetPath)));
            }

            if (!Path.IsPathRooted(project.ProjectDirectory))
            {
                project.OutputPath = Path.GetFullPath(
                    Path.Combine(IODirectory.GetCurrentDirectory(), project.ProjectDirectory));
            }

            if (!Path.IsPathRooted(project.OutputPath))
            {
                project.OutputPath = Path.GetFullPath(Path.Combine(project.ProjectDirectory, project.OutputPath));
            }

            if (!Path.IsPathRooted(project.ProjectExtensionsPath))
            {
                project.ProjectExtensionsPath = Path.GetFullPath(
                    Path.Combine(project.ProjectDirectory, project.ProjectExtensionsPath));
            }

            if (!Path.IsPathRooted(project.TargetPath))
            {
                project.TargetPath = Path.GetFullPath(Path.Combine(project.OutputPath, project.TargetPath));
            }

            // Some document generation tools support non-ASP.NET Core projects. Any of the remaining properties may
            // thus be null empty.
            var configPath = $"{project.TargetPath}.config";

            if (File.Exists(configPath))
            {
                project.ConfigPath = configPath;
            }

            if (!(string.IsNullOrEmpty(project.ProjectAssetsFile) || Path.IsPathRooted(project.ProjectAssetsFile)))
            {
                project.ProjectAssetsFile = Path.GetFullPath(
                    Path.Combine(project.ProjectDirectory, project.ProjectAssetsFile));
            }

            if (!(string.IsNullOrEmpty(project.ProjectDepsFilePath) || Path.IsPathRooted(project.ProjectDepsFilePath)))
            {
                project.ProjectDepsFilePath = Path.GetFullPath(
                    Path.Combine(project.ProjectDirectory, project.ProjectDepsFilePath));
            }

            if (!(string.IsNullOrEmpty(project.ProjectRuntimeConfigFilePath) ||
                  Path.IsPathRooted(project.ProjectRuntimeConfigFilePath)))
            {
                project.ProjectRuntimeConfigFilePath = Path.GetFullPath(
                    Path.Combine(project.OutputPath, project.ProjectRuntimeConfigFilePath));
            }

            return(project);
        }