diff --git a/src/Microsoft.Extensions.SecretManager.Tools/FindUserSecretsProperty.targets b/src/Microsoft.Extensions.SecretManager.Tools/FindUserSecretsProperty.targets deleted file mode 100644 index 694dc25008..0000000000 --- a/src/Microsoft.Extensions.SecretManager.Tools/FindUserSecretsProperty.targets +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/Microsoft.Extensions.SecretManager.Tools/Internal/ProjectIdResolver.cs b/src/Microsoft.Extensions.SecretManager.Tools/Internal/ProjectIdResolver.cs index 683f412c83..88bddcd68e 100644 --- a/src/Microsoft.Extensions.SecretManager.Tools/Internal/ProjectIdResolver.cs +++ b/src/Microsoft.Extensions.SecretManager.Tools/Internal/ProjectIdResolver.cs @@ -4,19 +4,16 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Reflection; using Microsoft.DotNet.Cli.Utils; using Microsoft.Extensions.Logging; namespace Microsoft.Extensions.SecretManager.Tools.Internal { - public class ProjectIdResolver : IDisposable + public class ProjectIdResolver { - private const string TargetsFileName = "FindUserSecretsProperty.targets"; private readonly ILogger _logger; private readonly string _workingDirectory; - private readonly List _tempFiles = new List(); public ProjectIdResolver(ILogger logger, string workingDirectory) { @@ -28,88 +25,70 @@ namespace Microsoft.Extensions.SecretManager.Tools.Internal { var finder = new MsBuildProjectFinder(_workingDirectory); var projectFile = finder.FindMsBuildProject(project); + EnsureProjectExtensionTargetsExist(projectFile); _logger.LogDebug(Resources.Message_Project_File_Path, projectFile); - var targetFile = GetTargetFile(); - var outputFile = Path.GetTempFileName(); - _tempFiles.Add(outputFile); - var commandOutput = new List(); - var commandResult = Command.CreateDotNet("msbuild", - new[] { - targetFile, - "/nologo", - "/t:_FindUserSecretsProperty", - $"/p:Project={projectFile}", - $"/p:OutputFile={outputFile}", - $"/p:Configuration={configuration}" - }) - .CaptureStdErr() - .CaptureStdOut() - .OnErrorLine(l => commandOutput.Add(l)) - .OnOutputLine(l => commandOutput.Add(l)) - .Execute(); - - if (commandResult.ExitCode != 0) + var outputFile = Path.GetTempFileName(); + try { - _logger.LogDebug(string.Join(Environment.NewLine, commandOutput)); - throw new GracefulException(Resources.FormatError_ProjectFailedToLoad(projectFile)); + var commandResult = Command.CreateDotNet("msbuild", + new[] { + projectFile, + "/nologo", + "/t:_ExtractUserSecretsMetadata", // defined in ProjectIdResolverTargets.xml + $"/p:_UserSecretsMetadataFile={outputFile}", + $"/p:Configuration={configuration}" + }) + .CaptureStdErr() + .CaptureStdOut() + .OnErrorLine(l => commandOutput.Add(l)) + .OnOutputLine(l => commandOutput.Add(l)) + .Execute(); + + if (commandResult.ExitCode != 0) + { + _logger.LogDebug(string.Join(Environment.NewLine, commandOutput)); + throw new GracefulException(Resources.FormatError_ProjectFailedToLoad(projectFile)); + } + + var id = File.ReadAllText(outputFile)?.Trim(); + if (string.IsNullOrEmpty(id)) + { + throw new GracefulException(Resources.FormatError_ProjectMissingId(projectFile)); + } + + return id; + } - - var id = File.ReadAllText(outputFile)?.Trim(); - if (string.IsNullOrEmpty(id)) + finally { - throw new GracefulException(Resources.FormatError_ProjectMissingId(projectFile)); - } - - return id; - } - - public void Dispose() - { - foreach (var file in _tempFiles) - { - TryDelete(file); + TryDelete(outputFile); } } - private string GetTargetFile() + private void EnsureProjectExtensionTargetsExist(string projectFile) { - var assemblyDir = Path.GetDirectoryName(GetType().GetTypeInfo().Assembly.Location); + // relies on MSBuildProjectExtensionsPath and Microsoft.Common.targets to import this file + // into the target project + var projectExtensionsPath = Path.Combine( + Path.GetDirectoryName(projectFile), + "obj", + $"{Path.GetFileName(projectFile)}.usersecrets.targets"); - // targets should be in one of these locations, depending on test setup and tools installation - var searchPaths = new[] - { - AppContext.BaseDirectory, - assemblyDir, // next to assembly - Path.Combine(assemblyDir, "../../tools"), // inside the nupkg - }; - - var foundFile = searchPaths - .Select(dir => Path.Combine(dir, TargetsFileName)) - .Where(File.Exists) - .FirstOrDefault(); - - if (foundFile != null) - { - return foundFile; - } - - // This should only really happen during testing. Current build system doesn't give us a good way to ensure the - // test project has an always-up to date version of the targets file. - // TODO cleanup after we switch to an MSBuild system in which can specify "CopyToOutputDirectory: Always" to resolve this issue - var outputPath = Path.GetTempFileName(); - using (var resource = GetType().GetTypeInfo().Assembly.GetManifestResourceStream(TargetsFileName)) - using (var stream = new FileStream(outputPath, FileMode.Create)) + Directory.CreateDirectory(Path.GetDirectoryName(projectExtensionsPath)); + + // should overwrite the file always. Hypothetically, another version of the user-secrets tool + // could have already put a file here. We want to ensure the target file matches the currently + // running tool + using (var resource = GetType().GetTypeInfo().Assembly.GetManifestResourceStream("ProjectIdResolverTargets.xml")) + using (var stream = new FileStream(projectExtensionsPath, FileMode.Create)) + using (var writer = new StreamWriter(stream)) { + writer.WriteLine(""); resource.CopyTo(stream); } - - // cleanup - _tempFiles.Add(outputPath); - - return outputPath; } private static void TryDelete(string file) diff --git a/src/Microsoft.Extensions.SecretManager.Tools/Microsoft.Extensions.SecretManager.Tools.nuspec b/src/Microsoft.Extensions.SecretManager.Tools/Microsoft.Extensions.SecretManager.Tools.nuspec index f8c596e5e9..626339e76d 100644 --- a/src/Microsoft.Extensions.SecretManager.Tools/Microsoft.Extensions.SecretManager.Tools.nuspec +++ b/src/Microsoft.Extensions.SecretManager.Tools/Microsoft.Extensions.SecretManager.Tools.nuspec @@ -24,7 +24,6 @@ - diff --git a/src/Microsoft.Extensions.SecretManager.Tools/Program.cs b/src/Microsoft.Extensions.SecretManager.Tools/Program.cs index 3ef60eb563..10e491c465 100644 --- a/src/Microsoft.Extensions.SecretManager.Tools/Program.cs +++ b/src/Microsoft.Extensions.SecretManager.Tools/Program.cs @@ -125,10 +125,8 @@ namespace Microsoft.Extensions.SecretManager.Tools return options.Id; } - using (var resolver = new ProjectIdResolver(Logger, _workingDirectory)) - { - return resolver.Resolve(options.Project, options.Configuration); - } + var resolver = new ProjectIdResolver(Logger, _workingDirectory); + return resolver.Resolve(options.Project, options.Configuration); } } } \ No newline at end of file diff --git a/src/Microsoft.Extensions.SecretManager.Tools/project.json b/src/Microsoft.Extensions.SecretManager.Tools/project.json index 71db102962..4a60b24d2c 100644 --- a/src/Microsoft.Extensions.SecretManager.Tools/project.json +++ b/src/Microsoft.Extensions.SecretManager.Tools/project.json @@ -5,10 +5,9 @@ "emitEntryPoint": true, "warningsAsErrors": true, "keyFile": "../../tools/Key.snk", - "copyToOutput": "*.targets", "embed": { "mappings": { - "FindUserSecretsProperty.targets": "./FindUserSecretsProperty.targets" + "ProjectIdResolverTargets.xml": "./resources/ProjectIdResolverTargets.xml" } }, "compile": { @@ -25,16 +24,6 @@ "configuration", "secrets", "usersecrets" - ], - "files": { - "mappings": { - "tools/FindUserSecretsProperty.targets": "FindUserSecretsProperty.targets" - } - } - }, - "publishOptions": { - "include": [ - "*.targets" ] }, "dependencies": { diff --git a/src/Microsoft.Extensions.SecretManager.Tools/resources/ProjectIdResolverTargets.xml b/src/Microsoft.Extensions.SecretManager.Tools/resources/ProjectIdResolverTargets.xml new file mode 100644 index 0000000000..a30a87d34a --- /dev/null +++ b/src/Microsoft.Extensions.SecretManager.Tools/resources/ProjectIdResolverTargets.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/test/Microsoft.Extensions.SecretManager.Tools.Tests/UserSecretsTestFixture.cs b/test/Microsoft.Extensions.SecretManager.Tools.Tests/UserSecretsTestFixture.cs index a3ff3dfbb1..569ee1c6c3 100644 --- a/test/Microsoft.Extensions.SecretManager.Tools.Tests/UserSecretsTestFixture.cs +++ b/test/Microsoft.Extensions.SecretManager.Tools.Tests/UserSecretsTestFixture.cs @@ -32,9 +32,7 @@ namespace Microsoft.Extensions.Configuration.UserSecrets.Tests return GetTempSecretProject(out userSecretsId); } - private const string ProjectTemplate = @" - - + private const string ProjectTemplate = @" Exe netcoreapp1.0 @@ -43,12 +41,8 @@ namespace Microsoft.Extensions.Configuration.UserSecrets.Tests - - - - "; public string GetTempSecretProject(out string userSecretsId)