diff --git a/.gitignore b/.gitignore index 3388915..29b5f79 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ project.lock.json .testPublish/ .build/ /.vs/ +.vscode/ testWorkDir/ *.nuget.props *.nuget.targets \ No newline at end of file diff --git a/src/Microsoft.Extensions.SecretManager.Tools/FindUserSecretsProperty.targets b/src/Microsoft.Extensions.SecretManager.Tools/FindUserSecretsProperty.targets new file mode 100644 index 0000000..694dc25 --- /dev/null +++ b/src/Microsoft.Extensions.SecretManager.Tools/FindUserSecretsProperty.targets @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/Microsoft.Extensions.SecretManager.Tools/Internal/CommandLineOptions.cs b/src/Microsoft.Extensions.SecretManager.Tools/Internal/CommandLineOptions.cs index 3bd4508..59363c6 100644 --- a/src/Microsoft.Extensions.SecretManager.Tools/Internal/CommandLineOptions.cs +++ b/src/Microsoft.Extensions.SecretManager.Tools/Internal/CommandLineOptions.cs @@ -3,6 +3,7 @@ using System.IO; using System.Reflection; +using Microsoft.DotNet.Cli.Utils; using Microsoft.Extensions.CommandLineUtils; namespace Microsoft.Extensions.SecretManager.Tools.Internal @@ -13,6 +14,7 @@ public class CommandLineOptions public bool IsVerbose { get; set; } public bool IsHelp { get; set; } public string Project { get; set; } + public string Configuration { get; set; } internal ICommand Command { get; set; } public static CommandLineOptions Parse(string[] args, TextWriter output) @@ -34,6 +36,9 @@ public static CommandLineOptions Parse(string[] args, TextWriter output) var optionProject = app.Option("-p|--project ", "Path to project, default is current directory", CommandOptionType.SingleValue, inherited: true); + var optionConfig = app.Option("-c|--configuration ", $"The project configuration to use. Defaults to {Constants.DefaultConfiguration}", + CommandOptionType.SingleValue, inherited: true); + // the escape hatch if project evaluation fails, or if users want to alter a secret store other than the one // in the current project var optionId = app.Option("--id", "The user secret id to use.", @@ -58,6 +63,7 @@ public static CommandLineOptions Parse(string[] args, TextWriter output) options.IsHelp = app.IsShowingInformation; options.IsVerbose = optionVerbose.HasValue(); options.Project = optionProject.Value(); + options.Configuration = optionConfig.Value(); return options; } diff --git a/src/Microsoft.Extensions.SecretManager.Tools/Internal/GracefulProjectFinder.cs b/src/Microsoft.Extensions.SecretManager.Tools/Internal/GracefulProjectFinder.cs deleted file mode 100644 index 9ad7bbd..0000000 --- a/src/Microsoft.Extensions.SecretManager.Tools/Internal/GracefulProjectFinder.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using Microsoft.DotNet.Cli.Utils; -using Microsoft.Extensions.ProjectModel; - -namespace Microsoft.Extensions.SecretManager.Tools -{ - internal class GracefulProjectFinder : MsBuildProjectFinder - { - public GracefulProjectFinder(string directory) - : base(directory) - { - } - - protected override Exception FileDoesNotExist(string filePath) - => new GracefulException(Resources.FormatError_ProjectPath_NotFound(filePath)); - - protected override Exception MultipleProjectsFound(string directory) - => new GracefulException($"Multiple MSBuild project files found in '{directory}'. Specify which to use with the --project option."); - - protected override Exception NoProjectsFound(string directory) - => new GracefulException($"Could not find a MSBuild project file in '{directory}'. Specify which project to use with the --project option."); - } -} \ No newline at end of file diff --git a/src/Microsoft.Extensions.SecretManager.Tools/Internal/MsBuildProjectFinder.cs b/src/Microsoft.Extensions.SecretManager.Tools/Internal/MsBuildProjectFinder.cs new file mode 100644 index 0000000..e080b4c --- /dev/null +++ b/src/Microsoft.Extensions.SecretManager.Tools/Internal/MsBuildProjectFinder.cs @@ -0,0 +1,61 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.IO; +using System.Linq; +using Microsoft.DotNet.Cli.Utils; + +namespace Microsoft.Extensions.SecretManager.Tools.Internal +{ + internal class MsBuildProjectFinder + { + private readonly string _directory; + + public MsBuildProjectFinder(string directory) + { + if (string.IsNullOrEmpty(directory)) + { + throw new ArgumentException(Resources.Common_StringNullOrEmpty, nameof(directory)); + } + + _directory = directory; + } + + 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 GracefulException(Resources.FormatError_MultipleProjectsFound(projectPath)); + } + + if (projects.Count == 0) + { + throw new GracefulException(Resources.FormatError_NoProjectsFound(projectPath)); + } + + return projects[0]; + } + + if (!File.Exists(projectPath)) + { + throw new GracefulException(Resources.FormatError_ProjectPath_NotFound(projectPath)); + } + + return projectPath; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.SecretManager.Tools/Internal/ProjectContextExtensions.cs b/src/Microsoft.Extensions.SecretManager.Tools/Internal/ProjectContextExtensions.cs deleted file mode 100644 index 627cb50..0000000 --- a/src/Microsoft.Extensions.SecretManager.Tools/Internal/ProjectContextExtensions.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.DotNet.Cli.Utils; -using Microsoft.Extensions.ProjectModel; - -namespace Microsoft.Extensions.SecretManager.Tools.Internal -{ - public static class ProjectContextExtensions - { - public static string GetUserSecretsId(this IProjectContext context) - { - var userSecretsId = context.FindProperty("UserSecretsId"); - - if (string.IsNullOrEmpty(userSecretsId)) - { - throw new GracefulException(Resources.FormatError_ProjectMissingId(context.ProjectFullPath)); - } - - return userSecretsId; - } - } -} diff --git a/src/Microsoft.Extensions.SecretManager.Tools/Internal/ProjectIdResolver.cs b/src/Microsoft.Extensions.SecretManager.Tools/Internal/ProjectIdResolver.cs new file mode 100644 index 0000000..683f412 --- /dev/null +++ b/src/Microsoft.Extensions.SecretManager.Tools/Internal/ProjectIdResolver.cs @@ -0,0 +1,130 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +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 + { + 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) + { + _workingDirectory = workingDirectory; + _logger = logger; + } + + public string Resolve(string project, string configuration = Constants.DefaultConfiguration) + { + var finder = new MsBuildProjectFinder(_workingDirectory); + var projectFile = finder.FindMsBuildProject(project); + + _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) + { + _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; + } + + public void Dispose() + { + foreach (var file in _tempFiles) + { + TryDelete(file); + } + } + + private string GetTargetFile() + { + var assemblyDir = Path.GetDirectoryName(GetType().GetTypeInfo().Assembly.Location); + + // 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)) + { + resource.CopyTo(stream); + } + + // cleanup + _tempFiles.Add(outputPath); + + return outputPath; + } + + private static void TryDelete(string file) + { + try + { + if (File.Exists(file)) + { + File.Delete(file); + } + } + catch + { + // whatever + } + } + } +} \ No newline at end of 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 d552f11..db6cb0b 100644 --- a/src/Microsoft.Extensions.SecretManager.Tools/Microsoft.Extensions.SecretManager.Tools.nuspec +++ b/src/Microsoft.Extensions.SecretManager.Tools/Microsoft.Extensions.SecretManager.Tools.nuspec @@ -16,17 +16,16 @@ - - - - - - - + + + + + + diff --git a/src/Microsoft.Extensions.SecretManager.Tools/Program.cs b/src/Microsoft.Extensions.SecretManager.Tools/Program.cs index 4ca1a1c..2ae8b9b 100644 --- a/src/Microsoft.Extensions.SecretManager.Tools/Program.cs +++ b/src/Microsoft.Extensions.SecretManager.Tools/Program.cs @@ -2,14 +2,14 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using System.Reflection; using Microsoft.DotNet.Cli.Utils; using Microsoft.Extensions.Logging; using Microsoft.Extensions.SecretManager.Tools.Internal; -using Microsoft.Extensions.ProjectModel; -using Microsoft.Build.Exceptions; namespace Microsoft.Extensions.SecretManager.Tools { @@ -19,23 +19,20 @@ public class Program private CommandOutputProvider _loggerProvider; private readonly TextWriter _consoleOutput; private readonly string _workingDirectory; - // TODO this is only for testing. Can remove this when this project builds with CLI preview3 - private readonly MsBuildContext _msBuildContext; public static int Main(string[] args) { HandleDebugFlag(ref args); int rc; - new Program(Console.Out, Directory.GetCurrentDirectory(), MsBuildContext.FromCurrentDotNetSdk()).TryRun(args, out rc); + new Program(Console.Out, Directory.GetCurrentDirectory()).TryRun(args, out rc); return rc; } - internal Program(TextWriter consoleOutput, string workingDirectory, MsBuildContext msbuildContext) + internal Program(TextWriter consoleOutput, string workingDirectory) { _consoleOutput = consoleOutput; _workingDirectory = workingDirectory; - _msBuildContext = msbuildContext; var loggerFactory = new LoggerFactory(); CommandOutputProvider = new CommandOutputProvider(); @@ -136,37 +133,22 @@ internal int RunInternal(params string[] args) CommandOutputProvider.LogLevel = LogLevel.Debug; } - var userSecretsId = string.IsNullOrEmpty(options.Id) - ? ResolveIdFromProject(options.Project) - : options.Id; - + var userSecretsId = ResolveId(options); var store = new SecretsStore(userSecretsId, Logger); options.Command.Execute(store, Logger); return 0; } - internal string ResolveIdFromProject(string projectPath) + internal string ResolveId(CommandLineOptions options) { - var finder = new GracefulProjectFinder(_workingDirectory); - var projectFile = finder.FindMsBuildProject(projectPath); - - Logger.LogDebug(Resources.Message_Project_File_Path, projectFile); - - try + if (!string.IsNullOrEmpty(options.Id)) { - var project = new MsBuildProjectContextBuilder() - .UseMsBuild(_msBuildContext) - .AsDesignTimeBuild() - .WithBuildTargets(Array.Empty()) - .WithProjectFile(projectFile) - .WithTargetFramework("") // TFM doesn't matter - .Build(); - - return project.GetUserSecretsId(); + return options.Id; } - catch (InvalidProjectFileException ex) + + using (var resolver = new ProjectIdResolver(Logger, _workingDirectory)) { - throw new GracefulException(Resources.FormatError_ProjectFailedToLoad(projectFile), ex); + return resolver.Resolve(options.Project, options.Configuration); } } } diff --git a/src/Microsoft.Extensions.SecretManager.Tools/Properties/Resources.Designer.cs b/src/Microsoft.Extensions.SecretManager.Tools/Properties/Resources.Designer.cs index 1b9e397..819b0c8 100644 --- a/src/Microsoft.Extensions.SecretManager.Tools/Properties/Resources.Designer.cs +++ b/src/Microsoft.Extensions.SecretManager.Tools/Properties/Resources.Designer.cs @@ -10,6 +10,22 @@ internal static class Resources private static readonly ResourceManager _resourceManager = new ResourceManager("Microsoft.Extensions.SecretManager.Tools.Resources", typeof(Resources).GetTypeInfo().Assembly); + /// + /// Value cannot be null or an empty string. + /// + internal static string Common_StringNullOrEmpty + { + get { return GetString("Common_StringNullOrEmpty"); } + } + + /// + /// Value cannot be null or an empty string. + /// + internal static string FormatCommon_StringNullOrEmpty() + { + return GetString("Common_StringNullOrEmpty"); + } + /// /// Command failed : {message} /// @@ -42,6 +58,22 @@ internal static string FormatError_Missing_Secret(object key) return string.Format(CultureInfo.CurrentCulture, GetString("Error_Missing_Secret", "key"), key); } + /// + /// Multiple MSBuild project files found in '{projectPath}'. Specify which to use with the --project option. + /// + internal static string Error_MultipleProjectsFound + { + get { return GetString("Error_MultipleProjectsFound"); } + } + + /// + /// Multiple MSBuild project files found in '{projectPath}'. Specify which to use with the --project option. + /// + internal static string FormatError_MultipleProjectsFound(object projectPath) + { + return string.Format(CultureInfo.CurrentCulture, GetString("Error_MultipleProjectsFound", "projectPath"), projectPath); + } + /// /// No secrets configured for this application. /// @@ -58,6 +90,22 @@ internal static string FormatError_No_Secrets_Found() return GetString("Error_No_Secrets_Found"); } + /// + /// Could not find a MSBuild project file in '{projectPath}'. Specify which project to use with the --project option. + /// + internal static string Error_NoProjectsFound + { + get { return GetString("Error_NoProjectsFound"); } + } + + /// + /// Could not find a MSBuild project file in '{projectPath}'. Specify which project to use with the --project option. + /// + internal static string FormatError_NoProjectsFound(object projectPath) + { + return string.Format(CultureInfo.CurrentCulture, GetString("Error_NoProjectsFound", "projectPath"), projectPath); + } + /// /// Could not find the global property 'UserSecretsId' in MSBuild project '{project}'. Ensure this property is set in the project or use the '--id' command line option. /// diff --git a/src/Microsoft.Extensions.SecretManager.Tools/Resources.resx b/src/Microsoft.Extensions.SecretManager.Tools/Resources.resx index 403bfd3..ade092e 100644 --- a/src/Microsoft.Extensions.SecretManager.Tools/Resources.resx +++ b/src/Microsoft.Extensions.SecretManager.Tools/Resources.resx @@ -117,15 +117,24 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Value cannot be null or an empty string. + Command failed : {message} Cannot find '{key}' in the secret store. + + Multiple MSBuild project files found in '{projectPath}'. Specify which to use with the --project option. + No secrets configured for this application. + + Could not find a MSBuild project file in '{projectPath}'. Specify which project to use with the --project option. + Could not find the global property 'UserSecretsId' in MSBuild project '{project}'. Ensure this property is set in the project or use the '--id' command line option. diff --git a/src/Microsoft.Extensions.SecretManager.Tools/project.json b/src/Microsoft.Extensions.SecretManager.Tools/project.json index 778f80d..1f2aaa7 100644 --- a/src/Microsoft.Extensions.SecretManager.Tools/project.json +++ b/src/Microsoft.Extensions.SecretManager.Tools/project.json @@ -4,7 +4,13 @@ "outputName": "dotnet-user-secrets", "emitEntryPoint": true, "warningsAsErrors": true, - "keyFile": "../../tools/Key.snk" + "keyFile": "../../tools/Key.snk", + "copyToOutput": "*.targets", + "embed": { + "mappings": { + "FindUserSecretsProperty.targets": "./FindUserSecretsProperty.targets" + } + } }, "description": "Command line tool to manage user secrets for Microsoft.Extensions.Configuration.", "packOptions": { @@ -16,23 +22,22 @@ "configuration", "secrets", "usersecrets" - ] + ], + "files": { + "mappings": { + "tools/FindUserSecretsProperty.targets": "FindUserSecretsProperty.targets" + } + } }, "dependencies": { - "Microsoft.Build.Runtime": "15.1.298-preview5", "Microsoft.DotNet.Cli.Utils": "1.0.0-*", "Microsoft.Extensions.CommandLineUtils": "1.1.0-*", "Microsoft.Extensions.Configuration.UserSecrets": "1.1.0-*", "Microsoft.Extensions.Logging": "1.1.0-*", - "Microsoft.Extensions.ProjectModel.Sources": { - "version": "1.0.0-*", - "type": "build" - }, "Microsoft.NETCore.App": { "version": "1.1.0-*", "type": "platform" - }, - "NuGet.Versioning": "3.5.0-*" + } }, "frameworks": { "netcoreapp1.0": {} diff --git a/test/Microsoft.Extensions.SecretManager.Tools.Tests/MsBuildProjectFinderTest.cs b/test/Microsoft.Extensions.SecretManager.Tools.Tests/MsBuildProjectFinderTest.cs new file mode 100644 index 0000000..3a3476d --- /dev/null +++ b/test/Microsoft.Extensions.SecretManager.Tools.Tests/MsBuildProjectFinderTest.cs @@ -0,0 +1,87 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.IO; +using Microsoft.DotNet.Cli.Utils; +using Microsoft.Extensions.SecretManager.Tools.Internal; +using Xunit; + +namespace Microsoft.Extensions.SecretsManager.Tools.Tests +{ + public class MsBuildProjectFinderTest + { + [Theory] + [InlineData(".csproj")] + [InlineData(".vbproj")] + [InlineData(".fsproj")] + public void FindsSingleProject(string extension) + { + using (var files = new TemporaryFileProvider()) + { + var filename = "TestProject" + extension; + files.Add(filename, ""); + + var finder = new MsBuildProjectFinder(files.Root); + + Assert.Equal(Path.Combine(files.Root, filename), finder.FindMsBuildProject(null)); + } + } + + [Fact] + public void ThrowsWhenNoFile() + { + using (var files = new TemporaryFileProvider()) + { + var finder = new MsBuildProjectFinder(files.Root); + + Assert.Throws(() => finder.FindMsBuildProject(null)); + } + } + + [Fact] + public void DoesNotMatchXproj() + { + using (var files = new TemporaryFileProvider()) + { + var finder = new MsBuildProjectFinder(files.Root); + files.Add("test.xproj", ""); + + Assert.Throws(() => finder.FindMsBuildProject(null)); + } + } + + [Fact] + public void ThrowsWhenMultipleFile() + { + using (var files = new TemporaryFileProvider()) + { + files.Add("Test1.csproj", ""); + files.Add("Test2.csproj", ""); + var finder = new MsBuildProjectFinder(files.Root); + + Assert.Throws(() => finder.FindMsBuildProject(null)); + } + } + + [Fact] + public void ThrowsWhenFileDoesNotExist() + { + using (var files = new TemporaryFileProvider()) + { + var finder = new MsBuildProjectFinder(files.Root); + + Assert.Throws(() => finder.FindMsBuildProject("test.csproj")); + } + } + + [Fact] + public void ThrowsWhenRootDoesNotExist() + { + var files = new TemporaryFileProvider(); + var finder = new MsBuildProjectFinder(files.Root); + files.Dispose(); + Assert.Throws(() => finder.FindMsBuildProject(null)); + } + } +} diff --git a/test/Microsoft.Extensions.SecretManager.Tools.Tests/SecretManagerTests.cs b/test/Microsoft.Extensions.SecretManager.Tools.Tests/SecretManagerTests.cs index f10ef10..7cae27f 100644 --- a/test/Microsoft.Extensions.SecretManager.Tools.Tests/SecretManagerTests.cs +++ b/test/Microsoft.Extensions.SecretManager.Tools.Tests/SecretManagerTests.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.IO; using System.Text; -using Microsoft.Build.Exceptions; using Microsoft.DotNet.Cli.Utils; using Microsoft.Extensions.Configuration.UserSecrets; using Microsoft.Extensions.Configuration.UserSecrets.Tests; @@ -29,7 +28,7 @@ public SecretManagerTests(UserSecretsTestFixture fixture, ITestOutputHelper outp private Program CreateProgram() { - return new Program(Console.Out, Directory.GetCurrentDirectory(), _fixture.GetMsBuildContext()) + return new Program(Console.Out, Directory.GetCurrentDirectory()) { Logger = _logger }; @@ -55,7 +54,6 @@ public void Error_InvalidProjectFormat() var ex = Assert.Throws(() => secretManager.RunInternal("list", "-p", project)); Assert.Equal(Resources.FormatError_ProjectFailedToLoad(project), ex.Message); - Assert.IsType(ex.InnerException); } [Fact] @@ -74,7 +72,7 @@ public void SupportsRelativePaths() var projectPath = _fixture.GetTempSecretProject(); var cwd = Path.Combine(projectPath, "nested1"); Directory.CreateDirectory(cwd); - var secretManager = new Program(Console.Out, cwd, _fixture.GetMsBuildContext()) { Logger = _logger, CommandOutputProvider = _logger.CommandOutputProvider }; + var secretManager = new Program(Console.Out, cwd) { Logger = _logger, CommandOutputProvider = _logger.CommandOutputProvider }; secretManager.CommandOutputProvider.LogLevel = LogLevel.Debug; secretManager.RunInternal("list", "-p", ".." + Path.DirectorySeparatorChar, "--verbose"); @@ -99,7 +97,7 @@ public void SetSecrets(bool fromCurrentDirectory) var dir = fromCurrentDirectory ? projectPath : Path.GetTempPath(); - var secretManager = new Program(Console.Out, dir, _fixture.GetMsBuildContext()) { Logger = _logger }; + var secretManager = new Program(Console.Out, dir) { Logger = _logger }; foreach (var secret in secrets) { @@ -278,7 +276,7 @@ public void Clear_Secrets(bool fromCurrentDirectory) ? projectPath : Path.GetTempPath(); - var secretManager = new Program(Console.Out, dir, _fixture.GetMsBuildContext()) { Logger = _logger }; + var secretManager = new Program(Console.Out, dir) { Logger = _logger }; var secrets = new KeyValuePair[] { diff --git a/test/Microsoft.Extensions.SecretManager.Tools.Tests/TemporaryFileProvider.cs b/test/Microsoft.Extensions.SecretManager.Tools.Tests/TemporaryFileProvider.cs new file mode 100644 index 0000000..08e4449 --- /dev/null +++ b/test/Microsoft.Extensions.SecretManager.Tools.Tests/TemporaryFileProvider.cs @@ -0,0 +1,29 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.IO; +using System.Text; + +namespace Microsoft.Extensions.SecretsManager.Tools.Tests +{ + internal class TemporaryFileProvider : IDisposable + { + public TemporaryFileProvider() + { + Root = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), "tmpfiles", Guid.NewGuid().ToString())).FullName; + } + + public string Root { get; } + + public void Add(string filename, string contents) + { + File.WriteAllText(Path.Combine(Root, filename), contents, Encoding.UTF8); + } + + public void Dispose() + { + Directory.Delete(Root, recursive: true); + } + } +} \ 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 72d9212..4eb18c2 100644 --- a/test/Microsoft.Extensions.SecretManager.Tools.Tests/UserSecretsTestFixture.cs +++ b/test/Microsoft.Extensions.SecretManager.Tools.Tests/UserSecretsTestFixture.cs @@ -4,11 +4,10 @@ using System; using System.Collections.Generic; using System.IO; -using Microsoft.Extensions.ProjectModel.Tests; namespace Microsoft.Extensions.Configuration.UserSecrets.Tests { - public class UserSecretsTestFixture : MsBuildFixture, IDisposable + public class UserSecretsTestFixture : IDisposable { private Stack _disposables = new Stack(); diff --git a/test/Microsoft.Extensions.SecretManager.Tools.Tests/project.json b/test/Microsoft.Extensions.SecretManager.Tools.Tests/project.json index baa9c8d..537709e 100644 --- a/test/Microsoft.Extensions.SecretManager.Tools.Tests/project.json +++ b/test/Microsoft.Extensions.SecretManager.Tools.Tests/project.json @@ -1,10 +1,7 @@ { "buildOptions": { "warningsAsErrors": true, - "keyFile": "../../tools/Key.snk", - "compile": { - "include": "../Shared/*.cs" - } + "keyFile": "../../tools/Key.snk" }, "dependencies": { "dotnet-test-xunit": "2.2.0-*",