Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion eng/common/SetupNugetSources.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ if ($dotnet31Source -ne $null) {
AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v2" -Creds $creds -Username $userName -pwd $Password
}

$dotnetVersions = @('5','6','7','8','9')
$dotnetVersions = @('5','6','7','8','9','10')

foreach ($dotnetVersion in $dotnetVersions) {
$feedPrefix = "dotnet" + $dotnetVersion;
Expand Down
2 changes: 1 addition & 1 deletion eng/common/SetupNugetSources.sh
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ if [ "$?" == "0" ]; then
PackageSources+=('dotnet3.1-internal-transport')
fi

DotNetVersions=('5' '6' '7' '8' '9')
DotNetVersions=('5' '6' '7' '8' '9' '10')

for DotNetVersion in ${DotNetVersions[@]} ; do
FeedPrefix="dotnet${DotNetVersion}";
Expand Down
1 change: 1 addition & 0 deletions src/Components/Components/src/RouteView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public Task SetParametersAsync(ParameterView parameters)
/// Renders the component.
/// </summary>
/// <param name="builder">The <see cref="RenderTreeBuilder"/>.</param>
[UnconditionalSuppressMessage("Trimming", "IL2110", Justification = "Layout components are preserved because the LayoutAttribute constructor parameter is correctly annotated.")]
[UnconditionalSuppressMessage("Trimming", "IL2111", Justification = "Layout components are preserved because the LayoutAttribute constructor parameter is correctly annotated.")]
[UnconditionalSuppressMessage("Trimming", "IL2118", Justification = "Layout components are preserved because the LayoutAttribute constructor parameter is correctly annotated.")]
protected virtual void Render(RenderTreeBuilder builder)
Expand Down
2 changes: 1 addition & 1 deletion src/Tools/Shared/SecretsHelpers/MsBuildProjectFinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public string FindMsBuildProject(string project)

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

return projectPath;
Expand Down
6 changes: 3 additions & 3 deletions src/Tools/Shared/SecretsHelpers/ProjectIdResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ public string Resolve(string project, string configuration)
UseShellExecute = false,
ArgumentList =
{
"msbuild",
"build",
projectFile,
"/nologo",
"--no-restore",
"/t:_ExtractUserSecretsMetadata", // defined in SecretManager.targets
"/p:_UserSecretsMetadataFile=" + outputFile,
"/p:Configuration=" + configuration,
Expand All @@ -72,7 +72,7 @@ public string Resolve(string project, string configuration)
};

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

using var process = new Process()
Expand Down
8 changes: 4 additions & 4 deletions src/Tools/Shared/SecretsHelpers/SecretsHelpersResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -124,16 +124,16 @@
<value>Multiple MSBuild project files found in '{projectPath}'. Specify which to use with the --project option.</value>
</data>
<data name="Error_NoProjectsFound" xml:space="preserve">
<value>Could not find a MSBuild project file in '{projectPath}'. Specify which project to use with the --project option.</value>
<value>Could not find a MSBuild project file in '{projectPath}'. Specify which project to use with the --project option. Use --file option for file-based apps.</value>
</data>
<data name="Error_ProjectFailedToLoad" xml:space="preserve">
<value>Could not load the MSBuild project '{project}'.</value>
</data>
<data name="Error_ProjectMissingId" xml:space="preserve">
<value>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.</value>
</data>
<data name="Error_ProjectPath_NotFound" xml:space="preserve">
<value>The project file '{0}' does not exist.</value>
<data name="Error_File_NotFound" xml:space="preserve">
<value>The file '{0}' does not exist.</value>
</data>
<data name="Message_ProjectAlreadyInitialized" xml:space="preserve">
<value>The MSBuild project '{project}' has already been initialized with a UserSecretsId.</value>
Expand All @@ -144,4 +144,4 @@
<data name="Message_SetUserSecretsIdForProject" xml:space="preserve">
<value>Set UserSecretsId to '{userSecretsId}' for MSBuild project '{project}'.</value>
</data>
</root>
</root>
12 changes: 11 additions & 1 deletion src/Tools/dotnet-user-secrets/src/CommandLineOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class CommandLineOptions
public bool IsHelp { get; private set; }
public bool IsVerbose { get; private set; }
public string Project { get; private set; }
public string File { get; private set; }

public static CommandLineOptions Parse(string[] args, IConsole console)
{
Expand All @@ -36,6 +37,9 @@ public static CommandLineOptions Parse(string[] args, IConsole console)
var optionProject = app.Option("-p|--project <PROJECT>", "Path to project. Defaults to searching the current directory.",
CommandOptionType.SingleValue, inherited: true);

var optionFile = app.Option("-f|--file <FILE>", "Path to file-based app.",
CommandOptionType.SingleValue, inherited: true);

var optionConfig = app.Option("-c|--configuration <CONFIGURATION>", "The project configuration to use. Defaults to 'Debug'.",
CommandOptionType.SingleValue, inherited: true);

Expand All @@ -50,7 +54,7 @@ public static CommandLineOptions Parse(string[] args, IConsole console)
app.Command("remove", c => RemoveCommand.Configure(c, options));
app.Command("list", c => ListCommand.Configure(c, options));
app.Command("clear", c => ClearCommand.Configure(c, options));
app.Command("init", c => InitCommandFactory.Configure(c, options));
app.Command("init", c => InitCommandFactory.Configure(c, options, optionFile));

// Show help information if no subcommand/option was specified.
app.OnExecute(() => app.ShowHelp());
Expand All @@ -66,6 +70,12 @@ public static CommandLineOptions Parse(string[] args, IConsole console)
options.IsHelp = app.IsShowingInformation;
options.IsVerbose = optionVerbose.HasValue();
options.Project = optionProject.Value();
options.File = optionFile.Value();

if (options.File != null && options.Project != null)
{
throw new CommandParsingException(app, Resources.Error_ProjectAndFileOptions);
}

return options;
}
Expand Down
7 changes: 6 additions & 1 deletion src/Tools/dotnet-user-secrets/src/Internal/InitCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,18 @@ public class InitCommandFactory : ICommand
{
public CommandLineOptions Options { get; }

internal static void Configure(CommandLineApplication command, CommandLineOptions options)
internal static void Configure(CommandLineApplication command, CommandLineOptions options, CommandOption optionFile)
{
command.Description = "Set a user secrets ID to enable secret storage";
command.HelpOption();

command.OnExecute(() =>
{
if (optionFile.HasValue())
{
throw new CommandParsingException(command, Resources.Error_InitNotSupportedForFileBasedApps);
}

options.Command = new InitCommandFactory(options);
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/Tools/dotnet-user-secrets/src/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,6 @@ internal string ResolveId(CommandLineOptions options, IReporter reporter)
}

var resolver = new ProjectIdResolver(reporter, _workingDirectory);
return resolver.Resolve(options.Project, options.Configuration);
return resolver.Resolve(options.Project ?? options.File, options.Configuration);
}
}
16 changes: 8 additions & 8 deletions src/Tools/dotnet-user-secrets/src/Resources.resx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Expand Down Expand Up @@ -133,15 +133,9 @@ Use the '--help' flag to see info.</value>
<data name="Error_No_Secrets_Found" xml:space="preserve">
<value>No secrets configured for this application.</value>
</data>
<data name="Error_NoProjectsFound" xml:space="preserve">
<value>Could not find a MSBuild project file in '{projectPath}'. Specify which project to use with the --project option.</value>
</data>
<data name="Error_ProjectMissingId" xml:space="preserve">
<value>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.</value>
</data>
<data name="Error_ProjectPath_NotFound" xml:space="preserve">
<value>The project file '{path}' does not exist.</value>
</data>
<data name="Error_ProjectFailedToLoad" xml:space="preserve">
<value>Could not load the MSBuild project '{project}'.</value>
</data>
Expand Down Expand Up @@ -169,4 +163,10 @@ Use the '--help' flag to see info.</value>
<data name="Message_SetUserSecretsIdForProject" xml:space="preserve">
<value>Set UserSecretsId to '{userSecretsId}' for MSBuild project '{project}'.</value>
</data>
</root>
<data name="Error_ProjectAndFileOptions" xml:space="preserve">
<value>Cannot use both --file and --project options together.</value>
</data>
<data name="Error_InitNotSupportedForFileBasedApps" xml:space="preserve">
<value>Init command is currently not supported for file-based apps. Please add '#:property UserSecretsId=...' manually.</value>
</data>
</root>
101 changes: 64 additions & 37 deletions src/Tools/dotnet-user-secrets/test/SecretManagerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.IO;
using System.Text;
using Microsoft.AspNetCore.InternalTesting;
using Microsoft.AspNetCore.Tools;
using Microsoft.Extensions.Configuration.UserSecrets;
using Microsoft.Extensions.Configuration.UserSecrets.Tests;
using Microsoft.Extensions.Tools.Internal;
Expand Down Expand Up @@ -64,7 +65,27 @@ public void Error_Project_DoesNotExist()
var secretManager = CreateProgram();

secretManager.RunInternal("list", "--project", projectPath);
Assert.Contains(Resources.FormatError_ProjectPath_NotFound(projectPath), _console.GetOutput());
Assert.Contains(SecretsHelpersResources.FormatError_File_NotFound(projectPath), _console.GetOutput());
}

[Fact]
public void Error_ProjectAndFileOptions()
{
var projectPath = Path.Combine(_fixture.GetTempSecretProject(), "does_not_exist", "TestProject.csproj");
var secretManager = CreateProgram();

secretManager.RunInternal("list", "--project", projectPath, "--file", projectPath);
Assert.Contains(Resources.Error_ProjectAndFileOptions, _console.GetOutput());
}

[Fact]
public void Error_InitFile()
{
var dir = _fixture.CreateFileBasedApp(null);
var secretManager = CreateProgram();

secretManager.RunInternal("init", "--file", Path.Combine(dir, "app.cs"));
Assert.Contains(Resources.Error_InitNotSupportedForFileBasedApps, _console.GetOutput());
}

[Fact]
Expand All @@ -81,9 +102,10 @@ public void SupportsRelativePaths()
}

[Theory]
[InlineData(true)]
[InlineData(false)]
public void SetSecrets(bool fromCurrentDirectory)
[InlineData(false, true)]
[InlineData(false, false)]
[InlineData(true, false)]
public void SetSecrets(bool fromCurrentDirectory, bool fileBasedApp)
{
var secrets = new KeyValuePair<string, string>[]
{
Expand All @@ -95,18 +117,22 @@ public void SetSecrets(bool fromCurrentDirectory)
new KeyValuePair<string, string>("--twoDashedKey", "--twoDashedValue")
};

var projectPath = _fixture.GetTempSecretProject();
var projectPath = fileBasedApp
? _fixture.GetTempFileBasedApp(out _)
: _fixture.GetTempSecretProject();
var dir = fromCurrentDirectory
? projectPath
: Path.GetTempPath();
ReadOnlySpan<string> pathArgs = fromCurrentDirectory
? []
: (fileBasedApp
? ["-f", Path.Join(projectPath, "app.cs")]
: ["-p", projectPath]);
var secretManager = new Program(_console, dir);

foreach (var secret in secrets)
{
var parameters = fromCurrentDirectory ?
new string[] { "set", secret.Key, secret.Value, "--verbose" } :
new string[] { "set", secret.Key, secret.Value, "-p", projectPath, "--verbose" };
secretManager.RunInternal(parameters);
secretManager.RunInternal(["set", secret.Key, secret.Value, .. pathArgs, "--verbose"]);
}

foreach (var keyValue in secrets)
Expand All @@ -117,10 +143,7 @@ public void SetSecrets(bool fromCurrentDirectory)
}

_console.ClearOutput();
var args = fromCurrentDirectory
? new string[] { "list", "--verbose" }
: new string[] { "list", "-p", projectPath, "--verbose" };
secretManager.RunInternal(args);
secretManager.RunInternal(["list", .. pathArgs, "--verbose"]);
foreach (var keyValue in secrets)
{
Assert.Contains(
Expand All @@ -132,21 +155,24 @@ public void SetSecrets(bool fromCurrentDirectory)
_console.ClearOutput();
foreach (var secret in secrets)
{
var parameters = fromCurrentDirectory ?
new string[] { "remove", secret.Key, "--verbose" } :
new string[] { "remove", secret.Key, "-p", projectPath, "--verbose" };
secretManager.RunInternal(parameters);
secretManager.RunInternal(["remove", secret.Key, .. pathArgs, "--verbose"]);
}

// Verify secrets are removed.
_console.ClearOutput();
args = fromCurrentDirectory
? new string[] { "list", "--verbose" }
: new string[] { "list", "-p", projectPath, "--verbose" };
secretManager.RunInternal(args);
secretManager.RunInternal(["list", .. pathArgs, "--verbose"]);
Assert.Contains(Resources.Error_No_Secrets_Found, _console.GetOutput());
}

[Fact]
public void SetSecrets_FileBasedAppInCurrentDirectory()
{
var directoryPath = _fixture.GetTempFileBasedApp(out _);
var secretManager = new Program(_console, directoryPath);
secretManager.RunInternal("set", "key1", "value1", "--verbose");
Assert.Contains(SecretsHelpersResources.FormatError_NoProjectsFound(directoryPath), _console.GetOutput());
}

[Fact]
public void SetSecret_Update_Existing_Secret()
{
Expand Down Expand Up @@ -268,16 +294,25 @@ public void List_Empty_Secrets_File()
}

[Theory]
[InlineData(true)]
[InlineData(false)]
public void Clear_Secrets(bool fromCurrentDirectory)
[InlineData(false, true)]
[InlineData(false, false)]
[InlineData(true, false)]
public void Clear_Secrets(bool fromCurrentDirectory, bool fileBasedApp)
{
var projectPath = _fixture.GetTempSecretProject();
var projectPath = fileBasedApp
? _fixture.GetTempFileBasedApp(out _)
: _fixture.GetTempSecretProject();

var dir = fromCurrentDirectory
? projectPath
: Path.GetTempPath();

ReadOnlySpan<string> pathArgs = fromCurrentDirectory
? []
: (fileBasedApp
? ["-f", Path.Join(projectPath, "app.cs")]
: ["-p", projectPath]);

var secretManager = new Program(_console, dir);

var secrets = new KeyValuePair<string, string>[]
Expand All @@ -290,10 +325,7 @@ public void Clear_Secrets(bool fromCurrentDirectory)

foreach (var secret in secrets)
{
var parameters = fromCurrentDirectory ?
new string[] { "set", secret.Key, secret.Value, "--verbose" } :
new string[] { "set", secret.Key, secret.Value, "-p", projectPath, "--verbose" };
secretManager.RunInternal(parameters);
secretManager.RunInternal(["set", secret.Key, secret.Value, .. pathArgs, "--verbose"]);
}

foreach (var keyValue in secrets)
Expand All @@ -305,10 +337,7 @@ public void Clear_Secrets(bool fromCurrentDirectory)

// Verify secrets are persisted.
_console.ClearOutput();
var args = fromCurrentDirectory ?
new string[] { "list", "--verbose" } :
new string[] { "list", "-p", projectPath, "--verbose" };
secretManager.RunInternal(args);
secretManager.RunInternal(["list", .. pathArgs, "--verbose"]);
foreach (var keyValue in secrets)
{
Assert.Contains(
Expand All @@ -318,11 +347,9 @@ public void Clear_Secrets(bool fromCurrentDirectory)

// Clear secrets.
_console.ClearOutput();
args = fromCurrentDirectory ? new string[] { "clear", "--verbose" } : new string[] { "clear", "-p", projectPath, "--verbose" };
secretManager.RunInternal(args);
secretManager.RunInternal(["clear", .. pathArgs, "--verbose"]);

args = fromCurrentDirectory ? new string[] { "list", "--verbose" } : new string[] { "list", "-p", projectPath, "--verbose" };
secretManager.RunInternal(args);
secretManager.RunInternal(["list", .. pathArgs, "--verbose"]);
Assert.Contains(Resources.Error_No_Secrets_Found, _console.GetOutput());
}

Expand Down
Loading
Loading