Move UpgradeOptions into CLI class (#666)

UpgradeOptions should be an implementation detail of the CLI as it is tightly bound to the command line parsing. The names on it cannot be changed without breaking that binding, and has ended up being a bag of a bunch of options.

This change introduces new options for the parts of the system that needed it and flows the values to them via:

- Directly configuring the options in the ConfigureServices
- Setting them up as extension options for values that are needed in extensions and cannot be directly set
This commit is contained in:
Taylor Southwick 2021-06-25 14:02:19 -07:00 коммит произвёл GitHub
Родитель ed131abba5
Коммит d621fc1ae0
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
27 изменённых файлов: 245 добавлений и 105 удалений

Просмотреть файл

@ -0,0 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.ComponentModel.DataAnnotations;
namespace Microsoft.DotNet.UpgradeAssistant.Cli
{
public class FileStateOptions
{
[Required]
public string Path { get; set; } = null!;
}
}

Просмотреть файл

@ -10,6 +10,7 @@ using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Microsoft.DotNet.UpgradeAssistant.Cli
{
@ -19,7 +20,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.Cli
private readonly ILogger<FileUpgradeStateFactory> _logger;
public FileUpgradeStateFactory(
UpgradeOptions options,
IOptions<FileStateOptions> options,
ILogger<FileUpgradeStateFactory> logger)
{
if (options is null)
@ -27,7 +28,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.Cli
throw new ArgumentNullException(nameof(options));
}
_path = Path.Combine(options.Project.DirectoryName!, ".upgrade-assistant");
_path = options.Value.Path;
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}

Просмотреть файл

@ -0,0 +1,12 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
namespace Microsoft.DotNet.UpgradeAssistant.Cli
{
public class NonInteractiveOptions
{
public TimeSpan Wait { get; set; }
}
}

Просмотреть файл

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
namespace Microsoft.DotNet.UpgradeAssistant.Cli
{
@ -13,14 +14,14 @@ namespace Microsoft.DotNet.UpgradeAssistant.Cli
{
private readonly TimeSpan _waitPeriod;
public NonInteractiveUserInput(UpgradeOptions options)
public NonInteractiveUserInput(IOptions<NonInteractiveOptions> options)
{
if (options is null)
{
throw new ArgumentNullException(nameof(options));
}
_waitPeriod = TimeSpan.FromSeconds(options.NonInteractiveWait);
_waitPeriod = options.Value.Wait;
}
public bool IsInteractive => false;

Просмотреть файл

@ -3,6 +3,7 @@
using System;
using System.CommandLine.Parsing;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Autofac.Extensions.DependencyInjection;
@ -17,7 +18,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.Cli
{
public static class UpgradeAssistantHostExtensions
{
public static IHostBuilder UseUpgradeAssistant<TApp>(this IHostBuilder host, UpgradeOptions options)
public static IHostBuilder UseUpgradeAssistant<TApp>(this IHostBuilder host, UpgradeOptions upgradeOptions)
where TApp : class, IAppCommand
{
if (host is null)
@ -25,9 +26,9 @@ namespace Microsoft.DotNet.UpgradeAssistant.Cli
throw new ArgumentNullException(nameof(host));
}
if (options is null)
if (upgradeOptions is null)
{
throw new ArgumentNullException(nameof(options));
throw new ArgumentNullException(nameof(upgradeOptions));
}
return host
@ -44,35 +45,38 @@ namespace Microsoft.DotNet.UpgradeAssistant.Cli
});
services.AddHostedService<ConsoleRunner>();
services.AddSingleton<IUpgradeStateManager, FileUpgradeStateFactory>();
services.AddStateFactory(upgradeOptions);
services.AddExtensions()
.AddDefaultExtensions(context.Configuration)
.AddFromEnvironmentVariables(context.Configuration)
.Configure(opts =>
.Configure(options =>
{
opts.RetainedProperties = options.Option.ParseOptions();
opts.CurrentVersion = UpgradeVersion.Current.Version;
options.AdditionalOptions = upgradeOptions.Option.ParseOptions();
options.CurrentVersion = UpgradeVersion.Current.Version;
foreach (var path in options.Extension)
foreach (var path in upgradeOptions.Extension)
{
opts.ExtensionPaths.Add(path);
options.ExtensionPaths.Add(path);
}
})
.AddExtensionOption(new
{
Backup = new { Skip = upgradeOptions.SkipBackup },
Solution = new { EntryPoints = upgradeOptions.EntryPoint }
});
services.AddMsBuild();
services.AddSingleton(options);
services.AddMsBuild(optionss =>
{
optionss.InputPath = upgradeOptions.ProjectPath;
});
// Add command handlers
if (options.NonInteractive)
services.AddNuGet(optionss =>
{
services.AddTransient<IUserInput, NonInteractiveUserInput>();
}
else
{
services.AddTransient<IUserInput, ConsoleCollectUserInput>();
}
optionss.PackageSourcePath = Path.GetDirectoryName(upgradeOptions.ProjectPath);
});
services.AddUserInput(upgradeOptions);
services.AddSingleton(new InputOutputStreams(Console.In, Console.Out));
services.AddSingleton<CommandProvider>();
@ -81,7 +85,17 @@ namespace Microsoft.DotNet.UpgradeAssistant.Cli
services.AddSingleton<IProcessRunner, ProcessRunner>();
services.AddSingleton<ErrorCodeAccessor>();
services.AddStepManagement(context.Configuration.GetSection("DefaultTargetFrameworks").Bind);
services.AddStepManagement();
services.AddTargetFrameworkSelectors(options =>
{
context.Configuration.GetSection("DefaultTargetFrameworks").Bind(options);
options.TargetTfmSupport = upgradeOptions.TargetTfmSupport;
});
services.AddReadinessChecks(options =>
{
options.IgnoreUnsupportedFeatures = upgradeOptions.IgnoreUnsupportedFeatures;
});
services.AddScoped<IAppCommand, TApp>();
})
@ -91,6 +105,36 @@ namespace Microsoft.DotNet.UpgradeAssistant.Cli
});
}
private static void AddStateFactory(this IServiceCollection services, UpgradeOptions upgradeOptions)
{
services.AddSingleton<IUpgradeStateManager, FileUpgradeStateFactory>();
services
.AddOptions<FileStateOptions>()
.Configure(options =>
{
options.Path = Path.Combine(upgradeOptions.Project.DirectoryName!, ".upgrade-assistant");
})
.ValidateDataAnnotations();
}
private static void AddUserInput(this IServiceCollection services, UpgradeOptions upgradeOptions)
{
if (upgradeOptions.NonInteractive)
{
services.AddTransient<IUserInput, NonInteractiveUserInput>();
services
.AddOptions<NonInteractiveOptions>()
.Configure(options =>
{
options.Wait = TimeSpan.FromSeconds(upgradeOptions.NonInteractiveWait);
});
}
else
{
services.AddTransient<IUserInput, ConsoleCollectUserInput>();
}
}
public static IHostBuilder UseConsoleUpgradeAssistant<TApp>(
this IHostBuilder host,
UpgradeOptions options,

Просмотреть файл

@ -46,9 +46,9 @@ namespace Microsoft.DotNet.UpgradeAssistant.Extensions
logger.LogInformation("Loaded {Count} extensions", list.Count);
if (options.Value.RetainedProperties.Any())
if (options.Value.AdditionalOptions.Any())
{
list.Add(LoadOptionsExtension(options.Value.RetainedProperties));
list.Add(LoadOptionsExtension(options.Value.AdditionalOptions));
}
return list;

Просмотреть файл

@ -11,7 +11,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.Extensions
{
public ICollection<string> ExtensionPaths { get; } = new List<string>();
public IEnumerable<KeyValuePair<string, string>> RetainedProperties { get; set; } = Enumerable.Empty<KeyValuePair<string, string>>();
public IEnumerable<KeyValuePair<string, string>> AdditionalOptions { get; set; } = Enumerable.Empty<KeyValuePair<string, string>>();
public Version CurrentVersion { get; set; } = null!;
}

Просмотреть файл

@ -9,6 +9,7 @@ using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Options;
namespace Microsoft.DotNet.UpgradeAssistant.Extensions
@ -96,6 +97,27 @@ namespace Microsoft.DotNet.UpgradeAssistant.Extensions
});
}
public static OptionsBuilder<ExtensionOptions> AddExtensionOption<TOption>(this OptionsBuilder<ExtensionOptions> builder, TOption option)
{
if (builder is null)
{
throw new ArgumentNullException(nameof(builder));
}
var json = JsonSerializer.SerializeToUtf8Bytes(option);
using var stream = new MemoryStream(json);
var config = new ConfigurationBuilder()
.AddJsonStream(stream)
.Build();
#pragma warning disable CA2000 // Dispose objects before losing scope
builder.Services.AddSingleton(new ExtensionInstance(new PhysicalFileProvider(Environment.CurrentDirectory), Environment.CurrentDirectory, config));
#pragma warning restore CA2000 // Dispose objects before losing scope
return builder;
}
public static OptionsBuilder<ExtensionOptions> AddFromEnvironmentVariables(this OptionsBuilder<ExtensionOptions> builder, IConfiguration configuration)
{
if (builder is null)

Просмотреть файл

@ -11,6 +11,7 @@ using Microsoft.Build.Evaluation;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.MSBuild;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Microsoft.DotNet.UpgradeAssistant.MSBuild
{
@ -53,7 +54,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.MSBuild
public UpgradeStep? CurrentStep { get; set; }
public MSBuildWorkspaceUpgradeContext(
UpgradeOptions options,
IOptions<WorkspaceOptions> options,
IVisualStudioFinder vsFinder,
Func<string, ISolutionInfo> infoGenerator,
IPackageRestorer restorer,
@ -62,18 +63,13 @@ namespace Microsoft.DotNet.UpgradeAssistant.MSBuild
ILogger<MSBuildWorkspaceUpgradeContext> logger,
IUpgradeContextProperties properties)
{
if (options is null)
{
throw new ArgumentNullException(nameof(options));
}
if (vsFinder is null)
{
throw new ArgumentNullException(nameof(vsFinder));
}
_projectCache = new Dictionary<string, IProject>(StringComparer.OrdinalIgnoreCase);
InputPath = options.ProjectPath;
InputPath = options.Value.InputPath;
_restorer = restorer;
_comparer = comparer;
_componentIdentifier = componentIdentifier ?? throw new ArgumentNullException(nameof(componentIdentifier));

Просмотреть файл

@ -6,5 +6,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.MSBuild
public class NuGetDownloaderOptions
{
public string? CachePath { get; set; }
public string? PackageSourcePath { get; set; }
}
}

Просмотреть файл

@ -32,16 +32,10 @@ namespace Microsoft.DotNet.UpgradeAssistant.MSBuild
private readonly NuGetDownloaderOptions _options;
public PackageLoader(
UpgradeOptions upgradeOptions,
INuGetPackageSourceFactory sourceFactory,
ILogger<PackageLoader> logger,
IOptions<NuGetDownloaderOptions> options)
{
if (upgradeOptions is null)
{
throw new ArgumentNullException(nameof(upgradeOptions));
}
if (sourceFactory is null)
{
throw new ArgumentNullException(nameof(sourceFactory));
@ -52,17 +46,12 @@ namespace Microsoft.DotNet.UpgradeAssistant.MSBuild
throw new ArgumentNullException(nameof(options));
}
if (upgradeOptions.ProjectPath is null)
{
throw new ArgumentException("Project path must be set in UpgradeOptions", nameof(upgradeOptions));
}
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_nugetLogger = new NuGetLogger(logger);
_cache = new SourceCacheContext();
_packageSources = new Lazy<IEnumerable<PackageSource>>(() => sourceFactory.GetPackageSources(Path.GetDirectoryName(upgradeOptions.ProjectPath)));
_sourceRepositoryCache = new Dictionary<PackageSource, SourceRepository>();
_options = options.Value;
_packageSources = new Lazy<IEnumerable<PackageSource>>(() => sourceFactory.GetPackageSources(_options.PackageSourcePath));
_sourceRepositoryCache = new Dictionary<PackageSource, SourceRepository>();
}
public async Task<bool> DoesPackageSupportTargetFrameworksAsync(NuGetReference packageReference, IEnumerable<TargetFrameworkMoniker> targetFrameworks, CancellationToken token)

Просмотреть файл

@ -15,7 +15,7 @@ namespace Microsoft.DotNet.UpgradeAssistant
{
private static readonly string[] ItemTypesToDeduplicate = new[] { "Compile", "Content" };
public static void AddMsBuild(this IServiceCollection services)
public static void AddMsBuild(this IServiceCollection services, Action<WorkspaceOptions> configure)
{
services.AddSingleton<MSBuildPathLocator>();
services.AddSingleton<IVisualStudioFinder, VisualStudioFinder>();
@ -30,10 +30,12 @@ namespace Microsoft.DotNet.UpgradeAssistant
services.AddTransient<IUpgradeContext>(sp => sp.GetRequiredService<MSBuildWorkspaceUpgradeContext>());
services.AddTransient<Func<MSBuildWorkspaceUpgradeContext>>(sp => () => sp.GetRequiredService<MSBuildWorkspaceUpgradeContext>());
services.AddNuGet();
services.AddOptions<WorkspaceOptions>()
.Configure(configure)
.ValidateDataAnnotations();
}
private static void AddNuGet(this IServiceCollection services)
public static void AddNuGet(this IServiceCollection services, Action<NuGetDownloaderOptions> configure)
{
services.AddSingleton<IPackageLoader, PackageLoader>();
services.AddSingleton<IVersionComparer, NuGetVersionComparer>();
@ -41,6 +43,7 @@ namespace Microsoft.DotNet.UpgradeAssistant
services.AddSingleton<IUpgradeStartup, NuGetCredentialsStartup>();
services.AddSingleton<INuGetPackageSourceFactory, NuGetPackageSourceFactory>();
services.AddOptions<NuGetDownloaderOptions>()
.Configure(configure)
.Configure(options =>
{
var settings = Settings.LoadDefaultSettings(null);

Просмотреть файл

@ -0,0 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.ComponentModel.DataAnnotations;
namespace Microsoft.DotNet.UpgradeAssistant.MSBuild
{
public class WorkspaceOptions
{
[Required]
public string InputPath { get; set; } = null!;
}
}

Просмотреть файл

@ -5,7 +5,7 @@ using System.ComponentModel.DataAnnotations;
namespace Microsoft.DotNet.UpgradeAssistant
{
public class DefaultTfmOptions
public record DefaultTfmOptions
{
[Required]
public string Current { get; set; } = null!;
@ -15,5 +15,7 @@ namespace Microsoft.DotNet.UpgradeAssistant
[Required]
public string Preview { get; set; } = null!;
public UpgradeTarget TargetTfmSupport { get; set; } = UpgradeTarget.Current;
}
}

Просмотреть файл

@ -17,10 +17,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.TargetFramework
private readonly IEnumerable<ITargetFrameworkSelectorFilter> _selectors;
private readonly ILogger<TargetFrameworkSelector> _logger;
private readonly UpgradeTarget _upgradeTarget;
public TargetFrameworkSelector(
UpgradeOptions options,
ITargetFrameworkMonikerComparer comparer,
IOptions<DefaultTfmOptions> selectorOptions,
IEnumerable<ITargetFrameworkSelectorFilter> selectors,
@ -30,8 +27,6 @@ namespace Microsoft.DotNet.UpgradeAssistant.TargetFramework
_selectorOptions = selectorOptions?.Value ?? throw new ArgumentNullException(nameof(selectorOptions));
_selectors = selectors;
_logger = logger;
_upgradeTarget = options?.TargetTfmSupport ?? throw new ArgumentNullException(nameof(options));
}
public async ValueTask<TargetFrameworkMoniker> SelectTargetFrameworkAsync(IProject project, CancellationToken token)
@ -41,7 +36,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.TargetFramework
throw new ArgumentNullException(nameof(project));
}
var appBase = _upgradeTarget switch
var appBase = _selectorOptions.TargetTfmSupport switch
{
UpgradeTarget.Current => _selectorOptions.Current,
UpgradeTarget.Preview => _selectorOptions.Preview,

Просмотреть файл

@ -11,18 +11,12 @@ namespace Microsoft.DotNet.UpgradeAssistant
{
public static class UpgraderExtensions
{
public static void AddStepManagement(this IServiceCollection services, Action<DefaultTfmOptions> options)
public static void AddStepManagement(this IServiceCollection services)
{
services.AddScoped<UpgraderManager>();
services.AddTransient<IUpgradeContextProperties, UpgradeContextProperties>();
services.AddTransient<IUpgradeStepOrderer, UpgradeStepOrderer>();
services.AddReadinessChecks();
services.AddTargetFrameworkSelectors();
services.AddOptions<DefaultTfmOptions>()
.Configure(options)
.ValidateDataAnnotations();
services.AddContextTelemetry();
}
@ -33,7 +27,7 @@ namespace Microsoft.DotNet.UpgradeAssistant
services.AddTransient<IUpgradeContextAccessor>(ctx => ctx.GetRequiredService<UpgradeContextTelemetry>());
}
private static void AddReadinessChecks(this IServiceCollection services)
public static void AddReadinessChecks(this IServiceCollection services, Action<UpgradeReadinessOptions> configure)
{
services.AddTransient<IUpgradeReadyCheck, CanLoadProjectFile>();
services.AddTransient<IUpgradeReadyCheck, CentralPackageManagementCheck>();
@ -43,14 +37,15 @@ namespace Microsoft.DotNet.UpgradeAssistant
services.AddTransient<IUpgradeReadyCheck, WcfServerCheck>();
services.AddOptions<UpgradeReadinessOptions>()
.Configure<UpgradeOptions>((upgradeReadinessOptions, upgradeOptions) =>
{
upgradeReadinessOptions.IgnoreUnsupportedFeatures = upgradeOptions.IgnoreUnsupportedFeatures;
});
.Configure(configure);
}
private static void AddTargetFrameworkSelectors(this IServiceCollection services)
public static void AddTargetFrameworkSelectors(this IServiceCollection services, Action<DefaultTfmOptions> configure)
{
services.AddOptions<DefaultTfmOptions>()
.Configure(configure)
.ValidateDataAnnotations();
services.AddTransient<ITargetFrameworkSelector, TargetFrameworkSelector>();
services.AddTransient<ITargetFrameworkSelectorFilter, DependencyMinimumTargetFrameworkSelectorFilter>();

Просмотреть файл

@ -31,12 +31,12 @@ namespace Microsoft.DotNet.UpgradeAssistant.Extensions.Default
private static void AddUpgradeSteps(IExtensionServiceCollection services)
{
services.Services.AddBackupStep();
services.AddBackupStep();
services.AddConfigUpdaterStep();
services.AddPackageUpdaterStep();
services.AddProjectFormatSteps()
.Bind(services.Configuration.GetSection(TryConvertProjectConverterStepOptionsSection));
services.Services.AddSolutionSteps();
services.AddSolutionSteps();
services.AddSourceUpdaterStep();
services.AddTemplateInserterStep();
}

Просмотреть файл

@ -0,0 +1,10 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
namespace Microsoft.DotNet.UpgradeAssistant.Steps.Backup
{
public class BackupOptions
{
public bool Skip { get; set; }
}
}

Просмотреть файл

@ -7,6 +7,7 @@ using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Microsoft.DotNet.UpgradeAssistant.Steps.Backup
{
@ -35,10 +36,18 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Backup
WellKnownStepIds.NextProjectStepId,
};
public BackupStep(UpgradeOptions options, ILogger<BackupStep> logger, IUserInput userInput, IUpgradeContextProperties properties)
public BackupStep(
IUserInput userInput,
IOptions<BackupOptions> options,
ILogger<BackupStep> logger)
: base(logger)
{
_skipBackup = options?.SkipBackup ?? throw new ArgumentNullException(nameof(options));
if (options is null)
{
throw new ArgumentNullException(nameof(options));
}
_skipBackup = options.Value.Skip;
_userInput = userInput ?? throw new ArgumentNullException(nameof(userInput));
}

Просмотреть файл

@ -1,14 +1,23 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using Microsoft.DotNet.UpgradeAssistant.Extensions;
using Microsoft.DotNet.UpgradeAssistant.Steps.Backup;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.DotNet.UpgradeAssistant
{
public static class BackupStepExtensions
{
public static IServiceCollection AddBackupStep(this IServiceCollection services) =>
services.AddUpgradeStep<BackupStep>();
public static void AddBackupStep(this IExtensionServiceCollection services)
{
if (services is null)
{
throw new ArgumentNullException(nameof(services));
}
services.Services.AddUpgradeStep<BackupStep>();
services.AddExtensionOption<BackupOptions>("Backup");
}
}
}

Просмотреть файл

@ -7,6 +7,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Microsoft.DotNet.UpgradeAssistant.Steps.Solution
{
@ -14,18 +15,18 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Solution
{
private readonly IPackageRestorer _restorer;
private readonly IUserInput _userInput;
private readonly UpgradeOptions _options;
private readonly IEntrypointResolver _entrypointResolver;
private readonly SolutionOptions _options;
public EntrypointSelectionStep(
UpgradeOptions options,
IOptions<SolutionOptions> options,
IEntrypointResolver entrypointResolver,
IPackageRestorer restorer,
IUserInput userInput,
ILogger<EntrypointSelectionStep> logger)
: base(logger)
{
_options = options;
_options = options?.Value ?? throw new ArgumentNullException(nameof(options));
_entrypointResolver = entrypointResolver ?? throw new ArgumentNullException(nameof(entrypointResolver));
_restorer = restorer ?? throw new ArgumentNullException(nameof(restorer));
_userInput = userInput ?? throw new ArgumentNullException(nameof(userInput));
@ -103,7 +104,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Solution
return new UpgradeStepInitializeResult(UpgradeStepStatus.Complete, "Selected user's choice of entry point project.", BuildBreakRisk.None);
}
context.EntryPoints = _entrypointResolver.GetEntrypoints(context.Projects, _options.EntryPoint);
context.EntryPoints = _entrypointResolver.GetEntrypoints(context.Projects, _options.Entrypoints);
if (context.EntryPoints.Any())
{

Просмотреть файл

@ -0,0 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
namespace Microsoft.DotNet.UpgradeAssistant.Steps.Solution
{
public class SolutionOptions
{
public IReadOnlyCollection<string> Entrypoints { get; set; } = Array.Empty<string>();
}
}

Просмотреть файл

@ -1,6 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using Microsoft.DotNet.UpgradeAssistant.Extensions;
using Microsoft.DotNet.UpgradeAssistant.Steps.Solution;
using Microsoft.Extensions.DependencyInjection;
@ -8,14 +10,21 @@ namespace Microsoft.DotNet.UpgradeAssistant
{
public static class SolutionStepsExtensions
{
public static void AddSolutionSteps(this IServiceCollection services)
public static void AddSolutionSteps(this IExtensionServiceCollection services)
{
services.AddSingleton<IEntrypointResolver, EntrypointResolver>();
if (services is null)
{
throw new ArgumentNullException(nameof(services));
}
services.AddUpgradeStep<CurrentProjectSelectionStep>();
services.AddUpgradeStep<NextProjectStep>();
services.AddUpgradeStep<FinalizeSolutionStep>();
services.AddUpgradeStep<EntrypointSelectionStep>();
services.Services.AddSingleton<IEntrypointResolver, EntrypointResolver>();
services.Services.AddUpgradeStep<CurrentProjectSelectionStep>();
services.Services.AddUpgradeStep<NextProjectStep>();
services.Services.AddUpgradeStep<FinalizeSolutionStep>();
services.Services.AddUpgradeStep<EntrypointSelectionStep>();
services.AddExtensionOption<SolutionOptions>("Solution");
}
}
}

Просмотреть файл

@ -62,8 +62,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.Tests
project.Setup(p => p.TargetFrameworks).Returns(currentTfms.Select(t => ParseTfm(t)).ToArray());
project.Setup(p => p.GetComponentsAsync(default)).Returns(new ValueTask<ProjectComponents>(components));
mock.Create<UpgradeOptions>().TargetTfmSupport = target;
mock.Mock<IOptions<DefaultTfmOptions>>().Setup(o => o.Value).Returns(_options);
mock.Mock<IOptions<DefaultTfmOptions>>().Setup(o => o.Value).Returns(_options with { TargetTfmSupport = target });
var moniker = mock.Mock<ITargetFrameworkMonikerComparer>();
moniker.Setup(c => c.TryMerge(ParseTfm(current), tfm, out finalTfm)).Returns(true);

Просмотреть файл

@ -9,6 +9,7 @@ using System.Threading;
using System.Threading.Tasks;
using Autofac;
using Autofac.Extras.Moq;
using Microsoft.Extensions.Options;
using Moq;
using Xunit;
@ -30,7 +31,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Backup.Tests
projectPath = Path.GetFullPath(Path.Combine("TestAssets", projectPath));
expectedBackupPath = Path.GetFullPath(Path.Combine("TestAssets", expectedBackupPath));
using var mock = GetMock(GetDefaultNonInteractiveOptions());
using var mock = GetMock();
var context = GetContext(mock, inputPath, projectPath);
var step = mock.Create<BackupStep>();
var expectedStatus = backupComplete ? UpgradeStepStatus.Complete : UpgradeStepStatus.Incomplete;
@ -67,7 +68,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Backup.Tests
expectedBaseBackupPath = Path.GetFullPath(Path.Combine("TestAssets", expectedBaseBackupPath));
expectedBackupPath = Path.GetFullPath(Path.Combine("TestAssets", expectedBackupPath));
using var mock = GetMock(GetDefaultNonInteractiveOptions());
using var mock = GetMock();
var context = GetContext(mock, inputPath, projectPath);
var step = mock.Create<BackupStep>();
step.SetStatus(UpgradeStepStatus.Incomplete);
@ -106,22 +107,15 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Backup.Tests
}
}
private static UpgradeOptions GetDefaultNonInteractiveOptions() =>
new()
{
NonInteractive = true,
NonInteractiveWait = 0,
SkipBackup = false,
};
private static AutoMock GetMock(UpgradeOptions options)
private static AutoMock GetMock()
{
var mock = AutoMock.GetLoose(cfg =>
{
cfg.RegisterInstance(options);
cfg.RegisterType<MockedUserInput>().As<IUserInput>();
});
mock.Mock<IOptions<BackupOptions>>().Setup(o => o.Value).Returns(new BackupOptions());
return mock;
}

Просмотреть файл

@ -6,6 +6,7 @@ using System.Linq;
using System.Threading.Tasks;
using Autofac.Extras.Moq;
using AutoFixture;
using Microsoft.Extensions.Options;
using Moq;
using Xunit;
@ -29,6 +30,7 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Solution.Tests
var context = mock.Mock<IUpgradeContext>();
context.Setup(c => c.EntryPoints).Returns(new[] { new Mock<IProject>().Object });
mock.Mock<IOptions<SolutionOptions>>().Setup(o => o.Value).Returns(new SolutionOptions());
var step = mock.Create<EntrypointSelectionStep>();
// Act
@ -44,6 +46,8 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Solution.Tests
// Arrange
using var mock = AutoMock.GetLoose();
mock.Mock<IOptions<SolutionOptions>>().Setup(o => o.Value).Returns(new SolutionOptions());
var project = new Mock<IProject>().Object;
var context = mock.Mock<IUpgradeContext>();
context.SetupProperty(t => t.EntryPoints);
@ -78,6 +82,8 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Solution.Tests
var inputProject = projects[ProjectCount / 2];
mock.Mock<IOptions<SolutionOptions>>().Setup(o => o.Value).Returns(new SolutionOptions());
var context = mock.Mock<IUpgradeContext>();
context.Setup(c => c.InputIsSolution).Returns(false);
context.SetupProperty(t => t.EntryPoints);
@ -119,11 +125,11 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Solution.Tests
context.Setup(c => c.Projects).Returns(projects);
context.Object.EntryPoints = Enumerable.Empty<IProject>();
var options = mock.Create<UpgradeOptions>();
options.EntryPoint = _fixture.CreateMany<string>().ToList();
var options = mock.Mock<IOptions<SolutionOptions>>();
options.Setup(o => o.Value).Returns(new SolutionOptions { Entrypoints = _fixture.CreateMany<string>().ToList() });
var resolver = mock.Mock<IEntrypointResolver>();
resolver.Setup(r => r.GetEntrypoints(projects, options.EntryPoint)).Returns(new[] { selectedProject });
resolver.Setup(r => r.GetEntrypoints(projects, options.Object.Value.Entrypoints)).Returns(new[] { selectedProject });
var step = mock.Create<EntrypointSelectionStep>();
@ -145,6 +151,8 @@ namespace Microsoft.DotNet.UpgradeAssistant.Steps.Solution.Tests
mock.Mock<IUserInput>().Setup(u => u.IsInteractive).Returns(isInteractive);
mock.Mock<IOptions<SolutionOptions>>().Setup(o => o.Value).Returns(new SolutionOptions());
var context = mock.Mock<IUpgradeContext>();
context.Setup(c => c.InputIsSolution).Returns(true);
context.SetupProperty(t => t.EntryPoints);