Back-port fix for implicit imports for dotnet-user-secrets (#243)
This commit is contained in:
parent
d6079d6595
commit
d1f94460e2
|
|
@ -1,6 +0,0 @@
|
|||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(Project)" />
|
||||
<Target Name="_FindUserSecretsProperty">
|
||||
<WriteLinesToFile File="$(OutputFile)" Lines="$(UserSecretsId)" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
|
@ -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<string> _tempFiles = new List<string>();
|
||||
|
||||
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<string>();
|
||||
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("<!-- Auto-generated by dotnet-user-secrets. This file can be deleted and should not be commited to source control. -->");
|
||||
resource.CopyTo(stream);
|
||||
}
|
||||
|
||||
// cleanup
|
||||
_tempFiles.Add(outputPath);
|
||||
|
||||
return outputPath;
|
||||
}
|
||||
|
||||
private static void TryDelete(string file)
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="FindUserSecretsProperty.targets" target="tools\" />
|
||||
<file src="dotnet-user-secrets.dll" target="lib\netcoreapp1.0\" />
|
||||
<file src="dotnet-user-secrets.deps.json" target="lib\netcoreapp1.0\" />
|
||||
<file src="dotnet-user-secrets.runtimeconfig.json" target="lib\netcoreapp1.0\" />
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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": {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
<Project>
|
||||
<Target Name="_ExtractUserSecretsMetadata">
|
||||
<WriteLinesToFile File="$(_UserSecretsMetadataFile)" Lines="$(UserSecretsId)" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
|
@ -32,9 +32,7 @@ namespace Microsoft.Extensions.Configuration.UserSecrets.Tests
|
|||
return GetTempSecretProject(out userSecretsId);
|
||||
}
|
||||
|
||||
private const string ProjectTemplate = @"<Project ToolsVersion=""14.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
|
||||
<Import Project=""$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props"" />
|
||||
|
||||
private const string ProjectTemplate = @"<Project ToolsVersion=""15.0"" Sdk=""Microsoft.NET.Sdk"">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFrameworks>netcoreapp1.0</TargetFrameworks>
|
||||
|
|
@ -43,12 +41,8 @@ namespace Microsoft.Extensions.Configuration.UserSecrets.Tests
|
|||
|
||||
<ItemGroup>
|
||||
<Compile Include=""**\*.cs"" Exclude=""Excluded.cs"" />
|
||||
|
||||
<PackageReference Include=""Microsoft.NET.Sdk"" Version=""1.0.0-*"" PrivateAssets=""All"" />
|
||||
<PackageReference Include=""Microsoft.NETCore.App"" Version=""1.0.1"" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project=""$(MSBuildToolsPath)\Microsoft.CSharp.targets"" />
|
||||
</Project>";
|
||||
|
||||
public string GetTempSecretProject(out string userSecretsId)
|
||||
|
|
|
|||
Loading…
Reference in New Issue