Skip to content

Commit

Permalink
fix null handling
Browse files Browse the repository at this point in the history
  • Loading branch information
adamralph committed Feb 1, 2022
1 parent fb3cb4d commit 0a1041c
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 90 deletions.
5 changes: 3 additions & 2 deletions MinVer.Lib/MajorMinor.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Diagnostics.CodeAnalysis;

namespace MinVer.Lib
{
Expand Down Expand Up @@ -30,9 +31,9 @@ public MajorMinor(int major, int minor)

public static string ValidValues => "1.0, 1.1, 2.0, etc.";

public static bool TryParse(string value, out MajorMinor majorMinor)
public static bool TryParse(string value, [NotNullWhen(returnValue: true)] out MajorMinor? majorMinor)
{
majorMinor = Zero;
majorMinor = null;

if (string.IsNullOrWhiteSpace(value))
{
Expand Down
6 changes: 3 additions & 3 deletions MinVer.Lib/Version.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public int CompareTo(Version? other)

public Version Satisfying(MajorMinor minMajorMinor, string defaultPreReleasePhase)
{
minMajorMinor ??= MajorMinor.Zero;
minMajorMinor = minMajorMinor ?? throw new ArgumentNullException(nameof(minMajorMinor));

return minMajorMinor.Major < this.major || (minMajorMinor.Major == this.major && minMajorMinor.Minor <= this.minor)
? this
Expand All @@ -127,8 +127,8 @@ public Version AddBuildMetadata(string buildMetadata)

public static bool TryParse(string text, [NotNullWhen(returnValue: true)] out Version? version, string prefix = "")
{
text ??= "";
prefix ??= "";
text = text ?? throw new ArgumentNullException(nameof(text));
prefix = prefix ?? throw new ArgumentNullException(nameof(prefix));

version = null;

Expand Down
2 changes: 1 addition & 1 deletion MinVer.Lib/Versioner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ private static Version GetVersion(string workDir, string tagPrefix, VersionPart
.OrderBy(candidate => candidate.Version)
.ThenByDescending(candidate => candidate.Index).ToList();

var tagWidth = log.IsDebugEnabled ? orderedCandidates.Max(candidate => candidate.Tag?.Length ?? 2) : 0;
var tagWidth = log.IsDebugEnabled ? orderedCandidates.Max(candidate => candidate.Tag.Length) : 0;
var versionWidth = log.IsDebugEnabled ? orderedCandidates.Max(candidate => candidate.Version.ToString().Length) : 0;
var heightWidth = log.IsDebugEnabled ? orderedCandidates.Max(candidate => candidate.Height).ToString(CultureInfo.CurrentCulture).Length : 0;

Expand Down
5 changes: 3 additions & 2 deletions MinVer/VerbosityMap.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;

namespace MinVer
{
internal static class VerbosityMap
{
private static readonly Dictionary<string, Verbosity> map = new Dictionary<string, Verbosity>(StringComparer.OrdinalIgnoreCase);
private static readonly Dictionary<string, Verbosity?> map = new Dictionary<string, Verbosity?>(StringComparer.OrdinalIgnoreCase);

static VerbosityMap()
{
Expand All @@ -26,6 +27,6 @@ static void Add(Verbosity verbosity, int shortLength)
public static string ValidValues => "q[uiet], m[inimal] (default), n[ormal], d[etailed], or diag[nostic] (case insensitive)";

// spell-checker:enable
public static bool TryMap(string value, out Verbosity verbosity) => map.TryGetValue(value, out verbosity);
public static bool TryMap(string value, [NotNullWhen(returnValue: true)] out Verbosity? verbosity) => map.TryGetValue(value, out verbosity);
}
}
2 changes: 1 addition & 1 deletion MinVerTests.Infra/Sdk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public static class Sdk

public static async Task CreateSolution(string path, string[] projectNames, string configuration = Configuration.Current)
{
projectNames ??= Array.Empty<string>();
projectNames = projectNames ?? throw new ArgumentNullException(nameof(projectNames));

FileSystem.EnsureEmptyDirectory(path);

Expand Down
2 changes: 1 addition & 1 deletion minver-cli/Logger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ internal class Logger : ILogger

public static void ErrorInvalidEnvVar(string name, string value, string validValueString)
{
if (validValueString == null)
if (validValueString.Length == 0)
{
Error($"Invalid environment variable '{name}' '{value}'.");
}
Expand Down
137 changes: 68 additions & 69 deletions minver-cli/Options.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ namespace MinVer
internal class Options
{
public Options(
VersionPart autoIncrement,
string buildMeta,
string defaultPreReleasePhase,
MajorMinor minMajorMinor,
string tagPrefix,
Verbosity verbosity,
VersionPart? autoIncrement,
string? buildMeta,
string? defaultPreReleasePhase,
MajorMinor? minMajorMinor,
string? tagPrefix,
Verbosity? verbosity,
Lib.Version? versionOverride)
{
this.AutoIncrement = autoIncrement;
Expand All @@ -32,119 +32,116 @@ public static bool TryParseEnvVars([NotNullWhen(returnValue: true)] out Options?
{
options = null;

var autoIncrement = default(VersionPart);
var minMajorMinor = MajorMinor.Zero;
var verbosity = default(Verbosity);
var versionOverride = default(Lib.Version?);
VersionPart? autoIncrement = null;
MajorMinor? minMajorMinor = null;
Verbosity? verbosity = null;
Lib.Version? versionOverride = null;

var autoIncrementEnvVar = GetEnvVar("MinVerAutoIncrement");
if (!string.IsNullOrEmpty(autoIncrementEnvVar))
{
if (!Enum.TryParse(autoIncrementEnvVar, true, out autoIncrement))
if (Enum.TryParse<VersionPart>(autoIncrementEnvVar, true, out var versionPart))
{
autoIncrement = versionPart;
}
else
{
Logger.ErrorInvalidEnvVar("MinVerAutoIncrement", autoIncrementEnvVar, VersionPartExtensions.ValidValues);
return false;
}
}

var buildMeta = GetEnvVar("MinVerBuildMetadata");

var defaultPreReleasePhase = GetEnvVar("MinVerDefaultPreReleasePhase");

var minMajorMinorEnvVar = GetEnvVar("MinVerMinimumMajorMinor");
if (!string.IsNullOrEmpty(minMajorMinorEnvVar))
if (!string.IsNullOrEmpty(minMajorMinorEnvVar) && !MajorMinor.TryParse(minMajorMinorEnvVar, out minMajorMinor))
{
if (!MajorMinor.TryParse(minMajorMinorEnvVar, out minMajorMinor))
{
Logger.ErrorInvalidEnvVar("MinVerMinimumMajorMinor", minMajorMinorEnvVar, MajorMinor.ValidValues);
return false;
}
Logger.ErrorInvalidEnvVar("MinVerMinimumMajorMinor", minMajorMinorEnvVar, MajorMinor.ValidValues);
return false;
}

var tagPrefix = GetEnvVar("MinVerTagPrefix");

var verbosityEnvVar = GetEnvVar("MinVerVerbosity");
if (!string.IsNullOrEmpty(verbosityEnvVar))
if (!string.IsNullOrEmpty(verbosityEnvVar) && !VerbosityMap.TryMap(verbosityEnvVar, out verbosity))
{
if (!VerbosityMap.TryMap(verbosityEnvVar, out verbosity))
{
Logger.ErrorInvalidEnvVar("MinVerVerbosity", verbosityEnvVar, VerbosityMap.ValidValues);
return false;
}
Logger.ErrorInvalidEnvVar("MinVerVerbosity", verbosityEnvVar, VerbosityMap.ValidValues);
return false;
}

var versionOverrideEnvVar = GetEnvVar("MinVerVersionOverride");
if (!string.IsNullOrEmpty(versionOverrideEnvVar))
if (!string.IsNullOrEmpty(versionOverrideEnvVar) && !Lib.Version.TryParse(versionOverrideEnvVar, out versionOverride))
{
if (!Lib.Version.TryParse(versionOverrideEnvVar, out versionOverride))
{
Logger.ErrorInvalidEnvVar("MinVerVersionOverride", versionOverrideEnvVar, "");
return false;
}
Logger.ErrorInvalidEnvVar("MinVerVersionOverride", versionOverrideEnvVar, "");
return false;
}

options = new Options(autoIncrement, buildMeta, defaultPreReleasePhase, minMajorMinor, tagPrefix, verbosity, versionOverride);

return true;
}

private static string GetEnvVar(string name)
private static string? GetEnvVar(string name)
{
var vars = Environment.GetEnvironmentVariables();

var key = vars.Keys
.Cast<string>()
.OrderBy(_ => _)
.FirstOrDefault(k => string.Equals(k, name, StringComparison.OrdinalIgnoreCase));
.OrderBy(_ => _, StringComparer.Ordinal)
.FirstOrDefault(key => string.Equals(key, name, StringComparison.OrdinalIgnoreCase));

return key == null
? ""
: (string?)vars[key] ?? "";
return key == null ? null : (string?)vars[key];
}
#endif

public static bool TryParse(
string autoIncrementOption,
string buildMetaOption,
string defaultPreReleasePhaseOption,
string minMajorMinorOption,
string tagPrefixOption,
string verbosityOption,
string? autoIncrementOption,
string? buildMetaOption,
string? defaultPreReleasePhaseOption,
string? minMajorMinorOption,
string? tagPrefixOption,
string? verbosityOption,
#if MINVER
string versionOverrideOption,
string? versionOverrideOption,
#endif
[NotNullWhen(returnValue: true)] out Options? options)
{
options = null;

var autoIncrement = default(VersionPart);
var minMajorMinor = MajorMinor.Zero;
var verbosity = default(Verbosity);
var versionOverride = default(Lib.Version?);
VersionPart? autoIncrement = null;
MajorMinor? minMajorMinor = null;
Verbosity? verbosity = null;
Lib.Version? versionOverride = null;

if (!string.IsNullOrEmpty(autoIncrementOption) &&
!Enum.TryParse(autoIncrementOption, true, out autoIncrement))
if (!string.IsNullOrEmpty(autoIncrementOption))
{
Logger.ErrorInvalidAutoIncrement(autoIncrementOption);
return false;
if (Enum.TryParse<VersionPart>(autoIncrementOption, true, out var versionPart))
{
autoIncrement = versionPart;
}
else
{
Logger.ErrorInvalidAutoIncrement(autoIncrementOption);
return false;
}
}

if (!string.IsNullOrEmpty(minMajorMinorOption) &&
!MajorMinor.TryParse(minMajorMinorOption, out minMajorMinor))
if (!string.IsNullOrEmpty(minMajorMinorOption) && !MajorMinor.TryParse(minMajorMinorOption, out minMajorMinor))
{
Logger.ErrorInvalidMinMajorMinor(minMajorMinorOption);
return false;
}

if (!string.IsNullOrEmpty(verbosityOption) &&
!VerbosityMap.TryMap(verbosityOption, out verbosity))
if (!string.IsNullOrEmpty(verbosityOption) && !VerbosityMap.TryMap(verbosityOption, out verbosity))
{
Logger.ErrorInvalidVerbosity(verbosityOption);
return false;
}

#if MINVER
if (!string.IsNullOrEmpty(versionOverrideOption) &&
!Lib.Version.TryParse(versionOverrideOption, out versionOverride))
if (!string.IsNullOrEmpty(versionOverrideOption) && !Lib.Version.TryParse(versionOverrideOption, out versionOverride))
{
Logger.ErrorInvalidVersionOverride(versionOverrideOption);
return false;
Expand All @@ -158,25 +155,27 @@ public static bool TryParse(

public Options Mask(Options other) =>
new Options(
this.AutoIncrement == default ? other.AutoIncrement : this.AutoIncrement,
string.IsNullOrEmpty(this.BuildMeta) ? other.BuildMeta : this.BuildMeta,
string.IsNullOrEmpty(this.DefaultPreReleasePhase) ? other.DefaultPreReleasePhase : this.DefaultPreReleasePhase,
this.MinMajorMinor == MajorMinor.Zero ? other.MinMajorMinor : this.MinMajorMinor,
string.IsNullOrEmpty(this.TagPrefix) ? other.TagPrefix : this.TagPrefix,
this.Verbosity == default ? other.Verbosity : this.Verbosity,
this.VersionOverride ?? other.VersionOverride);
#pragma warning disable format
this.AutoIncrement ?? other.AutoIncrement,
this.BuildMeta ?? other.BuildMeta,
this.DefaultPreReleasePhase ?? other.DefaultPreReleasePhase,
this.MinMajorMinor ?? other.MinMajorMinor,
this.TagPrefix ?? other.TagPrefix,
this.Verbosity ?? other.Verbosity,
this.VersionOverride ?? other.VersionOverride);
#pragma warning restore format

public VersionPart AutoIncrement { get; private set; }
public VersionPart? AutoIncrement { get; private set; }

public string BuildMeta { get; private set; }
public string? BuildMeta { get; private set; }

public string DefaultPreReleasePhase { get; private set; }
public string? DefaultPreReleasePhase { get; private set; }

public MajorMinor MinMajorMinor { get; private set; }
public MajorMinor? MinMajorMinor { get; private set; }

public string TagPrefix { get; private set; }
public string? TagPrefix { get; private set; }

public Verbosity Verbosity { get; private set; }
public Verbosity? Verbosity { get; private set; }

public Lib.Version? VersionOverride { get; private set; }
}
Expand Down
18 changes: 9 additions & 9 deletions minver-cli/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ private static int Main(string[] args)
}

if (!Options.TryParse(
autoIncrementOption.Value() ?? "",
buildMetaOption.Value() ?? "",
defaultPreReleasePhaseOption.Value() ?? "",
minMajorMinorOption.Value() ?? "",
tagPrefixOption.Value() ?? "",
verbosityOption.Value() ?? "",
autoIncrementOption.Value(),
buildMetaOption.Value(),
defaultPreReleasePhaseOption.Value(),
minMajorMinorOption.Value(),
tagPrefixOption.Value(),
verbosityOption.Value(),
#if MINVER
versionOverrideOption.Value() ?? "",
versionOverrideOption.Value(),
#endif
out var options))
{
Expand All @@ -63,7 +63,7 @@ private static int Main(string[] args)
options = options.Mask(envOptions);
#endif

var log = new Logger(options.Verbosity);
var log = new Logger(options.Verbosity ?? default);

_ = log.IsDebugEnabled && log.Debug($"MinVer {informationalVersion}.");

Expand All @@ -76,7 +76,7 @@ private static int Main(string[] args)
return 0;
}

var version = Versioner.GetVersion(workDir, options.TagPrefix, options.MinMajorMinor, options.BuildMeta, options.AutoIncrement, options.DefaultPreReleasePhase, log);
var version = Versioner.GetVersion(workDir, options.TagPrefix ?? "", options.MinMajorMinor ?? MajorMinor.Zero, options.BuildMeta ?? "", options.AutoIncrement ?? default, options.DefaultPreReleasePhase ?? "", log);

Console.Out.WriteLine(version);

Expand Down
5 changes: 3 additions & 2 deletions minver-cli/VerbosityMap.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;

namespace MinVer
{
internal static class VerbosityMap
{
private static readonly Dictionary<string, Verbosity> map = new Dictionary<string, Verbosity>(StringComparer.OrdinalIgnoreCase);
private static readonly Dictionary<string, Verbosity?> map = new Dictionary<string, Verbosity?>(StringComparer.OrdinalIgnoreCase);

static VerbosityMap()
{
Expand All @@ -26,6 +27,6 @@ static void Add(Verbosity verbosity)
public static string ValidValues => "e[rror], w[arn], i[nfo] (default), d[ebug], or t[race] (case insensitive)";

// spell-checker:enable
public static bool TryMap(string value, out Verbosity verbosity) => map.TryGetValue(value, out verbosity);
public static bool TryMap(string value, [NotNullWhen(returnValue: true)] out Verbosity? verbosity) => map.TryGetValue(value, out verbosity);
}
}

0 comments on commit 0a1041c

Please sign in to comment.