diff --git a/src/EFCore.Design/Design/IOperationResultHandler.cs b/src/EFCore.Design/Design/IOperationResultHandler.cs index 5e14819e4d5..597aa26a16f 100644 --- a/src/EFCore.Design/Design/IOperationResultHandler.cs +++ b/src/EFCore.Design/Design/IOperationResultHandler.cs @@ -3,6 +3,8 @@ using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Design { /// @@ -20,7 +22,7 @@ public interface IOperationResultHandler /// Invoked when a result is available. /// /// The result. - void OnResult([CanBeNull] object value); + void OnResult([CanBeNull] object? value); /// /// Invoked when an error occurs. diff --git a/src/EFCore.Design/Design/OperationReportHandler.cs b/src/EFCore.Design/Design/OperationReportHandler.cs index 56ed7cc42ab..9650023693b 100644 --- a/src/EFCore.Design/Design/OperationReportHandler.cs +++ b/src/EFCore.Design/Design/OperationReportHandler.cs @@ -4,6 +4,8 @@ using System; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Design { /// @@ -11,10 +13,10 @@ namespace Microsoft.EntityFrameworkCore.Design /// public class OperationReportHandler : MarshalByRefObject, IOperationReportHandler { - private readonly Action _errorHandler; - private readonly Action _warningHandler; - private readonly Action _informationHandler; - private readonly Action _verboseHandler; + private readonly Action? _errorHandler; + private readonly Action? _warningHandler; + private readonly Action? _informationHandler; + private readonly Action? _verboseHandler; /// /// Gets the contract version of this handler. @@ -31,10 +33,10 @@ public virtual int Version /// A callback for . /// A callback for . public OperationReportHandler( - [CanBeNull] Action errorHandler = null, - [CanBeNull] Action warningHandler = null, - [CanBeNull] Action informationHandler = null, - [CanBeNull] Action verboseHandler = null) + [CanBeNull] Action? errorHandler = null, + [CanBeNull] Action? warningHandler = null, + [CanBeNull] Action? informationHandler = null, + [CanBeNull] Action? verboseHandler = null) { _errorHandler = errorHandler; _warningHandler = warningHandler; diff --git a/src/EFCore.Design/Design/OperationResultHandler.cs b/src/EFCore.Design/Design/OperationResultHandler.cs index 66d06df5f79..416d10aaa06 100644 --- a/src/EFCore.Design/Design/OperationResultHandler.cs +++ b/src/EFCore.Design/Design/OperationResultHandler.cs @@ -3,6 +3,8 @@ using System; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Design { /// @@ -11,10 +13,10 @@ namespace Microsoft.EntityFrameworkCore.Design public class OperationResultHandler : MarshalByRefObject, IOperationResultHandler { private bool _hasResult; - private object _result; - private string _errorType; - private string _errorMessage; - private string _errorStackTrace; + private object? _result; + private string? _errorType; + private string? _errorMessage; + private string? _errorStackTrace; /// /// Gets the contract version of this handler. @@ -34,21 +36,21 @@ public virtual bool HasResult /// Gets the result. /// /// The result. - public virtual object Result + public virtual object? Result => _result; /// /// Gets the type of the exception if any. /// /// The exception type. - public virtual string ErrorType + public virtual string? ErrorType => _errorType; /// /// Gets the error message if any. /// /// The error message. - public virtual string ErrorMessage + public virtual string? ErrorMessage => _errorMessage; /// @@ -58,14 +60,14 @@ public virtual string ErrorMessage /// /// When an is received, the stack trace should not be shown by default. /// - public virtual string ErrorStackTrace + public virtual string? ErrorStackTrace => _errorStackTrace; /// /// Invoked when a result is available. /// /// The result. - public virtual void OnResult(object value) + public virtual void OnResult(object? value) { _hasResult = true; _result = value; diff --git a/src/dotnet-ef/Exe.cs b/src/dotnet-ef/Exe.cs index 1f48aa181e5..35e2b7d898f 100644 --- a/src/dotnet-ef/Exe.cs +++ b/src/dotnet-ef/Exe.cs @@ -12,7 +12,7 @@ internal static class Exe public static int Run( string executable, IReadOnlyList args, - string workingDirectory = null, + string? workingDirectory = null, bool interceptOutput = false) { var arguments = ToArguments(args); @@ -28,11 +28,11 @@ public static int Run( startInfo.WorkingDirectory = workingDirectory; } - var process = Process.Start(startInfo); + var process = Process.Start(startInfo)!; if (interceptOutput) { - string line; + string? line; while ((line = process.StandardOutput.ReadLine()) != null) { Reporter.WriteVerbose(line); diff --git a/src/dotnet-ef/Project.cs b/src/dotnet-ef/Project.cs index ab3cede7437..823613db31f 100644 --- a/src/dotnet-ef/Project.cs +++ b/src/dotnet-ef/Project.cs @@ -12,11 +12,11 @@ namespace Microsoft.EntityFrameworkCore.Tools internal class Project { private readonly string _file; - private readonly string _framework; - private readonly string _configuration; - private readonly string _runtime; + private readonly string? _framework; + private readonly string? _configuration; + private readonly string? _runtime; - public Project(string file, string framework, string configuration, string runtime) + public Project(string file, string? framework, string? configuration, string? runtime) { Debug.Assert(!string.IsNullOrEmpty(file), "file is null or empty."); @@ -29,29 +29,29 @@ public Project(string file, string framework, string configuration, string runti public string ProjectName { get; } - public string AssemblyName { get; set; } - public string Language { get; set; } - public string OutputPath { get; set; } - public string PlatformTarget { get; set; } - public string ProjectAssetsFile { get; set; } - public string ProjectDir { get; set; } - public string RootNamespace { get; set; } - public string RuntimeFrameworkVersion { get; set; } - public string TargetFileName { get; set; } - public string TargetFrameworkMoniker { get; set; } + public string? AssemblyName { get; set; } + public string? Language { get; set; } + public string? OutputPath { get; set; } + public string? PlatformTarget { get; set; } + public string? ProjectAssetsFile { get; set; } + public string? ProjectDir { get; set; } + public string? RootNamespace { get; set; } + public string? RuntimeFrameworkVersion { get; set; } + public string? TargetFileName { get; set; } + public string? TargetFrameworkMoniker { get; set; } public static Project FromFile( string file, - string buildExtensionsDir, - string framework = null, - string configuration = null, - string runtime = null) + string? buildExtensionsDir, + string? framework = null, + string? configuration = null, + string? runtime = null) { Debug.Assert(!string.IsNullOrEmpty(file), "file is null or empty."); if (buildExtensionsDir == null) { - buildExtensionsDir = Path.Combine(Path.GetDirectoryName(file), "obj"); + buildExtensionsDir = Path.Combine(Path.GetDirectoryName(file)!, "obj"); } Directory.CreateDirectory(buildExtensionsDir); @@ -60,7 +60,7 @@ public static Project FromFile( buildExtensionsDir, Path.GetFileName(file) + ".EntityFrameworkCore.targets"); using (var input = typeof(Resources).Assembly.GetManifestResourceStream( - "Microsoft.EntityFrameworkCore.Tools.Resources.EntityFrameworkCore.targets")) + "Microsoft.EntityFrameworkCore.Tools.Resources.EntityFrameworkCore.targets")!) using (var output = File.OpenWrite(efTargetsPath)) { // NB: Copy always in case it changes diff --git a/src/dotnet-ef/ProjectOptions.cs b/src/dotnet-ef/ProjectOptions.cs index 1f7ef975872..0b13600fda1 100644 --- a/src/dotnet-ef/ProjectOptions.cs +++ b/src/dotnet-ef/ProjectOptions.cs @@ -8,13 +8,13 @@ namespace Microsoft.EntityFrameworkCore.Tools { internal class ProjectOptions { - public CommandOption Project { get; private set; } - public CommandOption StartupProject { get; private set; } - public CommandOption Framework { get; private set; } - public CommandOption Configuration { get; private set; } - public CommandOption Runtime { get; private set; } - public CommandOption MSBuildProjectExtensionsPath { get; private set; } - public CommandOption NoBuild { get; private set; } + public CommandOption? Project { get; private set; } + public CommandOption? StartupProject { get; private set; } + public CommandOption? Framework { get; private set; } + public CommandOption? Configuration { get; private set; } + public CommandOption? Runtime { get; private set; } + public CommandOption? MSBuildProjectExtensionsPath { get; private set; } + public CommandOption? NoBuild { get; private set; } public void Configure(CommandLineApplication command) { diff --git a/src/dotnet-ef/RootCommand.cs b/src/dotnet-ef/RootCommand.cs index 7db5d7f42f9..68537434222 100644 --- a/src/dotnet-ef/RootCommand.cs +++ b/src/dotnet-ef/RootCommand.cs @@ -17,17 +17,17 @@ namespace Microsoft.EntityFrameworkCore.Tools { internal class RootCommand : CommandBase { - private CommandLineApplication _command; - private CommandOption _project; - private CommandOption _startupProject; - private CommandOption _framework; - private CommandOption _configuration; - private CommandOption _runtime; - private CommandOption _msbuildprojectextensionspath; - private CommandOption _noBuild; - private CommandOption _help; - private IList _args; - private IList _applicationArgs; + private CommandLineApplication? _command; + private CommandOption? _project; + private CommandOption? _startupProject; + private CommandOption? _framework; + private CommandOption? _configuration; + private CommandOption? _runtime; + private CommandOption? _msbuildprojectextensionspath; + private CommandOption? _noBuild; + private CommandOption? _help; + private IList? _args; + private IList? _applicationArgs; public override void Configure(CommandLineApplication command) { @@ -58,29 +58,29 @@ public override void Configure(CommandLineApplication command) protected override int Execute(string[] _) { - var commands = _args.TakeWhile(a => a[0] != '-').ToList(); - if (_help.HasValue() + var commands = _args!.TakeWhile(a => a[0] != '-').ToList(); + if (_help!.HasValue() || ShouldHelp(commands)) { return ShowHelp(_help.HasValue(), commands); } var (projectFile, startupProjectFile) = ResolveProjects( - _project.Value(), - _startupProject.Value()); + _project!.Value(), + _startupProject!.Value()); Reporter.WriteVerbose(Resources.UsingProject(projectFile)); Reporter.WriteVerbose(Resources.UsingStartupProject(startupProjectFile)); - var project = Project.FromFile(projectFile, _msbuildprojectextensionspath.Value()); + var project = Project.FromFile(projectFile, _msbuildprojectextensionspath!.Value()); var startupProject = Project.FromFile( startupProjectFile, _msbuildprojectextensionspath.Value(), - _framework.Value(), - _configuration.Value(), - _runtime.Value()); + _framework!.Value(), + _configuration!.Value(), + _runtime!.Value()); - if (!_noBuild.HasValue()) + if (!_noBuild!.HasValue()) { Reporter.WriteInformation(Resources.BuildStarted); startupProject.Build(); @@ -91,12 +91,12 @@ protected override int Execute(string[] _) var args = new List(); var toolsPath = Path.Combine( - Path.GetDirectoryName(typeof(Program).Assembly.Location), + Path.GetDirectoryName(typeof(Program).Assembly.Location)!, "tools"); - var targetDir = Path.GetFullPath(Path.Combine(startupProject.ProjectDir, startupProject.OutputPath)); - var targetPath = Path.Combine(targetDir, project.TargetFileName); - var startupTargetPath = Path.Combine(targetDir, startupProject.TargetFileName); + var targetDir = Path.GetFullPath(Path.Combine(startupProject.ProjectDir!, startupProject.OutputPath!)); + var targetPath = Path.Combine(targetDir, project.TargetFileName!); + var startupTargetPath = Path.Combine(targetDir, startupProject.TargetFileName!); var depsFile = Path.Combine( targetDir, startupProject.AssemblyName + ".deps.json"); @@ -105,7 +105,7 @@ protected override int Execute(string[] _) startupProject.AssemblyName + ".runtimeconfig.json"); var projectAssetsFile = startupProject.ProjectAssetsFile; - var targetFramework = new FrameworkName(startupProject.TargetFrameworkMoniker); + var targetFramework = new FrameworkName(startupProject.TargetFrameworkMoniker!); if (targetFramework.Identifier == ".NETFramework") { executable = Path.Combine( @@ -148,7 +148,7 @@ protected override int Execute(string[] _) args.Add("--runtimeconfig"); args.Add(runtimeConfig); } - else if (startupProject.RuntimeFrameworkVersion.Length != 0) + else if (startupProject.RuntimeFrameworkVersion!.Length != 0) { args.Add("--fx-version"); args.Add(startupProject.RuntimeFrameworkVersion); @@ -166,15 +166,15 @@ protected override int Execute(string[] _) Resources.UnsupportedFramework(startupProject.ProjectName, targetFramework.Identifier)); } - args.AddRange(_args); + args.AddRange(_args!); args.Add("--assembly"); args.Add(targetPath); args.Add("--startup-assembly"); args.Add(startupTargetPath); args.Add("--project-dir"); - args.Add(project.ProjectDir); + args.Add(project.ProjectDir!); args.Add("--language"); - args.Add(project.Language); + args.Add(project.Language!); args.Add("--working-dir"); args.Add(Directory.GetCurrentDirectory()); @@ -193,24 +193,24 @@ protected override int Execute(string[] _) args.Add("--prefix-output"); } - if (project.RootNamespace.Length != 0) + if (project.RootNamespace!.Length != 0) { args.Add("--root-namespace"); args.Add(project.RootNamespace); } - if (_applicationArgs.Any()) + if (_applicationArgs!.Any()) { args.Add("--"); - args.AddRange(_applicationArgs); + args.AddRange(_applicationArgs!); } return Exe.Run(executable, args, startupProject.ProjectDir); } private static (string, string) ResolveProjects( - string projectPath, - string startupProjectPath) + string? projectPath, + string? startupProjectPath) { var projects = ResolveProjects(projectPath); var startupProjects = ResolveProjects(startupProjectPath); @@ -264,7 +264,7 @@ private static (string, string) ResolveProjects( return (projects[0], startupProjects[0]); } - private static List ResolveProjects(string path) + private static List ResolveProjects(string? path) { if (path == null) { @@ -283,7 +283,7 @@ private static List ResolveProjects(string path) } private static string GetVersion() - => typeof(RootCommand).Assembly.GetCustomAttribute() + => typeof(RootCommand).Assembly.GetCustomAttribute()! .InformationalVersion; private static bool ShouldHelp(IReadOnlyList commands) @@ -295,7 +295,7 @@ private static bool ShouldHelp(IReadOnlyList commands) private int ShowHelp(bool help, IEnumerable commands) { - var app = new CommandLineApplication { Name = _command.Name }; + var app = new CommandLineApplication { Name = _command!.Name }; new EFCommand().Configure(app); diff --git a/src/dotnet-ef/dotnet-ef.csproj b/src/dotnet-ef/dotnet-ef.csproj index 789102c22a5..b64af669f97 100644 --- a/src/dotnet-ef/dotnet-ef.csproj +++ b/src/dotnet-ef/dotnet-ef.csproj @@ -27,6 +27,7 @@ dotnet ef database update --> false Major + enable diff --git a/src/ef/AnsiConsole.cs b/src/ef/AnsiConsole.cs index 550fb4bf130..849c07c0db1 100644 --- a/src/ef/AnsiConsole.cs +++ b/src/ef/AnsiConsole.cs @@ -9,7 +9,7 @@ internal static class AnsiConsole { public static readonly AnsiTextWriter _out = new(Console.Out); - public static void WriteLine(string text) + public static void WriteLine(string? text) => _out.WriteLine(text); } } diff --git a/src/ef/AnsiTextWriter.cs b/src/ef/AnsiTextWriter.cs index 737552a824e..3f1ab5362bd 100644 --- a/src/ef/AnsiTextWriter.cs +++ b/src/ef/AnsiTextWriter.cs @@ -4,6 +4,7 @@ using System; using System.Diagnostics; using System.IO; +using System.Linq; using System.Text.RegularExpressions; namespace Microsoft.EntityFrameworkCore.Tools @@ -14,23 +15,23 @@ internal class AnsiTextWriter public AnsiTextWriter(TextWriter writer) => _writer = writer; - public void WriteLine(string text) + public void WriteLine(string? text) { Interpret(text); _writer.Write(Environment.NewLine); } - private void Interpret(string value) + private void Interpret(string? value) { var matches = Regex.Matches(value, "\x1b\\[([0-9]+)?m"); var start = 0; - foreach (Match match in matches) + foreach (var match in matches.Cast()) { var length = match.Index - start; if (length != 0) { - _writer.Write(value.Substring(start, length)); + _writer.Write(value!.Substring(start, length)); } Apply(match.Groups[1].Value); @@ -38,9 +39,9 @@ private void Interpret(string value) start = match.Index + match.Length; } - if (start != value.Length) + if (start != value?.Length) { - _writer.Write(value.Substring(start)); + _writer.Write(value?.Substring(start)); } } diff --git a/src/ef/AppDomainOperationExecutor.cs b/src/ef/AppDomainOperationExecutor.cs index acf58cde203..69438de5ad9 100644 --- a/src/ef/AppDomainOperationExecutor.cs +++ b/src/ef/AppDomainOperationExecutor.cs @@ -20,11 +20,11 @@ internal class AppDomainOperationExecutor : OperationExecutorBase public AppDomainOperationExecutor( string assembly, - string startupAssembly, - string projectDir, - string dataDirectory, - string rootNamespace, - string language, + string? startupAssembly, + string? projectDir, + string? dataDirectory, + string? rootNamespace, + string? language, string[] remainingArguments) : base(assembly, startupAssembly, projectDir, rootNamespace, language, remainingArguments) { diff --git a/src/ef/CommandLineUtils/CommandArgument.cs b/src/ef/CommandLineUtils/CommandArgument.cs index fae1fb16620..b887ce73702 100644 --- a/src/ef/CommandLineUtils/CommandArgument.cs +++ b/src/ef/CommandLineUtils/CommandArgument.cs @@ -10,10 +10,10 @@ internal class CommandArgument { public CommandArgument() => Values = new List(); - public string Name { get; set; } - public string Description { get; set; } + public string? Name { get; set; } + public string? Description { get; set; } public List Values { get; } public bool MultipleValues { get; set; } - public string Value => Values.FirstOrDefault(); + public string? Value => Values.FirstOrDefault(); } } diff --git a/src/ef/CommandLineUtils/CommandLineApplication.cs b/src/ef/CommandLineUtils/CommandLineApplication.cs index 502b5c9766b..d820dd2d38c 100644 --- a/src/ef/CommandLineUtils/CommandLineApplication.cs +++ b/src/ef/CommandLineUtils/CommandLineApplication.cs @@ -38,26 +38,26 @@ public CommandLineApplication(bool throwOnUnexpectedArg = true) Invoke = (args) => 0; } - public CommandLineApplication Parent { get; set; } - public string Name { get; set; } - public string FullName { get; set; } - public string Syntax { get; set; } - public string Description { get; set; } + public CommandLineApplication? Parent { get; set; } + public string? Name { get; set; } + public string? FullName { get; set; } + public string? Syntax { get; set; } + public string? Description { get; set; } public List Options { get; } - public CommandOption OptionHelp { get; private set; } - public CommandOption OptionVersion { get; private set; } + public CommandOption? OptionHelp { get; private set; } + public CommandOption? OptionVersion { get; private set; } public List Arguments { get; } public List RemainingArguments { get; } public List ApplicationArguments { get; } public bool IsShowingInformation { get; protected set; } // Is showing help or version? - public Func Invoke { get; set; } - public Func LongVersionGetter { get; set; } - public Func ShortVersionGetter { get; set; } + public Func Invoke { get; set; } + public Func? LongVersionGetter { get; set; } + public Func? ShortVersionGetter { get; set; } public List Commands { get; } public bool HandleResponseFiles { get; set; } public bool AllowArgumentSeparator { get; set; } public bool HandleRemainingArguments { get; set; } - public string ArgumentSeparatorHelpText { get; set; } + public string? ArgumentSeparatorHelpText { get; set; } public CommandLineApplication Command(string name, bool throwOnUnexpectedArg = true) => Command(name, _ => { }, throwOnUnexpectedArg); @@ -72,10 +72,10 @@ public CommandLineApplication Command( return command; } - public CommandOption Option(string template, string description, CommandOptionType optionType) + public CommandOption Option(string template, string? description, CommandOptionType optionType) => Option(template, description, optionType, _ => { }); - public CommandOption Option(string template, string description, CommandOptionType optionType, Action configuration) + public CommandOption Option(string template, string? description, CommandOptionType optionType, Action configuration) { var option = new CommandOption(template, optionType) { Description = description }; Options.Add(option); @@ -164,7 +164,7 @@ private ParseOptionResult ParseOption( CommandLineApplication command, string[] args, ref int index, - out CommandOption option) + out CommandOption? option) { option = null; var result = ParseOptionResult.Succeeded; @@ -253,7 +253,7 @@ private ParseOptionResult ParseOption( return result; } - private static CommandLineApplication ParseSubCommand(string arg, CommandLineApplication command) + private static CommandLineApplication? ParseSubCommand(string arg, CommandLineApplication command) { foreach (var subcommand in command.Commands) { @@ -279,7 +279,7 @@ public CommandOption HelpOption(string template) public CommandOption VersionOption( string template, string shortFormVersion, - string longFormVersion = null) + string? longFormVersion = null) { if (longFormVersion == null) { @@ -293,7 +293,7 @@ public CommandOption VersionOption( public CommandOption VersionOption( string template, Func shortFormVersionGetter, - Func longFormVersionGetter = null) + Func? longFormVersionGetter = null) { // Version option is special because we stop parsing once we see it // So we store it separately for further use @@ -314,7 +314,7 @@ public void ShowHint() } // Show full help - public void ShowHelp(string commandName = null) + public void ShowHelp(string? commandName = null) { var headerBuilder = new StringBuilder("Usage:"); var usagePrefixLength = headerBuilder.Length; @@ -333,7 +333,7 @@ public void ShowHelp(string commandName = null) } } - CommandLineApplication target; + CommandLineApplication? target; if (commandName == null || string.Equals(Name, commandName, StringComparison.OrdinalIgnoreCase)) @@ -389,7 +389,7 @@ public void ShowHelp(string commandName = null) { argumentsBuilder.AppendFormat( outputFormat, - arg.Name.PadRight(maxArgLen + 2), + arg.Name!.PadRight(maxArgLen + 2), arg.Description); argumentsBuilder.AppendLine(); } @@ -473,10 +473,10 @@ public void ShowVersion() } Console.WriteLine(FullName); - Console.WriteLine(LongVersionGetter()); + Console.WriteLine(LongVersionGetter!()); } - public string GetFullNameAndVersion() + public string? GetFullNameAndVersion() => ShortVersionGetter == null ? FullName : string.Format("{0} {1}", FullName, ShortVersionGetter()); public void ShowRootCommandFullNameAndVersion() @@ -507,7 +507,7 @@ private static int MaxCommandLength(IEnumerable commands var maxLen = 0; foreach (var cmd in commands) { - maxLen = cmd.Name.Length > maxLen ? cmd.Name.Length : maxLen; + maxLen = cmd.Name!.Length > maxLen ? cmd.Name.Length : maxLen; } return maxLen; @@ -518,7 +518,7 @@ private static int MaxArgumentLength(IEnumerable arguments) var maxLen = 0; foreach (var arg in arguments) { - maxLen = arg.Name.Length > maxLen ? arg.Name.Length : maxLen; + maxLen = arg.Name!.Length > maxLen ? arg.Name.Length : maxLen; } return maxLen; @@ -568,7 +568,7 @@ private IEnumerable ExpandResponseFiles(IEnumerable args) } } - private IEnumerable ParseResponseFile(string fileName) + private IEnumerable? ParseResponseFile(string fileName) { if (!HandleResponseFiles) { diff --git a/src/ef/CommandLineUtils/CommandLineApplicationExtensions.cs b/src/ef/CommandLineUtils/CommandLineApplicationExtensions.cs index 7a1ab6040cb..dec20298c62 100644 --- a/src/ef/CommandLineUtils/CommandLineApplicationExtensions.cs +++ b/src/ef/CommandLineUtils/CommandLineApplicationExtensions.cs @@ -7,7 +7,7 @@ namespace Microsoft.DotNet.Cli.CommandLine { internal static class CommandLineApplicationExtensions { - public static CommandOption Option(this CommandLineApplication command, string template, string description) + public static CommandOption Option(this CommandLineApplication command, string template, string? description) => command.Option( template, description, diff --git a/src/ef/CommandLineUtils/CommandOption.cs b/src/ef/CommandLineUtils/CommandOption.cs index f85a9da1d14..11fa1a35bb6 100644 --- a/src/ef/CommandLineUtils/CommandOption.cs +++ b/src/ef/CommandLineUtils/CommandOption.cs @@ -13,7 +13,7 @@ public CommandOption(string template, CommandOptionType optionType) { Template = template; OptionType = optionType; - Values = new List(); + Values = new List(); foreach (var part in Template.Split(new[] { ' ', '|' }, StringSplitOptions.RemoveEmptyEntries)) { @@ -62,16 +62,16 @@ public CommandOption(string template, CommandOptionType optionType) } public string Template { get; set; } - public string ShortName { get; set; } - public string LongName { get; set; } - public string SymbolName { get; set; } - public string ValueName { get; set; } - public string Description { get; set; } - public List Values { get; } + public string? ShortName { get; set; } + public string? LongName { get; set; } + public string? SymbolName { get; set; } + public string? ValueName { get; set; } + public string? Description { get; set; } + public List Values { get; } public bool? BoolValue { get; private set; } public CommandOptionType OptionType { get; } - public bool TryParse(string value) + public bool TryParse(string? value) { switch (OptionType) { @@ -126,7 +126,7 @@ public bool TryParse(string value) public bool HasValue() => Values.Count > 0; - public string Value() => HasValue() ? Values[0] : null; + public string? Value() => HasValue() ? Values[0] : null; private static bool IsEnglishLetter(char c) => (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } diff --git a/src/ef/Commands/ContextCommandBase.cs b/src/ef/Commands/ContextCommandBase.cs index 8b4232815b2..e0205897122 100644 --- a/src/ef/Commands/ContextCommandBase.cs +++ b/src/ef/Commands/ContextCommandBase.cs @@ -8,7 +8,7 @@ namespace Microsoft.EntityFrameworkCore.Tools.Commands { internal class ContextCommandBase : ProjectCommandBase { - protected CommandOption Context { get; private set; } + protected CommandOption? Context { get; private set; } public override void Configure(CommandLineApplication command) { diff --git a/src/ef/Commands/DatabaseDropCommand.Configure.cs b/src/ef/Commands/DatabaseDropCommand.Configure.cs index 65df319a1c3..57791972f02 100644 --- a/src/ef/Commands/DatabaseDropCommand.Configure.cs +++ b/src/ef/Commands/DatabaseDropCommand.Configure.cs @@ -8,8 +8,8 @@ namespace Microsoft.EntityFrameworkCore.Tools.Commands { internal partial class DatabaseDropCommand : ContextCommandBase { - private CommandOption _force; - private CommandOption _dryRun; + private CommandOption? _force; + private CommandOption? _dryRun; public override void Configure(CommandLineApplication command) { diff --git a/src/ef/Commands/DatabaseDropCommand.cs b/src/ef/Commands/DatabaseDropCommand.cs index f5405598eb0..a4466c26e29 100644 --- a/src/ef/Commands/DatabaseDropCommand.cs +++ b/src/ef/Commands/DatabaseDropCommand.cs @@ -13,32 +13,32 @@ protected override int Execute(string[] args) { using var executor = CreateExecutor(args); - void LogDropCommand(Func resource) + void LogDropCommand(Func resource) { - var result = executor.GetContextInfo(Context.Value()); + var result = executor.GetContextInfo(Context!.Value()); var databaseName = result["DatabaseName"] as string; var dataSource = result["DataSource"] as string; Reporter.WriteInformation(resource(databaseName, dataSource)); } - if (_dryRun.HasValue()) + if (_dryRun!.HasValue()) { LogDropCommand(Resources.DatabaseDropDryRun); return 0; } - if (!_force.HasValue()) + if (!_force!.HasValue()) { LogDropCommand(Resources.DatabaseDropPrompt); - var response = Console.ReadLine().Trim().ToUpperInvariant(); + var response = Console.ReadLine()!.Trim().ToUpperInvariant(); if (response != "Y") { return 1; } } - executor.DropDatabase(Context.Value()); + executor.DropDatabase(Context!.Value()); return base.Execute(args); } diff --git a/src/ef/Commands/DatabaseUpdateCommand.Configure.cs b/src/ef/Commands/DatabaseUpdateCommand.Configure.cs index 3bfd3a8d0ee..ab6363eb322 100644 --- a/src/ef/Commands/DatabaseUpdateCommand.Configure.cs +++ b/src/ef/Commands/DatabaseUpdateCommand.Configure.cs @@ -8,8 +8,8 @@ namespace Microsoft.EntityFrameworkCore.Tools.Commands { internal partial class DatabaseUpdateCommand : ContextCommandBase { - private CommandArgument _migration; - private CommandOption _connection; + private CommandArgument? _migration; + private CommandOption? _connection; public override void Configure(CommandLineApplication command) { diff --git a/src/ef/Commands/DatabaseUpdateCommand.cs b/src/ef/Commands/DatabaseUpdateCommand.cs index dec25755b6b..d2eedc24fa6 100644 --- a/src/ef/Commands/DatabaseUpdateCommand.cs +++ b/src/ef/Commands/DatabaseUpdateCommand.cs @@ -10,7 +10,7 @@ protected override int Execute(string[] args) { using var executor = CreateExecutor(args); - executor.UpdateDatabase(_migration.Value, _connection.Value(), Context.Value()); + executor.UpdateDatabase(_migration!.Value, _connection!.Value(), Context!.Value()); return base.Execute(args); } diff --git a/src/ef/Commands/DbContextInfoCommand.Configure.cs b/src/ef/Commands/DbContextInfoCommand.Configure.cs index 7426be15445..e7a67745430 100644 --- a/src/ef/Commands/DbContextInfoCommand.Configure.cs +++ b/src/ef/Commands/DbContextInfoCommand.Configure.cs @@ -8,7 +8,7 @@ namespace Microsoft.EntityFrameworkCore.Tools.Commands { internal partial class DbContextInfoCommand : ContextCommandBase { - private CommandOption _json; + private CommandOption? _json; public override void Configure(CommandLineApplication command) { diff --git a/src/ef/Commands/DbContextInfoCommand.cs b/src/ef/Commands/DbContextInfoCommand.cs index d7a2615eb78..d3575f6cd01 100644 --- a/src/ef/Commands/DbContextInfoCommand.cs +++ b/src/ef/Commands/DbContextInfoCommand.cs @@ -12,9 +12,9 @@ internal partial class DbContextInfoCommand protected override int Execute(string[] args) { using var executor = CreateExecutor(args); - var result = executor.GetContextInfo(Context.Value()); + var result = executor.GetContextInfo(Context!.Value()); - if (_json.HasValue()) + if (_json!.HasValue()) { ReportJsonResult(result); } diff --git a/src/ef/Commands/DbContextListCommand.Configure.cs b/src/ef/Commands/DbContextListCommand.Configure.cs index 26ab2d4d806..ba9e972fbc3 100644 --- a/src/ef/Commands/DbContextListCommand.Configure.cs +++ b/src/ef/Commands/DbContextListCommand.Configure.cs @@ -8,7 +8,7 @@ namespace Microsoft.EntityFrameworkCore.Tools.Commands { internal partial class DbContextListCommand : ProjectCommandBase { - private CommandOption _json; + private CommandOption? _json; public override void Configure(CommandLineApplication command) { diff --git a/src/ef/Commands/DbContextListCommand.cs b/src/ef/Commands/DbContextListCommand.cs index 5e4ba01e8a5..76e51040eeb 100644 --- a/src/ef/Commands/DbContextListCommand.cs +++ b/src/ef/Commands/DbContextListCommand.cs @@ -16,7 +16,7 @@ protected override int Execute(string[] args) using var executor = CreateExecutor(args); var types = executor.GetContextTypes().ToList(); - if (_json.HasValue()) + if (_json!.HasValue()) { ReportJsonResults(types); } @@ -66,7 +66,7 @@ private static void ReportResults(IEnumerable contextTypes) var any = false; foreach (var contextType in contextTypes) { - Reporter.WriteData(contextType["FullName"] as string); + Reporter.WriteData((contextType["FullName"] as string)!); any = true; } diff --git a/src/ef/Commands/DbContextScaffoldCommand.Configure.cs b/src/ef/Commands/DbContextScaffoldCommand.Configure.cs index 51979859c76..e63cfd8da1a 100644 --- a/src/ef/Commands/DbContextScaffoldCommand.Configure.cs +++ b/src/ef/Commands/DbContextScaffoldCommand.Configure.cs @@ -8,21 +8,21 @@ namespace Microsoft.EntityFrameworkCore.Tools.Commands { internal partial class DbContextScaffoldCommand : ProjectCommandBase { - private CommandArgument _connection; - private CommandArgument _provider; - private CommandOption _dataAnnotations; - private CommandOption _context; - private CommandOption _contextDir; - private CommandOption _force; - private CommandOption _outputDir; - private CommandOption _schemas; - private CommandOption _tables; - private CommandOption _useDatabaseNames; - private CommandOption _json; - private CommandOption _namespace; - private CommandOption _contextNamespace; - private CommandOption _suppressOnConfiguring; - private CommandOption _noPluralize; + private CommandArgument? _connection; + private CommandArgument? _provider; + private CommandOption? _dataAnnotations; + private CommandOption? _context; + private CommandOption? _contextDir; + private CommandOption? _force; + private CommandOption? _outputDir; + private CommandOption? _schemas; + private CommandOption? _tables; + private CommandOption? _useDatabaseNames; + private CommandOption? _json; + private CommandOption? _namespace; + private CommandOption? _contextNamespace; + private CommandOption? _suppressOnConfiguring; + private CommandOption? _noPluralize; public override void Configure(CommandLineApplication command) { diff --git a/src/ef/Commands/DbContextScaffoldCommand.cs b/src/ef/Commands/DbContextScaffoldCommand.cs index 67309c3fc57..30abedf0ef0 100644 --- a/src/ef/Commands/DbContextScaffoldCommand.cs +++ b/src/ef/Commands/DbContextScaffoldCommand.cs @@ -14,12 +14,12 @@ protected override void Validate() { base.Validate(); - if (string.IsNullOrEmpty(_connection.Value)) + if (string.IsNullOrEmpty(_connection!.Value)) { throw new CommandException(Resources.MissingArgument(_connection.Name)); } - if (string.IsNullOrEmpty(_provider.Value)) + if (string.IsNullOrEmpty(_provider!.Value)) { throw new CommandException(Resources.MissingArgument(_provider.Name)); } @@ -29,21 +29,21 @@ protected override int Execute(string[] args) { using var executor = CreateExecutor(args); var result = executor.ScaffoldContext( - _provider.Value, - _connection.Value, - _outputDir.Value(), - _contextDir.Value(), - _context.Value(), - _schemas.Values, - _tables.Values, - _dataAnnotations.HasValue(), - _force.HasValue(), - _useDatabaseNames.HasValue(), - _namespace.Value(), - _contextNamespace.Value(), - _suppressOnConfiguring.HasValue(), - _noPluralize.HasValue()); - if (_json.HasValue()) + _provider!.Value!, + _connection!.Value!, + _outputDir!.Value(), + _contextDir!.Value(), + _context!.Value(), + _schemas!.Values!, + _tables!.Values!, + _dataAnnotations!.HasValue(), + _force!.HasValue(), + _useDatabaseNames!.HasValue(), + _namespace!.Value(), + _contextNamespace!.Value(), + _suppressOnConfiguring!.HasValue(), + _noPluralize!.HasValue()); + if (_json!.HasValue()) { ReportJsonResults(result); } @@ -57,7 +57,7 @@ private static void ReportJsonResults(IDictionary result) Reporter.WriteData(" \"contextFile\": " + Json.Literal(result["ContextFile"] as string) + ","); Reporter.WriteData(" \"entityTypeFiles\": ["); - var files = (IReadOnlyList)result["EntityTypeFiles"]; + var files = (IReadOnlyList)result["EntityTypeFiles"]!; for (var i = 0; i < files.Count; i++) { var line = " " + Json.Literal(files[i]); diff --git a/src/ef/Commands/DbContextScriptCommand.Configure.cs b/src/ef/Commands/DbContextScriptCommand.Configure.cs index b72239ea77d..f2043614df8 100644 --- a/src/ef/Commands/DbContextScriptCommand.Configure.cs +++ b/src/ef/Commands/DbContextScriptCommand.Configure.cs @@ -8,7 +8,7 @@ namespace Microsoft.EntityFrameworkCore.Tools.Commands { internal partial class DbContextScriptCommand : ContextCommandBase { - private CommandOption _output; + private CommandOption? _output; public override void Configure(CommandLineApplication command) { diff --git a/src/ef/Commands/DbContextScriptCommand.cs b/src/ef/Commands/DbContextScriptCommand.cs index bcde223ba67..6271151a20d 100644 --- a/src/ef/Commands/DbContextScriptCommand.cs +++ b/src/ef/Commands/DbContextScriptCommand.cs @@ -13,18 +13,18 @@ internal partial class DbContextScriptCommand protected override int Execute(string[] args) { using var executor = CreateExecutor(args); - var sql = executor.ScriptDbContext(Context.Value()); + var sql = executor.ScriptDbContext(Context!.Value()); - if (!_output.HasValue()) + if (!_output!.HasValue()) { Reporter.WriteData(sql); } else { - var output = _output.Value(); - if (WorkingDir.HasValue()) + var output = _output.Value()!; + if (WorkingDir!.HasValue()) { - output = Path.Combine(WorkingDir.Value(), output); + output = Path.Combine(WorkingDir.Value()!, output); } var directory = Path.GetDirectoryName(output); diff --git a/src/ef/Commands/HelpCommandBase.cs b/src/ef/Commands/HelpCommandBase.cs index 6a05df3eedf..5715136db7c 100644 --- a/src/ef/Commands/HelpCommandBase.cs +++ b/src/ef/Commands/HelpCommandBase.cs @@ -7,7 +7,7 @@ namespace Microsoft.EntityFrameworkCore.Tools.Commands { internal class HelpCommandBase : EFCommandBase { - private CommandLineApplication _command; + private CommandLineApplication? _command; public override void Configure(CommandLineApplication command) { @@ -18,7 +18,7 @@ public override void Configure(CommandLineApplication command) protected override int Execute(string[] args) { - _command.ShowHelp(); + _command!.ShowHelp(); return base.Execute(args); } diff --git a/src/ef/Commands/MigrationsAddCommand.Configure.cs b/src/ef/Commands/MigrationsAddCommand.Configure.cs index d223a4b9d5b..66dff0932b5 100644 --- a/src/ef/Commands/MigrationsAddCommand.Configure.cs +++ b/src/ef/Commands/MigrationsAddCommand.Configure.cs @@ -8,10 +8,10 @@ namespace Microsoft.EntityFrameworkCore.Tools.Commands { internal partial class MigrationsAddCommand : ContextCommandBase { - private CommandArgument _name; - private CommandOption _outputDir; - private CommandOption _json; - private CommandOption _namespace; + private CommandArgument? _name; + private CommandOption? _outputDir; + private CommandOption? _json; + private CommandOption? _namespace; public override void Configure(CommandLineApplication command) { diff --git a/src/ef/Commands/MigrationsAddCommand.cs b/src/ef/Commands/MigrationsAddCommand.cs index 5ad0fc99bf9..a04afbeef88 100644 --- a/src/ef/Commands/MigrationsAddCommand.cs +++ b/src/ef/Commands/MigrationsAddCommand.cs @@ -13,7 +13,7 @@ protected override void Validate() { base.Validate(); - if (string.IsNullOrEmpty(_name.Value)) + if (string.IsNullOrEmpty(_name!.Value)) { throw new CommandException(Resources.MissingArgument(_name.Name)); } @@ -22,9 +22,9 @@ protected override void Validate() protected override int Execute(string[] args) { using var executor = CreateExecutor(args); - var files = executor.AddMigration(_name.Value, _outputDir.Value(), Context.Value(), _namespace.Value()); + var files = executor.AddMigration(_name!.Value!, _outputDir!.Value(), Context!.Value(), _namespace!.Value()); - if (_json.HasValue()) + if (_json!.HasValue()) { ReportJson(files); } diff --git a/src/ef/Commands/MigrationsListCommand.Configure.cs b/src/ef/Commands/MigrationsListCommand.Configure.cs index cf04db2ffb1..aa8d7bcdf64 100644 --- a/src/ef/Commands/MigrationsListCommand.Configure.cs +++ b/src/ef/Commands/MigrationsListCommand.Configure.cs @@ -8,9 +8,9 @@ namespace Microsoft.EntityFrameworkCore.Tools.Commands { internal partial class MigrationsListCommand : ContextCommandBase { - private CommandOption _connection; - private CommandOption _noConnect; - private CommandOption _json; + private CommandOption? _connection; + private CommandOption? _noConnect; + private CommandOption? _json; public override void Configure(CommandLineApplication command) { diff --git a/src/ef/Commands/MigrationsListCommand.cs b/src/ef/Commands/MigrationsListCommand.cs index c37fd196015..983df6745f2 100644 --- a/src/ef/Commands/MigrationsListCommand.cs +++ b/src/ef/Commands/MigrationsListCommand.cs @@ -14,9 +14,9 @@ internal partial class MigrationsListCommand protected override int Execute(string[] args) { using var executor = CreateExecutor(args); - var migrations = executor.GetMigrations(Context.Value(), _connection.Value(), _noConnect.HasValue()).ToList(); + var migrations = executor.GetMigrations(Context!.Value(), _connection!.Value(), _noConnect!.HasValue()).ToList(); - if (_json.HasValue()) + if (_json!.HasValue()) { ReportJsonResults(migrations); } diff --git a/src/ef/Commands/MigrationsRemoveCommand.Configure.cs b/src/ef/Commands/MigrationsRemoveCommand.Configure.cs index ff6c223a23a..bc9042b8bda 100644 --- a/src/ef/Commands/MigrationsRemoveCommand.Configure.cs +++ b/src/ef/Commands/MigrationsRemoveCommand.Configure.cs @@ -8,8 +8,8 @@ namespace Microsoft.EntityFrameworkCore.Tools.Commands { internal partial class MigrationsRemoveCommand : ContextCommandBase { - private CommandOption _force; - private CommandOption _json; + private CommandOption? _force; + private CommandOption? _json; public override void Configure(CommandLineApplication command) { diff --git a/src/ef/Commands/MigrationsRemoveCommand.cs b/src/ef/Commands/MigrationsRemoveCommand.cs index fd9e762af17..d0087cd2e7e 100644 --- a/src/ef/Commands/MigrationsRemoveCommand.cs +++ b/src/ef/Commands/MigrationsRemoveCommand.cs @@ -11,9 +11,9 @@ internal partial class MigrationsRemoveCommand protected override int Execute(string[] args) { using var executor = CreateExecutor(args); - var result = executor.RemoveMigration(Context.Value(), _force.HasValue()); + var result = executor.RemoveMigration(Context!.Value(), _force!.HasValue()); - if (_json.HasValue()) + if (_json!.HasValue()) { ReportJsonResults(result); } diff --git a/src/ef/Commands/MigrationsScriptCommand.Configure.cs b/src/ef/Commands/MigrationsScriptCommand.Configure.cs index 9ec2217afa9..09c21b143dc 100644 --- a/src/ef/Commands/MigrationsScriptCommand.Configure.cs +++ b/src/ef/Commands/MigrationsScriptCommand.Configure.cs @@ -8,11 +8,11 @@ namespace Microsoft.EntityFrameworkCore.Tools.Commands { internal partial class MigrationsScriptCommand : ContextCommandBase { - private CommandArgument _from; - private CommandArgument _to; - private CommandOption _output; - private CommandOption _idempotent; - private CommandOption _noTransactions; + private CommandArgument? _from; + private CommandArgument? _to; + private CommandOption? _output; + private CommandOption? _idempotent; + private CommandOption? _noTransactions; public override void Configure(CommandLineApplication command) { diff --git a/src/ef/Commands/MigrationsScriptCommand.cs b/src/ef/Commands/MigrationsScriptCommand.cs index 0d7196fec7b..6281a28bbdb 100644 --- a/src/ef/Commands/MigrationsScriptCommand.cs +++ b/src/ef/Commands/MigrationsScriptCommand.cs @@ -15,22 +15,22 @@ protected override int Execute(string[] args) using var executor = CreateExecutor(args); var sql = executor.ScriptMigration( - _from.Value, - _to.Value, - _idempotent.HasValue(), - _noTransactions.HasValue(), - Context.Value()); + _from!.Value, + _to!.Value, + _idempotent!.HasValue(), + _noTransactions!.HasValue(), + Context!.Value()); - if (!_output.HasValue()) + if (!_output!.HasValue()) { Reporter.WriteData(sql); } else { - var output = _output.Value(); - if (WorkingDir.HasValue()) + var output = _output.Value()!; + if (WorkingDir!.HasValue()) { - output = Path.Combine(WorkingDir.Value(), output); + output = Path.Combine(WorkingDir.Value()!, output); } var directory = Path.GetDirectoryName(output); diff --git a/src/ef/Commands/ProjectCommandBase.cs b/src/ef/Commands/ProjectCommandBase.cs index c2042ea2ccd..3f3d965cecf 100644 --- a/src/ef/Commands/ProjectCommandBase.cs +++ b/src/ef/Commands/ProjectCommandBase.cs @@ -1,13 +1,13 @@ // 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.Reflection; using Microsoft.DotNet.Cli.CommandLine; using Microsoft.EntityFrameworkCore.Tools.Properties; #if NET461 +using System; using System.Configuration; #endif @@ -15,14 +15,14 @@ namespace Microsoft.EntityFrameworkCore.Tools.Commands { internal abstract class ProjectCommandBase : EFCommandBase { - private CommandOption _assembly; - private CommandOption _startupAssembly; - private CommandOption _dataDir; - private CommandOption _projectDir; - private CommandOption _rootNamespace; - private CommandOption _language; + private CommandOption? _assembly; + private CommandOption? _startupAssembly; + private CommandOption? _dataDir; + private CommandOption? _projectDir; + private CommandOption? _rootNamespace; + private CommandOption? _language; - protected CommandOption WorkingDir { get; private set; } + protected CommandOption? WorkingDir { get; private set; } public override void Configure(CommandLineApplication command) { @@ -43,7 +43,7 @@ protected override void Validate() { base.Validate(); - if (!_assembly.HasValue()) + if (!_assembly!.HasValue()) { throw new CommandException(Resources.MissingOption(_assembly.LongName)); } @@ -57,17 +57,17 @@ protected IOperationExecutor CreateExecutor(string[] remainingArguments) try { return new AppDomainOperationExecutor( - _assembly.Value(), - _startupAssembly.Value(), - _projectDir.Value(), - _dataDir.Value(), - _rootNamespace.Value(), - _language.Value(), + _assembly!.Value()!, + _startupAssembly!.Value(), + _projectDir!.Value(), + _dataDir!.Value(), + _rootNamespace!.Value(), + _language!.Value(), remainingArguments); } catch (MissingMethodException) // NB: Thrown with EF Core 3.1 { - var configurationFile = (_startupAssembly.Value() ?? _assembly.Value()) + ".config"; + var configurationFile = (_startupAssembly!.Value() ?? _assembly!.Value()!) + ".config"; if (File.Exists(configurationFile)) { AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", configurationFile); @@ -93,21 +93,22 @@ protected IOperationExecutor CreateExecutor(string[] remainingArguments) #error target frameworks need to be updated. #endif return new ReflectionOperationExecutor( - _assembly.Value(), - _startupAssembly.Value(), - _projectDir.Value(), - _dataDir.Value(), - _rootNamespace.Value(), - _language.Value(), + _assembly!.Value()!, + _startupAssembly!.Value(), + _projectDir!.Value(), + _dataDir!.Value(), + _rootNamespace!.Value(), + _language!.Value(), remainingArguments); } catch (FileNotFoundException ex) - when (new AssemblyName(ex.FileName).Name == OperationExecutorBase.DesignAssemblyName) + when (ex.FileName != null + && new AssemblyName(ex.FileName).Name == OperationExecutorBase.DesignAssemblyName) { throw new CommandException( Resources.DesignNotFound( Path.GetFileNameWithoutExtension( - _startupAssembly.HasValue() ? _startupAssembly.Value() : _assembly.Value())), + _startupAssembly!.HasValue() ? _startupAssembly.Value() : _assembly!.Value())), ex); } } diff --git a/src/ef/Commands/RootCommand.cs b/src/ef/Commands/RootCommand.cs index 8a78cefc037..aafaaf09be7 100644 --- a/src/ef/Commands/RootCommand.cs +++ b/src/ef/Commands/RootCommand.cs @@ -31,19 +31,19 @@ protected override int Execute(string[] args) string.Join( Environment.NewLine, string.Empty, - Reporter.Colorize(@" _/\__ ", s => s.Insert(21, Bold + Gray)), - Reporter.Colorize(@" ---==/ \\ ", s => s.Insert(20, Bold + Gray)), - Reporter.Colorize(@" ___ ___ |. \|\ ", s => s.Insert(26, Bold).Insert(21, Dark).Insert(20, Bold + Gray).Insert(9, Dark + Magenta)), - Reporter.Colorize(@" | __|| __| | ) \\\ ", s => s.Insert(20, Bold + Gray).Insert(8, Dark + Magenta)), - Reporter.Colorize(@" | _| | _| \_/ | //|\\ ", s => s.Insert(20, Bold + Gray).Insert(8, Dark + Magenta)), - Reporter.Colorize(@" |___||_| / \\\/\\", s => s.Insert(33, Reset).Insert(23, Bold + Gray).Insert(8, Dark + Magenta)), + Reporter.Colorize(@" _/\__ ", s => s!.Insert(21, Bold + Gray)), + Reporter.Colorize(@" ---==/ \\ ", s => s!.Insert(20, Bold + Gray)), + Reporter.Colorize(@" ___ ___ |. \|\ ", s => s!.Insert(26, Bold).Insert(21, Dark).Insert(20, Bold + Gray).Insert(9, Dark + Magenta)), + Reporter.Colorize(@" | __|| __| | ) \\\ ", s => s!.Insert(20, Bold + Gray).Insert(8, Dark + Magenta)), + Reporter.Colorize(@" | _| | _| \_/ | //|\\ ", s => s!.Insert(20, Bold + Gray).Insert(8, Dark + Magenta)), + Reporter.Colorize(@" |___||_| / \\\/\\", s => s!.Insert(33, Reset).Insert(23, Bold + Gray).Insert(8, Dark + Magenta)), string.Empty)); return base.Execute(args); } private static string GetVersion() - => typeof(RootCommand).Assembly.GetCustomAttribute() + => typeof(RootCommand).Assembly.GetCustomAttribute()! .InformationalVersion; } } diff --git a/src/ef/IOperationExecutor.cs b/src/ef/IOperationExecutor.cs index 03d2fc8fff9..0715d0a3108 100644 --- a/src/ef/IOperationExecutor.cs +++ b/src/ef/IOperationExecutor.cs @@ -9,32 +9,32 @@ namespace Microsoft.EntityFrameworkCore.Tools { internal interface IOperationExecutor : IDisposable { - IDictionary AddMigration(string name, string outputDir, string contextType, string @namespace); - IDictionary RemoveMigration(string contextType, bool force); - IEnumerable GetMigrations(string contextType, string connectionString, bool noConnect); - void DropDatabase(string contextType); - IDictionary GetContextInfo(string name); - void UpdateDatabase(string migration, string connectionString, string contextType); + IDictionary AddMigration(string name, string? outputDir, string? contextType, string? @namespace); + IDictionary RemoveMigration(string? contextType, bool force); + IEnumerable GetMigrations(string? contextType, string? connectionString, bool noConnect); + void DropDatabase(string? contextType); + IDictionary GetContextInfo(string? name); + void UpdateDatabase(string? migration, string? connectionString, string? contextType); IEnumerable GetContextTypes(); IDictionary ScaffoldContext( string provider, string connectionString, - string outputDir, - string outputDbContextDir, - string dbContextClassName, + string? outputDir, + string? outputDbContextDir, + string? dbContextClassName, IEnumerable schemaFilters, IEnumerable tableFilters, bool useDataAnnotations, bool overwriteFiles, bool useDatabaseNames, - string entityNamespace, - string dbContextNamespace, + string? entityNamespace, + string? dbContextNamespace, bool suppressOnConfiguring, bool noPluralize); - string ScriptMigration(string fromMigration, string toMigration, bool idempotent, bool noTransactions, string contextType); + string ScriptMigration(string? fromMigration, string? toMigration, bool idempotent, bool noTransactions, string? contextType); - string ScriptDbContext(string contextType); + string ScriptDbContext(string? contextType); } } diff --git a/src/ef/Json.cs b/src/ef/Json.cs index 6b8c5e4e658..a603fac93cd 100644 --- a/src/ef/Json.cs +++ b/src/ef/Json.cs @@ -11,7 +11,7 @@ internal static class Json public static CommandOption ConfigureOption(CommandLineApplication command) => command.Option("--json", Resources.JsonDescription); - public static string Literal(string text) + public static string Literal(string? text) => text != null ? "\"" + text.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\"" : "null"; diff --git a/src/ef/NotNullIfNotNullAttribute.cs b/src/ef/NotNullIfNotNullAttribute.cs new file mode 100644 index 00000000000..f065e2462e1 --- /dev/null +++ b/src/ef/NotNullIfNotNullAttribute.cs @@ -0,0 +1,18 @@ +// 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. + +#if !NET + +namespace System.Diagnostics.CodeAnalysis +{ + [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] + internal sealed class NotNullIfNotNullAttribute : Attribute + { + public NotNullIfNotNullAttribute(string parameterName) + => ParameterName = parameterName; + + public string ParameterName { get; } + } +} + +#endif diff --git a/src/ef/OperationExecutorBase.cs b/src/ef/OperationExecutorBase.cs index bc9bba355d3..3ab838d14ba 100644 --- a/src/ef/OperationExecutorBase.cs +++ b/src/ef/OperationExecutorBase.cs @@ -22,15 +22,15 @@ internal abstract class OperationExecutorBase : IOperationExecutor protected string StartupAssemblyFileName { get; set; } protected string ProjectDirectory { get; } protected string RootNamespace { get; } - protected string Language { get; } + protected string? Language { get; } protected string[] RemainingArguments { get; } protected OperationExecutorBase( string assembly, - string startupAssembly, - string projectDir, - string rootNamespace, - string language, + string? startupAssembly, + string? projectDir, + string? rootNamespace, + string? language, string[] remainingArguments) { AssemblyFileName = Path.GetFileNameWithoutExtension(assembly); @@ -39,7 +39,7 @@ protected OperationExecutorBase( : Path.GetFileNameWithoutExtension(startupAssembly); AppBasePath = Path.GetFullPath( - Path.Combine(Directory.GetCurrentDirectory(), Path.GetDirectoryName(startupAssembly ?? assembly))); + Path.Combine(Directory.GetCurrentDirectory(), Path.GetDirectoryName(startupAssembly ?? assembly)!)); RootNamespace = rootNamespace ?? AssemblyFileName; ProjectDirectory = projectDir ?? Directory.GetCurrentDirectory(); @@ -88,10 +88,10 @@ private object InvokeOperationImpl(string operationName, IDictionary arguments) return resultHandler.Result; } - public IDictionary AddMigration(string name, string outputDir, string contextType, string @namespace) + public IDictionary AddMigration(string name, string? outputDir, string? contextType, string? @namespace) => InvokeOperation( "AddMigration", - new Dictionary + new Dictionary { ["name"] = name, ["outputDir"] = outputDir, @@ -99,35 +99,35 @@ public IDictionary AddMigration(string name, string outputDir, string contextTyp ["namespace"] = @namespace }); - public IDictionary RemoveMigration(string contextType, bool force) + public IDictionary RemoveMigration(string? contextType, bool force) => InvokeOperation( "RemoveMigration", - new Dictionary { ["contextType"] = contextType, ["force"] = force }); + new Dictionary { ["contextType"] = contextType, ["force"] = force }); - public IEnumerable GetMigrations(string contextType, string connectionString, bool noConnect) + public IEnumerable GetMigrations(string? contextType, string? connectionString, bool noConnect) => InvokeOperation>( "GetMigrations", - new Dictionary + new Dictionary { ["contextType"] = contextType, ["connectionString"] = connectionString, ["noConnect"] = noConnect }); - public void DropDatabase(string contextType) + public void DropDatabase(string? contextType) => InvokeOperation( "DropDatabase", - new Dictionary { ["contextType"] = contextType }); + new Dictionary { ["contextType"] = contextType }); - public IDictionary GetContextInfo(string name) + public IDictionary GetContextInfo(string? name) => InvokeOperation( "GetContextInfo", - new Dictionary { ["contextType"] = name }); + new Dictionary { ["contextType"] = name }); - public void UpdateDatabase(string migration, string connectionString, string contextType) + public void UpdateDatabase(string? migration, string? connectionString, string? contextType) => InvokeOperation( "UpdateDatabase", - new Dictionary + new Dictionary { ["targetMigration"] = migration, ["connectionString"] = connectionString, @@ -140,21 +140,21 @@ public IEnumerable GetContextTypes() public IDictionary ScaffoldContext( string provider, string connectionString, - string outputDir, - string outputDbContextDir, - string dbContextClassName, + string? outputDir, + string? outputDbContextDir, + string? dbContextClassName, IEnumerable schemaFilters, IEnumerable tableFilters, bool useDataAnnotations, bool overwriteFiles, bool useDatabaseNames, - string modelNamespace, - string contextNamespace, + string? modelNamespace, + string? contextNamespace, bool suppressOnConfiguring, bool noPluralize) => InvokeOperation( "ScaffoldContext", - new Dictionary + new Dictionary { ["provider"] = provider, ["connectionString"] = connectionString, @@ -173,14 +173,14 @@ public IDictionary ScaffoldContext( }); public string ScriptMigration( - string fromMigration, - string toMigration, + string? fromMigration, + string? toMigration, bool idempotent, bool noTransactions, - string contextType) + string? contextType) => InvokeOperation( "ScriptMigration", - new Dictionary + new Dictionary { ["fromMigration"] = fromMigration, ["toMigration"] = toMigration, @@ -189,9 +189,9 @@ public string ScriptMigration( ["contextType"] = contextType }); - public string ScriptDbContext(string contextType) + public string ScriptDbContext(string? contextType) => InvokeOperation( "ScriptDbContext", - new Dictionary { ["contextType"] = contextType }); + new Dictionary { ["contextType"] = contextType }); } } diff --git a/src/ef/ReflectionOperationExecutor.cs b/src/ef/ReflectionOperationExecutor.cs index cd240a31e47..7d3aa7f3a64 100644 --- a/src/ef/ReflectionOperationExecutor.cs +++ b/src/ef/ReflectionOperationExecutor.cs @@ -21,11 +21,11 @@ internal class ReflectionOperationExecutor : OperationExecutorBase public ReflectionOperationExecutor( string assembly, - string startupAssembly, - string projectDir, - string dataDirectory, - string rootNamespace, - string language, + string? startupAssembly, + string? projectDir, + string? dataDirectory, + string? rootNamespace, + string? language, string[] remainingArguments) : base(assembly, startupAssembly, projectDir, rootNamespace, language, remainingArguments) { @@ -38,19 +38,19 @@ public ReflectionOperationExecutor( AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; _commandsAssembly = Assembly.Load(new AssemblyName { Name = DesignAssemblyName }); - var reportHandlerType = _commandsAssembly.GetType(ReportHandlerTypeName, throwOnError: true, ignoreCase: false); + var reportHandlerType = _commandsAssembly.GetType(ReportHandlerTypeName, throwOnError: true, ignoreCase: false)!; var reportHandler = Activator.CreateInstance( reportHandlerType, (Action)Reporter.WriteError, (Action)Reporter.WriteWarning, (Action)Reporter.WriteInformation, - (Action)Reporter.WriteVerbose); + (Action)Reporter.WriteVerbose)!; _executor = Activator.CreateInstance( - _commandsAssembly.GetType(ExecutorTypeName, throwOnError: true, ignoreCase: false), + _commandsAssembly.GetType(ExecutorTypeName, throwOnError: true, ignoreCase: false)!, reportHandler, - new Dictionary + new Dictionary { { "targetName", AssemblyFileName }, { "startupTargetName", StartupAssemblyFileName }, @@ -59,22 +59,22 @@ public ReflectionOperationExecutor( { "language", Language }, { "toolsVersion", ProductInfo.GetVersion() }, { "remainingArguments", RemainingArguments } - }); + })!; - _resultHandlerType = _commandsAssembly.GetType(ResultHandlerTypeName, throwOnError: true, ignoreCase: false); + _resultHandlerType = _commandsAssembly.GetType(ResultHandlerTypeName, throwOnError: true, ignoreCase: false)!; } protected override object CreateResultHandler() - => Activator.CreateInstance(_resultHandlerType); + => Activator.CreateInstance(_resultHandlerType)!; protected override void Execute(string operationName, object resultHandler, IDictionary arguments) => Activator.CreateInstance( - _commandsAssembly.GetType(ExecutorTypeName + "+" + operationName, throwOnError: true, ignoreCase: true), + _commandsAssembly.GetType(ExecutorTypeName + "+" + operationName, throwOnError: true, ignoreCase: true)!, _executor, resultHandler, arguments); - private Assembly ResolveAssembly(object sender, ResolveEventArgs args) + private Assembly? ResolveAssembly(object? sender, ResolveEventArgs args) { var assemblyName = new AssemblyName(args.Name); diff --git a/src/ef/Reporter.cs b/src/ef/Reporter.cs index 219ca5a2022..c1ddb969116 100644 --- a/src/ef/Reporter.cs +++ b/src/ef/Reporter.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Diagnostics.CodeAnalysis; using System.Linq; using static Microsoft.EntityFrameworkCore.Tools.AnsiConstants; @@ -13,22 +14,23 @@ internal static class Reporter public static bool NoColor { get; set; } public static bool PrefixOutput { get; set; } - public static string Colorize(string value, Func colorizeFunc) + [return: NotNullIfNotNull("value")] + public static string? Colorize(string? value, Func colorizeFunc) => NoColor ? value : colorizeFunc(value); - public static void WriteError(string message) + public static void WriteError(string? message) => WriteLine(Prefix("error: ", Colorize(message, x => Bold + Red + x + Reset))); - public static void WriteWarning(string message) + public static void WriteWarning(string? message) => WriteLine(Prefix("warn: ", Colorize(message, x => Bold + Yellow + x + Reset))); - public static void WriteInformation(string message) + public static void WriteInformation(string? message) => WriteLine(Prefix("info: ", message)); - public static void WriteData(string message) + public static void WriteData(string? message) => WriteLine(Prefix("data: ", Colorize(message, x => Bold + Gray + x + Reset))); - public static void WriteVerbose(string message) + public static void WriteVerbose(string? message) { if (IsVerbose) { @@ -36,14 +38,16 @@ public static void WriteVerbose(string message) } } - private static string Prefix(string prefix, string value) + private static string? Prefix(string prefix, string? value) => PrefixOutput - ? string.Join( - Environment.NewLine, - value.Split(new[] { Environment.NewLine }, StringSplitOptions.None).Select(l => prefix + l)) + ? value == null + ? prefix + : string.Join( + Environment.NewLine, + value.Split(new[] { Environment.NewLine }, StringSplitOptions.None).Select(l => prefix + l)) : value; - private static void WriteLine(string value) + private static void WriteLine(string? value) { if (NoColor) { diff --git a/src/ef/ef.csproj b/src/ef/ef.csproj index b2548b58e40..b26f7729527 100644 --- a/src/ef/ef.csproj +++ b/src/ef/ef.csproj @@ -12,6 +12,7 @@ --> false False + enable