Beispiel #1
0
    public string FindMsBuildProject(string project)
    {
        var projectPath = project ?? _directory;

        if (!Path.IsPathRooted(projectPath))
        {
            projectPath = Path.Combine(_directory, projectPath);
        }

        if (Directory.Exists(projectPath))
        {
            var projects = Directory.EnumerateFileSystemEntries(projectPath, "*.*proj", SearchOption.TopDirectoryOnly)
                           .Where(f => !".xproj".Equals(Path.GetExtension(f), StringComparison.OrdinalIgnoreCase))
                           .ToList();

            if (projects.Count > 1)
            {
                throw new FileNotFoundException(SecretsHelpersResources.FormatError_MultipleProjectsFound(projectPath));
            }

            if (projects.Count == 0)
            {
                throw new FileNotFoundException(SecretsHelpersResources.FormatError_NoProjectsFound(projectPath));
            }

            return(projects[0]);
        }

        if (!File.Exists(projectPath))
        {
            throw new FileNotFoundException(SecretsHelpersResources.FormatError_ProjectPath_NotFound(projectPath));
        }

        return(projectPath);
    }
Beispiel #2
0
    public string Resolve(string project, string configuration)
    {
        var    finder = new MsBuildProjectFinder(_workingDirectory);
        string projectFile;

        try
        {
            projectFile = finder.FindMsBuildProject(project);
        }
        catch (Exception ex)
        {
            _reporter.Error(ex.Message);
            return(null);
        }

        _reporter.Verbose(SecretsHelpersResources.FormatMessage_Project_File_Path(projectFile));

        configuration = !string.IsNullOrEmpty(configuration)
            ? configuration
            : DefaultConfig;

        var outputFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());

        try
        {
            var psi = new ProcessStartInfo
            {
                FileName = DotNetMuxer.MuxerPathOrDefault(),
                RedirectStandardOutput = true,
                RedirectStandardError  = true,
                UseShellExecute        = false,
                ArgumentList           =
                {
                    "msbuild",
                    projectFile,
                    "/nologo",
                    "/t:_ExtractUserSecretsMetadata",     // defined in SecretManager.targets
                    "/p:_UserSecretsMetadataFile=" + outputFile,
                    "/p:Configuration=" + configuration,
                    "/p:CustomAfterMicrosoftCommonTargets=" + _targetsFile,
                    "/p:CustomAfterMicrosoftCommonCrossTargetingTargets=" + _targetsFile,
                    "-verbosity:detailed",
                }
            };

#if DEBUG
            _reporter.Verbose($"Invoking '{psi.FileName} {psi.Arguments}'");
#endif

            using var process = new Process()
                  {
                      StartInfo = psi,
                  };

            var outputBuilder = new StringBuilder();
            var errorBuilder  = new StringBuilder();
            process.OutputDataReceived += (_, d) =>
            {
                if (!string.IsNullOrEmpty(d.Data))
                {
                    outputBuilder.AppendLine(d.Data);
                }
            };
            process.ErrorDataReceived += (_, d) =>
            {
                if (!string.IsNullOrEmpty(d.Data))
                {
                    errorBuilder.AppendLine(d.Data);
                }
            };
            process.Start();
            process.BeginOutputReadLine();
            process.BeginErrorReadLine();
            process.WaitForExit();

            if (process.ExitCode != 0)
            {
                _reporter.Verbose(outputBuilder.ToString());
                _reporter.Verbose(errorBuilder.ToString());
                _reporter.Error($"Exit code: {process.ExitCode}");
                _reporter.Error(SecretsHelpersResources.FormatError_ProjectFailedToLoad(projectFile));
                return(null);
            }

            if (!File.Exists(outputFile))
            {
                _reporter.Error(SecretsHelpersResources.FormatError_ProjectMissingId(projectFile));
                return(null);
            }

            var id = File.ReadAllText(outputFile)?.Trim();
            if (string.IsNullOrEmpty(id))
            {
                _reporter.Error(SecretsHelpersResources.FormatError_ProjectMissingId(projectFile));
            }
            return(id);
        }
        finally
        {
            TryDelete(outputFile);
        }
    }
Beispiel #3
0
    public static string CreateUserSecretsId(IReporter reporter, string project, string workingDirectory, string overrideId = null)
    {
        var projectPath = ResolveProjectPath(project, workingDirectory);

        // Load the project file as XML
        var projectDocument = XDocument.Load(projectPath, LoadOptions.PreserveWhitespace);

        // Accept the `--id` CLI option to the main app
        string newSecretsId = string.IsNullOrWhiteSpace(overrideId)
            ? Guid.NewGuid().ToString()
            : overrideId;

        // Confirm secret ID does not contain invalid characters
        if (Path.GetInvalidPathChars().Any(newSecretsId.Contains))
        {
            throw new ArgumentException(SecretsHelpersResources.FormatError_InvalidSecretsId(newSecretsId));
        }

        var existingUserSecretsId = projectDocument.XPathSelectElements("//UserSecretsId").FirstOrDefault();

        // Check if a UserSecretsId is already set
        if (existingUserSecretsId is not null)
        {
            // Only set the UserSecretsId if the user specified an explicit value
            if (string.IsNullOrWhiteSpace(overrideId))
            {
                reporter.Output(SecretsHelpersResources.FormatMessage_ProjectAlreadyInitialized(projectPath));
                return(existingUserSecretsId.Value);
            }

            existingUserSecretsId.SetValue(newSecretsId);
        }
        else
        {
            // Find the first non-conditional PropertyGroup
            var propertyGroup = projectDocument.Root.DescendantNodes()
                                .FirstOrDefault(node => node is XElement el &&
                                                el.Name == "PropertyGroup" &&
                                                el.Attributes().All(attr =>
                                                                    attr.Name != "Condition")) as XElement;

            // No valid property group, create a new one
            if (propertyGroup == null)
            {
                propertyGroup = new XElement("PropertyGroup");
                projectDocument.Root.AddFirst(propertyGroup);
            }

            // Add UserSecretsId element
            propertyGroup.Add("  ");
            propertyGroup.Add(new XElement("UserSecretsId", newSecretsId));
            propertyGroup.Add($"{Environment.NewLine}  ");
        }

        var settings = new XmlWriterSettings
        {
            OmitXmlDeclaration = true,
        };

        using var xw = XmlWriter.Create(projectPath, settings);
        projectDocument.Save(xw);

        reporter.Output(SecretsHelpersResources.FormatMessage_SetUserSecretsIdForProject(newSecretsId, projectPath));
        return(newSecretsId);
    }