diff --git a/.cspell.json b/.cspell.json index 2602aeb3..97a771f7 100644 --- a/.cspell.json +++ b/.cspell.json @@ -17,6 +17,7 @@ "gpgsign", "nologo", "nupkg", + "Sdks", "shas", "Versioner", "Xbehave", diff --git a/.github/linters/.jscpd.json b/.github/linters/.jscpd.json new file mode 100644 index 00000000..1804e2f8 --- /dev/null +++ b/.github/linters/.jscpd.json @@ -0,0 +1,5 @@ +{ + "ignore": [ + "MinVerTests.Packages/**" + ] +} diff --git a/MinVer.sln b/MinVer.sln index aea8b05a..bf1988b1 100644 --- a/MinVer.sln +++ b/MinVer.sln @@ -13,6 +13,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MinVer", "MinVer\MinVer.csp EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "minver-cli", "minver-cli\minver-cli.csproj", "{34A5ECB1-400C-462A-B2B8-2B7136BE162A}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MinVerTests.Infra", "MinVerTests.Infra\MinVerTests.Infra.csproj", "{AA98F752-F8EF-447D-BC85-4F277CAF4B82}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MinVerTests.Packages", "MinVerTests.Packages\MinVerTests.Packages.csproj", "{694ECAC7-FD05-4550-A4FB-8F497D29ECB0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -39,6 +43,14 @@ Global {34A5ECB1-400C-462A-B2B8-2B7136BE162A}.Debug|Any CPU.Build.0 = Debug|Any CPU {34A5ECB1-400C-462A-B2B8-2B7136BE162A}.Release|Any CPU.ActiveCfg = Release|Any CPU {34A5ECB1-400C-462A-B2B8-2B7136BE162A}.Release|Any CPU.Build.0 = Release|Any CPU + {AA98F752-F8EF-447D-BC85-4F277CAF4B82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AA98F752-F8EF-447D-BC85-4F277CAF4B82}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AA98F752-F8EF-447D-BC85-4F277CAF4B82}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AA98F752-F8EF-447D-BC85-4F277CAF4B82}.Release|Any CPU.Build.0 = Release|Any CPU + {694ECAC7-FD05-4550-A4FB-8F497D29ECB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {694ECAC7-FD05-4550-A4FB-8F497D29ECB0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {694ECAC7-FD05-4550-A4FB-8F497D29ECB0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {694ECAC7-FD05-4550-A4FB-8F497D29ECB0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/MinVerTests.Infra/AssemblyVersion.cs b/MinVerTests.Infra/AssemblyVersion.cs new file mode 100644 index 00000000..0d1562e2 --- /dev/null +++ b/MinVerTests.Infra/AssemblyVersion.cs @@ -0,0 +1,6 @@ +#if !NETCOREAPP2_1 +namespace MinVerTests.Infra +{ + public record AssemblyVersion(int Major, int Minor, int Build, int Revision); +} +#endif diff --git a/MinVerTests.Infra/CommandExtensions.cs b/MinVerTests.Infra/CommandExtensions.cs new file mode 100644 index 00000000..74efe769 --- /dev/null +++ b/MinVerTests.Infra/CommandExtensions.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using CliWrap; +using CliWrap.Buffered; + +namespace MinVerTests.Infra +{ + internal static class CommandExtensions + { + private static int index; + + public static async Task ExecuteBufferedLoggedAsync(this Command command) + { + var validation = command.Validation; + + var result = await command.WithValidation(CommandResultValidation.None).ExecuteBufferedAsync(); + + var index = Interlocked.Increment(ref CommandExtensions.index); + + var log = +$@" +# Command {index} + +## Target file path + +`{command.TargetFilePath}` + +## Arguments + +`{command.Arguments}` + +## Environment variables + +```text +{string.Join(Environment.NewLine, command.EnvironmentVariables.Select(pair => $"{pair.Key}={pair.Value}"))} +``` + +## Exit code + +`{result.ExitCode}` + +## Standard error + +```text +{result.StandardError} +``` + +## Standard output + +```text +{result.StandardOutput} +``` +"; + + await File.WriteAllTextAsync(Path.Combine(command.WorkingDirPath, $"command-{index:D2}.md"), log); + + return result.ExitCode == 0 || validation == CommandResultValidation.None ? result : throw new Exception(log); + } + } +} diff --git a/MinVerTests.Infra/Configuration.cs b/MinVerTests.Infra/Configuration.cs new file mode 100644 index 00000000..594b7dee --- /dev/null +++ b/MinVerTests.Infra/Configuration.cs @@ -0,0 +1,12 @@ +namespace MinVerTests.Infra +{ + internal static class Configuration + { + public const string Current = +#if DEBUG + "Debug"; +#elif RELEASE + "Release"; +#endif + } +} diff --git a/MinVerTests.Lib/Infra/FileSystem.cs b/MinVerTests.Infra/FileSystem.cs similarity index 71% rename from MinVerTests.Lib/Infra/FileSystem.cs rename to MinVerTests.Infra/FileSystem.cs index c5a545a0..64489698 100644 --- a/MinVerTests.Lib/Infra/FileSystem.cs +++ b/MinVerTests.Infra/FileSystem.cs @@ -1,45 +1,21 @@ using System.IO; using System.Threading; -namespace MinVerTests.Lib.Infra +namespace MinVerTests.Infra { // The spin waits are required. System.IO and the file system race. ¯\_(ツ)_/¯ public static class FileSystem { private static readonly int millisecondsTimeout = 50; - public static string GetScenarioDirectory(string scenarioName) => Path.Combine(Path.GetTempPath(), "minver-tests", scenarioName); - public static void EnsureEmptyDirectory(string path) - { - EnsureDirectoryDeleted(path); - EnsureDirectoryCreated(path); - } - - private static void EnsureDirectoryCreated(string path) - { - if (SpinWait.SpinUntil(() => !Directory.Exists(path), millisecondsTimeout)) - { - CreateDirectory(path); - } - } - - private static void EnsureDirectoryDeleted(string path) { if (SpinWait.SpinUntil(() => Directory.Exists(path), millisecondsTimeout)) { DeleteDirectory(path); } - } - - private static void CreateDirectory(string path) - { - Directory.CreateDirectory(path); - if (!SpinWait.SpinUntil(() => Directory.Exists(path), millisecondsTimeout)) - { - throw new IOException($"Failed to create directory '{path}'."); - } + CreateDirectory(path); } private static void DeleteDirectory(string path) @@ -47,7 +23,11 @@ private static void DeleteDirectory(string path) // Directory.Delete fails if anything in the tree has the read-only attribute set. ¯\_(ツ)_/¯ ResetAttributes(new DirectoryInfo(path)); +#if !NETCOREAPP2_1 + static void ResetAttributes(DirectoryInfo directory) +#else void ResetAttributes(DirectoryInfo directory) +#endif { foreach (var childDirectory in directory.GetDirectories()) { @@ -69,5 +49,15 @@ void ResetAttributes(DirectoryInfo directory) throw new IOException($"Failed to delete directory '{path}'."); } } + + private static void CreateDirectory(string path) + { + _ = Directory.CreateDirectory(path); + + if (!SpinWait.SpinUntil(() => Directory.Exists(path), millisecondsTimeout)) + { + throw new IOException($"Failed to create directory '{path}'."); + } + } } } diff --git a/MinVerTests.Infra/FileVersion.cs b/MinVerTests.Infra/FileVersion.cs new file mode 100644 index 00000000..3fe799e8 --- /dev/null +++ b/MinVerTests.Infra/FileVersion.cs @@ -0,0 +1,6 @@ +#if !NETCOREAPP2_1 +namespace MinVerTests.Infra +{ + public record FileVersion(int FileMajorPart, int FileMinorPart, int FileBuildPart, int FilePrivatePart, string ProductVersion); +} +#endif diff --git a/MinVerTests.Infra/Git.cs b/MinVerTests.Infra/Git.cs new file mode 100644 index 00000000..bcf6a89e --- /dev/null +++ b/MinVerTests.Infra/Git.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using CliWrap; +using CliWrap.Buffered; + +namespace MinVerTests.Infra +{ + public static class Git + { + public static async Task EnsureEmptyRepositoryAndCommit(string path) + { + await EnsureEmptyRepository(path); + await Commit(path); + } + + public static Task Commit(string path) => + Cli.Wrap("git").WithArguments("commit -m '.' --allow-empty").WithWorkingDirectory(path).ExecuteAsync(); + + public static async Task EnsureEmptyRepository(string path) + { + FileSystem.EnsureEmptyDirectory(path); + await Init(path); + } + + public static async Task Init(string path) + { + _ = await Cli.Wrap("git").WithArguments("init").WithWorkingDirectory(path).ExecuteAsync(); + _ = await Cli.Wrap("git").WithArguments("config user.email johndoe@tempuri.org").WithWorkingDirectory(path).ExecuteAsync(); + _ = await Cli.Wrap("git").WithArguments("config user.name John Doe").WithWorkingDirectory(path).ExecuteAsync(); + _ = await Cli.Wrap("git").WithArguments("config commit.gpgsign false").WithWorkingDirectory(path).ExecuteAsync(); + } + + public static async Task GetGraph(string path) => + (await Cli.Wrap("git").WithArguments("log --graph --pretty=format:'%d'").WithWorkingDirectory(path).ExecuteBufferedAsync()) + .StandardOutput; + + public static Task Tag(string path, string tag) => + Cli.Wrap("git").WithArguments($"tag {tag}").WithWorkingDirectory(path).ExecuteAsync(); + + public static Task Tag(string path, string tagName, string sha) => + Cli.Wrap("git").WithArguments($"tag {tagName} {sha}").WithWorkingDirectory(path).ExecuteAsync(); + + public static Task AnnotatedTag(string path, string tag, string message) => + Cli.Wrap("git").WithArguments($"tag {tag} -a -m '{message}'").WithWorkingDirectory(path).ExecuteAsync(); + + public static async Task> GetCommitShas(string path) => + (await Cli.Wrap("git").WithArguments("log --pretty=format:\"%H\"").WithWorkingDirectory(path).ExecuteBufferedAsync()) + .StandardOutput + .Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); + + public static Task Checkout(string path, string sha) => + Cli.Wrap("git").WithArguments($"checkout {sha}").WithWorkingDirectory(path).ExecuteAsync(); + } +} diff --git a/MinVerTests.Infra/MinVerCli.cs b/MinVerTests.Infra/MinVerCli.cs new file mode 100644 index 00000000..f6bd8c24 --- /dev/null +++ b/MinVerTests.Infra/MinVerCli.cs @@ -0,0 +1,26 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using CliWrap; + +namespace MinVerTests.Infra +{ + public static class MinVerCli + { + public static async Task<(string, string)> Run(string workingDirectory, string configuration = Configuration.Current, params (string, string)[] envVars) + { + var environmentVariables = envVars.ToDictionary(envVar => envVar.Item1, envVar => envVar.Item2, StringComparer.OrdinalIgnoreCase); + _ = environmentVariables.TryAdd("MinVerVerbosity".ToAltCase(), "trace"); + + var result = await Cli.Wrap("dotnet") + .WithArguments($"exec {GetPath(configuration)}") + .WithEnvironmentVariables(environmentVariables) + .WithWorkingDirectory(workingDirectory).ExecuteBufferedLoggedAsync(); + + return (result.StandardOutput.Trim(), result.StandardError); + } + + public static string GetPath(string configuration) => + Solution.GetFullPath($"minver-cli/bin/{configuration}/netcoreapp2.1/minver-cli.dll"); + } +} diff --git a/MinVerTests.Infra/MinVerTests.Infra.csproj b/MinVerTests.Infra/MinVerTests.Infra.csproj new file mode 100644 index 00000000..da24549f --- /dev/null +++ b/MinVerTests.Infra/MinVerTests.Infra.csproj @@ -0,0 +1,11 @@ + + + + netcoreapp2.1;net5.0 + + + + + + + diff --git a/MinVerTests.Infra/Package.cs b/MinVerTests.Infra/Package.cs new file mode 100644 index 00000000..b48c32a3 --- /dev/null +++ b/MinVerTests.Infra/Package.cs @@ -0,0 +1,17 @@ +#if !NETCOREAPP2_1 +using System.Collections.Generic; +using System.Linq; + +namespace MinVerTests.Infra +{ + public record Package(string Version, AssemblyVersion AssemblyVersion, FileVersion FileVersion) + { + public static Package WithVersion(int Major, int Minor, int Patch, IEnumerable PreReleaseIdentifiers = null, int Height = 0, string BuildMetadata = null) + { + var version = $"{Major}.{Minor}.{Patch}{(!(PreReleaseIdentifiers?.Any() ?? false) ? "" : $"-{string.Join(".", PreReleaseIdentifiers)}")}{(Height == 0 ? "" : $".{Height}")}{(string.IsNullOrEmpty(BuildMetadata) ? "" : $"+{BuildMetadata}")}"; + + return new Package(version, new AssemblyVersion(Major, 0, 0, 0), new FileVersion(Major, Minor, Patch, 0, version)); + } + } +} +#endif diff --git a/MinVerTests.Infra/Sdk.cs b/MinVerTests.Infra/Sdk.cs new file mode 100644 index 00000000..3961b892 --- /dev/null +++ b/MinVerTests.Infra/Sdk.cs @@ -0,0 +1,115 @@ +#if !NETCOREAPP2_1 +using System; +using System.Diagnostics; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Runtime.Loader; +using System.Threading.Tasks; +using CliWrap; +using CliWrap.Builders; + +namespace MinVerTests.Infra +{ + public static class Sdk + { + private static readonly string dotnetRoot = Environment.GetEnvironmentVariable("DOTNET_ROOT"); + + public static string Version { get; } = Environment.GetEnvironmentVariable("MINVER_TESTS_SDK"); + + public static async Task CreateProject(string path, string configuration = Configuration.Current) + { + FileSystem.EnsureEmptyDirectory(path); + + if (!string.IsNullOrWhiteSpace(Version)) + { + File.WriteAllText( + Path.Combine(path, "global.json"), +$@"{{ +{" "}""sdk"": {{ +{" "}""version"": ""{Version.Trim()}"", +{" "}""rollForward"": ""disable"" +{" "}}} +}} +"); + } + + var source = Solution.GetFullPath($"MinVer/bin/{configuration}/"); + + var minVerPackageVersion = Path.GetFileNameWithoutExtension(Directory.EnumerateFiles(source, "*.nupkg").First()).Split("MinVer.", 2)[1]; + + _ = await Cli.Wrap("dotnet").WithArguments($"new classlib --name test --output {path}") + .WithEnvironmentVariables(builder => builder.SetSdk().Build()) + .WithWorkingDirectory(path).ExecuteBufferedLoggedAsync(); + + _ = await Cli.Wrap("dotnet").WithArguments($"add package MinVer --source {source} --version {minVerPackageVersion} --package-directory packages") + .WithEnvironmentVariables(builder => builder.SetSdk().Build()) + .WithWorkingDirectory(path).ExecuteBufferedLoggedAsync(); + + _ = await Cli.Wrap("dotnet").WithArguments($"restore --source {source} --packages packages") + .WithEnvironmentVariables(builder => builder.SetSdk().Build()) + .WithWorkingDirectory(path).ExecuteBufferedLoggedAsync(); + } + + public static async Task<(Package, string)> BuildProject(string path, params (string, string)[] envVars) + { + var environmentVariables = envVars.ToDictionary(envVar => envVar.Item1, envVar => envVar.Item2, StringComparer.OrdinalIgnoreCase); + _ = environmentVariables.TryAdd("MinVerVerbosity".ToAltCase(), "diagnostic"); + _ = environmentVariables.TryAdd("GeneratePackageOnBuild", "true"); + _ = environmentVariables.TryAdd("NoPackageAnalysis", "true"); + + var result = await Cli.Wrap("dotnet") + .WithArguments($"build --no-restore{((Version?.StartsWith("2.") ?? false) ? "" : " --nologo")}") + .WithEnvironmentVariables(builder => + { + foreach (var pair in environmentVariables) + { + _ = builder.Set(pair.Key, pair.Value); + } + + _ = builder.SetSdk().Build(); + }) + .WithWorkingDirectory(path).ExecuteBufferedLoggedAsync(); + + var packageFileName = Directory.EnumerateFiles(path, "*.nupkg", new EnumerationOptions { RecurseSubdirectories = true }).First(); + var extractedPackageDirectoryName = Path.Combine(Path.GetDirectoryName(packageFileName), Path.GetFileNameWithoutExtension(packageFileName)); + ZipFile.ExtractToDirectory(packageFileName, extractedPackageDirectoryName); + + var nuspec = await File.ReadAllTextAsync(Directory.EnumerateFiles(extractedPackageDirectoryName, "*.nuspec").First()); + var nuspecVersion = nuspec.Split("")[1].Split("")[0]; + + var assemblyFileName = Directory.EnumerateFiles(extractedPackageDirectoryName, "*.dll", new EnumerationOptions { RecurseSubdirectories = true }).First(); + + var systemAssemblyVersion = GetAssemblyVersion(assemblyFileName); + var assemblyVersion = new AssemblyVersion(systemAssemblyVersion.Major, systemAssemblyVersion.Minor, systemAssemblyVersion.Build, systemAssemblyVersion.Revision); + + var fileVersionInfo = FileVersionInfo.GetVersionInfo(assemblyFileName); + var fileVersion = new FileVersion(fileVersionInfo.FileMajorPart, fileVersionInfo.FileMinorPart, fileVersionInfo.FileBuildPart, fileVersionInfo.FilePrivatePart, fileVersionInfo.ProductVersion); + + return (new Package(nuspecVersion, assemblyVersion, fileVersion), result.StandardOutput); + } + + private static EnvironmentVariablesBuilder SetSdk(this EnvironmentVariablesBuilder builder) => + string.IsNullOrWhiteSpace(Version) || string.IsNullOrWhiteSpace(dotnetRoot) + ? builder + : builder + .Set("MSBuildExtensionsPath", Path.Combine(dotnetRoot, "sdk", Version, "") + Path.DirectorySeparatorChar) + .Set("MSBuildSDKsPath", Path.Combine(dotnetRoot, "sdk", Version, "Sdks")); + + private static Version GetAssemblyVersion(string assemblyFileName) + { + var assemblyLoadContext = new AssemblyLoadContext(default, true); + var assembly = assemblyLoadContext.LoadFromAssemblyPath(assemblyFileName); + + try + { + return assembly.GetName().Version; + } + finally + { + assemblyLoadContext.Unload(); + } + } + } +} +#endif diff --git a/MinVerTests.Infra/Solution.cs b/MinVerTests.Infra/Solution.cs new file mode 100644 index 00000000..b132800e --- /dev/null +++ b/MinVerTests.Infra/Solution.cs @@ -0,0 +1,10 @@ +using System.IO; + +namespace MinVerTests.Infra +{ + internal static class Solution + { + public static string GetFullPath(string path) => + Path.GetFullPath(Path.Combine(typeof(Solution).Assembly.Location, $"../../../../../", path)); + } +} diff --git a/MinVerTests.Infra/StringExtensions.cs b/MinVerTests.Infra/StringExtensions.cs new file mode 100644 index 00000000..78562085 --- /dev/null +++ b/MinVerTests.Infra/StringExtensions.cs @@ -0,0 +1,10 @@ +using System.Linq; + +namespace MinVerTests.Infra +{ + public static class StringExtensions + { + public static string ToAltCase(this string value) => + new string(value.Select((c, i) => i % 2 == 0 ? c.ToString().ToLowerInvariant()[0] : c.ToString().ToUpperInvariant()[0]).ToArray()); + } +} diff --git a/MinVerTests.Infra/TestDirectory.cs b/MinVerTests.Infra/TestDirectory.cs new file mode 100644 index 00000000..ca6f9188 --- /dev/null +++ b/MinVerTests.Infra/TestDirectory.cs @@ -0,0 +1,26 @@ +using System; +using System.Globalization; +using System.IO; +using System.Reflection; +using System.Runtime.CompilerServices; + +namespace MinVerTests.Infra +{ + public static class TestDirectory + { + private static readonly long runId = DateTimeOffset.UtcNow.UtcTicks; + + public static string Get(string testSuiteName, string testName, object tag = null) => + Path.Combine( + Path.GetTempPath(), + testSuiteName, + runId.ToString(CultureInfo.InvariantCulture), + $"{testName}{(tag == null ? "" : (tag.GetType().Name.StartsWith("ValueTuple") ? tag : $"({tag})"))}"); + + + public static string GetTestDirectory(this MethodBase testMethod, object tag = null, [CallerMemberName] string testMethodName = "") => + Get(testMethod.DeclaringType.Assembly.GetName().Name, $"{testMethod.DeclaringType.GetReflectedType().Name}.{testMethodName}", tag); + + private static Type GetReflectedType(this Type type) => type.ReflectedType?.GetReflectedType() ?? type; + } +} diff --git a/MinVerTests.Lib/AutoIncrement.cs b/MinVerTests.Lib/AutoIncrement.cs index ab3a075d..a6c9407d 100644 --- a/MinVerTests.Lib/AutoIncrement.cs +++ b/MinVerTests.Lib/AutoIncrement.cs @@ -1,9 +1,9 @@ +using System.Reflection; using MinVer.Lib; -using MinVerTests.Lib.Infra; +using MinVerTests.Infra; using Xbehave; using Xunit; -using static MinVerTests.Lib.Infra.FileSystem; -using static MinVerTests.Lib.Infra.Git; +using static MinVerTests.Infra.Git; using Version = MinVer.Lib.Version; namespace MinVerTests.Lib @@ -16,7 +16,7 @@ public static class AutoIncrement [Example("1.2.3", VersionPart.Patch, "1.2.4-alpha.0.1")] public static void RtmVersionIncrement(string tag, VersionPart autoIncrement, string expectedVersion, string path, Version actualVersion) { - $"Given a git repository with a commit in '{path = GetScenarioDirectory($"rtm-auto-increment-{tag}")}'" + $"Given a git repository with a commit in {path = MethodBase.GetCurrentMethod().GetTestDirectory(autoIncrement)}" .x(() => EnsureEmptyRepositoryAndCommit(path)); $"And the commit is tagged '{tag}'" diff --git a/MinVerTests.Lib/BuildMetadata.cs b/MinVerTests.Lib/BuildMetadata.cs index 85fd6934..e4a294ce 100644 --- a/MinVerTests.Lib/BuildMetadata.cs +++ b/MinVerTests.Lib/BuildMetadata.cs @@ -1,9 +1,9 @@ +using System.Reflection; using MinVer.Lib; -using MinVerTests.Lib.Infra; +using MinVerTests.Infra; using Xbehave; using Xunit; -using static MinVerTests.Lib.Infra.FileSystem; -using static MinVerTests.Lib.Infra.Git; +using static MinVerTests.Infra.Git; using Version = MinVer.Lib.Version; namespace MinVerTests.Lib @@ -15,7 +15,7 @@ public static class BuildMetadata [Example("a", "0.0.0-alpha.0+a")] public static void NoCommits(string buildMetadata, string expectedVersion, string path, Version actualVersion) { - $"Given an empty git repository in '{path = GetScenarioDirectory($"build-metadata-no-tag-{buildMetadata}")}'" + $"Given an empty git repository in {path = MethodBase.GetCurrentMethod().GetTestDirectory(buildMetadata)}" .x(() => EnsureEmptyRepository(path)); $"When the version is determined using build metadata '{buildMetadata}'" @@ -30,7 +30,7 @@ public static void NoCommits(string buildMetadata, string expectedVersion, strin [Example("a", "0.0.0-alpha.0+a")] public static void NoTag(string buildMetadata, string expectedVersion, string path, Version actualVersion) { - $"Given a git repository with a commit in '{path = GetScenarioDirectory($"build-metadata-no-tag-{buildMetadata}")}'" + $"Given a git repository with a commit in {path = MethodBase.GetCurrentMethod().GetTestDirectory(buildMetadata)}" .x(() => EnsureEmptyRepositoryAndCommit(path)); $"When the version is determined using build metadata '{buildMetadata}'" @@ -49,7 +49,7 @@ public static void NoTag(string buildMetadata, string expectedVersion, string pa [Example("1.2.3-pre+a", "b", "1.2.3-pre+a.b")] public static void CurrentTag(string tag, string buildMetadata, string expectedVersion, string path, Version actualVersion) { - $"Given a git repository with a commit in '{path = GetScenarioDirectory($"build-metadata-current-tag-{tag}-{buildMetadata}")}'" + $"Given a git repository with a commit in {path = MethodBase.GetCurrentMethod().GetTestDirectory((tag, buildMetadata))}" .x(() => EnsureEmptyRepositoryAndCommit(path)); $"And the commit is tagged '{tag}'" @@ -71,7 +71,7 @@ public static void CurrentTag(string tag, string buildMetadata, string expectedV [Example("1.2.3-pre+a", "b", "1.2.3-pre.1+b")] public static void PreviousTag(string tag, string buildMetadata, string expectedVersion, string path, Version actualVersion) { - $"Given a git repository with a commit in '{path = GetScenarioDirectory($"build-metadata-previous-tag-{tag}-{buildMetadata}")}'" + $"Given a git repository with a commit in {path = MethodBase.GetCurrentMethod().GetTestDirectory((tag, buildMetadata))}" .x(() => EnsureEmptyRepositoryAndCommit(path)); $"And the commit is tagged '{tag}'" diff --git a/MinVerTests.Lib/DefaultPreReleasePhases.cs b/MinVerTests.Lib/DefaultPreReleasePhases.cs index 39add20d..e76fa059 100644 --- a/MinVerTests.Lib/DefaultPreReleasePhases.cs +++ b/MinVerTests.Lib/DefaultPreReleasePhases.cs @@ -1,9 +1,9 @@ +using System.Reflection; using MinVer.Lib; -using MinVerTests.Lib.Infra; +using MinVerTests.Infra; using Xbehave; using Xunit; -using static MinVerTests.Lib.Infra.FileSystem; -using static MinVerTests.Lib.Infra.Git; +using static MinVerTests.Infra.Git; using Version = MinVer.Lib.Version; namespace MinVerTests.Lib @@ -16,7 +16,7 @@ public static class DefaultPreReleasePhases [Example("preview", "0.0.0-preview.0")] public static void DefaultPreReleasePhase(string phase, string expectedVersion, string path, Version actualVersion) { - $"Given a git repository with a commit in '{path = GetScenarioDirectory($"default-pre-release-phase-{phase}")}'" + $"Given a git repository with a commit in {path = MethodBase.GetCurrentMethod().GetTestDirectory(phase)}" .x(() => EnsureEmptyRepositoryAndCommit(path)); $"When the version is determined using the default pre-release phase '{phase}'" diff --git a/MinVerTests.Lib/Infra/Git.cs b/MinVerTests.Lib/Infra/Git.cs deleted file mode 100644 index 41577857..00000000 --- a/MinVerTests.Lib/Infra/Git.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using static MinVerTests.Lib.Infra.FileSystem; -using static SimpleExec.Command; - -namespace MinVerTests.Lib.Infra -{ - public static class Git - { - public static void EnsureEmptyRepositoryAndCommit(string path) - { - EnsureEmptyRepository(path); - Commit(path); - } - - public static void Commit(string path) => Run("git", "commit -m '.' --allow-empty", path); - - public static void EnsureEmptyRepository(string path) - { - EnsureEmptyDirectory(path); - Init(path); - PrepareForCommits(path); - } - - public static void Init(string path) => Run("git", "init", path); - - public static void PrepareForCommits(string path) - { - Run("git", "config user.email johndoe@tempuri.org", path); - Run("git", "config user.name John Doe", path); - Run("git", "config commit.gpgsign false", path); - } - - public static Task GetGraph(string path) => ReadAsync("git", "log --graph --pretty=format:'%d'", path); - - internal static void Tag(string path, string tag) => Run("git", $"tag {tag}", path); - - internal static void Tag(string path, string tagName, string sha) => Run("git", $"tag {tagName} {sha}", path); - - internal static void AnnotatedTag(string path, string tag, string message) => Run("git", $"tag {tag} -a -m '{message}'", path); - - internal static IEnumerable GetCommitShas(string path) => - Read("git", "log --pretty=format:\"%H\"", path, noEcho: true) - .Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); - - internal static void Checkout(string path, string sha) => Run("git", $"checkout {sha}", path); - } -} diff --git a/MinVerTests.Lib/MinMajorMinor.cs b/MinVerTests.Lib/MinMajorMinor.cs index 1d8f7975..4f83b4e9 100644 --- a/MinVerTests.Lib/MinMajorMinor.cs +++ b/MinVerTests.Lib/MinMajorMinor.cs @@ -1,9 +1,10 @@ +using System.Reflection; using MinVer.Lib; +using MinVerTests.Infra; using MinVerTests.Lib.Infra; using Xbehave; using Xunit; -using static MinVerTests.Lib.Infra.FileSystem; -using static MinVerTests.Lib.Infra.Git; +using static MinVerTests.Infra.Git; using Version = MinVer.Lib.Version; namespace MinVerTests.Lib @@ -13,7 +14,7 @@ public static class MinMajorMinor [Scenario] public static void NoCommits(string path, Version actualVersion) { - $"Given an empty git repository in '{path = GetScenarioDirectory("minimum-major-minor-not-tagged")}'" + $"Given an empty git repository in {path = MethodBase.GetCurrentMethod().GetTestDirectory()}" .x(() => EnsureEmptyRepository(path)); "When the version is determined using minimum major minor '1.2'" @@ -24,12 +25,12 @@ public static void NoCommits(string path, Version actualVersion) } [Scenario] - [Example("2.0.0", 1, 0, "2.0.0", true)] - [Example("2.0.0", 2, 0, "2.0.0", true)] - [Example("2.0.0", 3, 0, "3.0.0-alpha.0", false)] + [Example("4.0.0", 3, 2, "4.0.0", true)] + [Example("4.3.0", 4, 3, "4.3.0", true)] + [Example("4.3.0", 5, 4, "5.4.0-alpha.0", false)] public static void Tagged(string tag, int major, int minor, string expectedVersion, bool isRedundant, string path, TestLogger logger, Version actualVersion) { - $"Given a git repository with a commit in '{path = GetScenarioDirectory($"minimum-major-minor-tagged-{tag}-{major}-{minor}")}'" + $"Given a git repository with a commit in {path = MethodBase.GetCurrentMethod().GetTestDirectory((major, minor))}" .x(() => EnsureEmptyRepositoryAndCommit(path)); $"And the commit is tagged '{tag}'" @@ -51,7 +52,7 @@ public static void Tagged(string tag, int major, int minor, string expectedVersi [Scenario] public static void NotTagged(string path, Version actualVersion) { - $"Given a git repository with a commit in '{path = GetScenarioDirectory("minimum-major-minor-not-tagged")}'" + $"Given a git repository with a commit in {path = MethodBase.GetCurrentMethod().GetTestDirectory()}" .x(() => EnsureEmptyRepositoryAndCommit(path)); "When the version is determined using minimum major minor '1.0'" diff --git a/MinVerTests.Lib/MinVerTests.Lib.csproj b/MinVerTests.Lib/MinVerTests.Lib.csproj index 42eff5f5..c3739c0b 100644 --- a/MinVerTests.Lib/MinVerTests.Lib.csproj +++ b/MinVerTests.Lib/MinVerTests.Lib.csproj @@ -7,13 +7,13 @@ - + diff --git a/MinVerTests.Lib/TagPrefixes.cs b/MinVerTests.Lib/TagPrefixes.cs index 8529f6ee..2706c3c4 100644 --- a/MinVerTests.Lib/TagPrefixes.cs +++ b/MinVerTests.Lib/TagPrefixes.cs @@ -1,9 +1,9 @@ +using System.Reflection; using MinVer.Lib; -using MinVerTests.Lib.Infra; +using MinVerTests.Infra; using Xbehave; using Xunit; -using static MinVerTests.Lib.Infra.FileSystem; -using static MinVerTests.Lib.Infra.Git; +using static MinVerTests.Infra.Git; using Version = MinVer.Lib.Version; namespace MinVerTests.Lib @@ -17,7 +17,7 @@ public static class TagPrefixes [Example("version5.6.7", "version", "5.6.7")] public static void TagPrefix(string tag, string prefix, string expectedVersion, string path, Version actualVersion) { - $"Given a git repository with a commit in '{path = GetScenarioDirectory($"tag-prefixes-{tag}")}'" + $"Given a git repository with a commit in {path = MethodBase.GetCurrentMethod().GetTestDirectory(tag)}" .x(() => EnsureEmptyRepositoryAndCommit(path)); $"And the commit is tagged '{tag}'" diff --git a/MinVerTests.Lib/Versioning.cs b/MinVerTests.Lib/Versioning.cs index 80618159..8fb64fed 100644 --- a/MinVerTests.Lib/Versioning.cs +++ b/MinVerTests.Lib/Versioning.cs @@ -1,13 +1,15 @@ using System; using System.Collections.Generic; +using System.Reflection; using System.Threading.Tasks; +using CliWrap; using MinVer.Lib; +using MinVerTests.Infra; using MinVerTests.Lib.Infra; using Xbehave; using Xunit; -using static MinVerTests.Lib.Infra.FileSystem; -using static MinVerTests.Lib.Infra.Git; -using static SimpleExec.Command; +using static MinVerTests.Infra.FileSystem; +using static MinVerTests.Infra.Git; using Version = MinVer.Lib.Version; namespace MinVerTests.Lib @@ -70,26 +72,26 @@ git tag 1.1.0 -a -m '.' [Example("general")] public static void RepoWithHistory(string name, string path) { - $"Given a git repository in '{path = GetScenarioDirectory("versioning-repo-with-history-" + name)}' with a history of branches and/or tags" + $"Given a git repository with a history of branches and/or tags in {path = MethodBase.GetCurrentMethod().GetTestDirectory(name)}" .x(async () => { - EnsureEmptyRepositoryAndCommit(path); + await EnsureEmptyRepositoryAndCommit(path); foreach (var command in historicalCommands[name].Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)) { var nameAndArgs = command.Split(" ", 2); - await RunAsync(nameAndArgs[0], nameAndArgs[1], path); + await Cli.Wrap(nameAndArgs[0]).WithArguments(nameAndArgs[1]).WithWorkingDirectory(path).ExecuteAsync(); await Task.Delay(200); } }); "When the version is determined for every commit" - .x(() => + .x(async () => { var versionCounts = new Dictionary(); - foreach (var sha in GetCommitShas(path)) + foreach (var sha in await GetCommitShas(path)) { - Checkout(path, sha); + await Checkout(path, sha); var version = Versioner.GetVersion(path, default, default, default, default, default, default); var versionString = version.ToString(); @@ -103,10 +105,10 @@ public static void RepoWithHistory(string name, string path) ? $"v({versionCount})/{versionString}" : tagName; - Tag(path, tagName, sha); + await Tag(path, tagName, sha); } - Checkout(path, "master"); + await Checkout(path, "master"); }); "Then the versions are as expected" @@ -116,7 +118,7 @@ public static void RepoWithHistory(string name, string path) [Scenario] public static void EmptyRepo(string path, Version version) { - $"Given an empty git repository in '{path = GetScenarioDirectory("versioning-empty-repo")}'" + $"Given an empty git repository in {path = MethodBase.GetCurrentMethod().GetTestDirectory()}" .x(() => EnsureEmptyRepository(path)); "When the version is determined" @@ -129,7 +131,7 @@ public static void EmptyRepo(string path, Version version) [Scenario] public static void NoRepo(string path, Version version) { - $"Given an empty directory '{path = GetScenarioDirectory("versioning-no-repo")}'" + $"Given an empty directory {path = MethodBase.GetCurrentMethod().GetTestDirectory()}" .x(() => EnsureEmptyDirectory(path)); "When the version is determined" diff --git a/MinVerTests.Packages/AnnotatedTag.cs b/MinVerTests.Packages/AnnotatedTag.cs new file mode 100644 index 00000000..0050157e --- /dev/null +++ b/MinVerTests.Packages/AnnotatedTag.cs @@ -0,0 +1,32 @@ +using System.Reflection; +using System.Threading.Tasks; +using MinVerTests.Infra; +using Xunit; + +namespace MinVerTests.Packages +{ + public static class AnnotatedTag + { + [Fact] + public static async Task HasTagVersion() + { + // arrange + var path = MethodBase.GetCurrentMethod().GetTestDirectory(); + await Sdk.CreateProject(path); + + await Git.Init(path); + await Git.Commit(path); + await Git.AnnotatedTag(path, "2.3.4-alpha.5+build.6", "foo"); + + var expected = Package.WithVersion(2, 3, 4, new[] { "alpha", "5" }, 0, "build.6"); + + // act + var (sdkActual, _) = await Sdk.BuildProject(path); + var (cliActual, _) = await MinVerCli.Run(path); + + // assert + Assert.Equal(expected, sdkActual); + Assert.Equal(expected.Version, cliActual); + } + } +} diff --git a/MinVerTests.Packages/BuildMetadata.cs b/MinVerTests.Packages/BuildMetadata.cs new file mode 100644 index 00000000..7d4b2672 --- /dev/null +++ b/MinVerTests.Packages/BuildMetadata.cs @@ -0,0 +1,28 @@ +using System.Reflection; +using System.Threading.Tasks; +using MinVerTests.Infra; +using Xunit; + +namespace MinVerTests.Packages +{ + public static class BuildMetadata + { + [Fact] + public static async Task HasBuildMetadata() + { + // arrange + var path = MethodBase.GetCurrentMethod().GetTestDirectory(); + await Sdk.CreateProject(path); + var envVars = ("MinVerBuildMetadata", "build.123"); + var expected = Package.WithVersion(0, 0, 0, new[] { "alpha", "0" }, 0, "build.123"); + + // act + var (sdkActual, _) = await Sdk.BuildProject(path, envVars: envVars); + var (cliActual, _) = await MinVerCli.Run(path, envVars: envVars); + + // assert + Assert.Equal(expected, sdkActual); + Assert.Equal(expected.Version, cliActual); + } + } +} diff --git a/MinVerTests.Packages/CommitAfterPreReleaseTag.cs b/MinVerTests.Packages/CommitAfterPreReleaseTag.cs new file mode 100644 index 00000000..8745bbfc --- /dev/null +++ b/MinVerTests.Packages/CommitAfterPreReleaseTag.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Threading.Tasks; +using MinVerTests.Infra; +using Xunit; + +namespace MinVerTests.Packages +{ + public static class CommitAfterPreReleaseTag + { + [Fact] + public static async Task HasHeightOne() + { + // arrange + var path = MethodBase.GetCurrentMethod().GetTestDirectory(); + await Sdk.CreateProject(path); + + await Git.Init(path); + await Git.Commit(path); + await Git.Tag(path, "2.3.4-alpha.5"); + await Git.Commit(path); + + var expected = Package.WithVersion(2, 3, 4, new[] { "alpha", "5" }, 1); + + // act + var (sdkActual, _) = await Sdk.BuildProject(path); + var (cliActual, _) = await MinVerCli.Run(path); + + // assert + Assert.Equal(expected, sdkActual); + Assert.Equal(expected.Version, cliActual); + } + } +} diff --git a/MinVerTests.Packages/CommitAfterRtmTag.cs b/MinVerTests.Packages/CommitAfterRtmTag.cs new file mode 100644 index 00000000..94ee24cd --- /dev/null +++ b/MinVerTests.Packages/CommitAfterRtmTag.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Threading.Tasks; +using MinVerTests.Infra; +using Xunit; + +namespace MinVerTests.Packages +{ + public static class CommitAfterRtmTag + { + [Fact] + public static async Task HasNextPatchWithHeightOne() + { + // arrange + var path = MethodBase.GetCurrentMethod().GetTestDirectory(); + await Sdk.CreateProject(path); + + await Git.Init(path); + await Git.Commit(path); + await Git.Tag(path, "2.3.4"); + await Git.Commit(path); + + var expected = Package.WithVersion(2, 3, 5, new[] { "alpha", "0" }, 1); + + // act + var (sdkActual, _) = await Sdk.BuildProject(path); + var (cliActual, _) = await MinVerCli.Run(path); + + // assert + Assert.Equal(expected, sdkActual); + Assert.Equal(expected.Version, cliActual); + } + } +} diff --git a/MinVerTests.Packages/CommitAfterTagWithBuildMetadata.cs b/MinVerTests.Packages/CommitAfterTagWithBuildMetadata.cs new file mode 100644 index 00000000..2877eb02 --- /dev/null +++ b/MinVerTests.Packages/CommitAfterTagWithBuildMetadata.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Threading.Tasks; +using MinVerTests.Infra; +using Xunit; + +namespace MinVerTests.Packages +{ + public static class CommitAfterTagWithBuildMetadata + { + [Fact] + public static async Task DoesNotHaveBuildMetadata() + { + // arrange + var path = MethodBase.GetCurrentMethod().GetTestDirectory(); + await Sdk.CreateProject(path); + + await Git.Init(path); + await Git.Commit(path); + await Git.Tag(path, "2.3.4+build.5"); + await Git.Commit(path); + + var expected = Package.WithVersion(2, 3, 5, new[] { "alpha", "0" }, 1); + + // act + var (sdkActual, _) = await Sdk.BuildProject(path); + var (cliActual, _) = await MinVerCli.Run(path); + + // assert + Assert.Equal(expected, sdkActual); + Assert.Equal(expected.Version, cliActual); + } + } +} diff --git a/MinVerTests.Packages/CustomAutoIncrement.cs b/MinVerTests.Packages/CustomAutoIncrement.cs new file mode 100644 index 00000000..339d3092 --- /dev/null +++ b/MinVerTests.Packages/CustomAutoIncrement.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Threading.Tasks; +using MinVerTests.Infra; +using Xunit; + +namespace MinVerTests.Packages +{ + public static class CustomAutoIncrement + { + [Fact] + public static async Task HasCustomAutoIncrement() + { + // arrange + var path = MethodBase.GetCurrentMethod().GetTestDirectory(); + await Sdk.CreateProject(path); + + await Git.Init(path); + await Git.Commit(path); + await Git.Tag(path, "2.3.4"); + await Git.Commit(path); + + var envVars = ("MinVerAutoIncrement".ToAltCase(), "minor"); + + var expected = Package.WithVersion(2, 4, 0, new[] { "alpha", "0" }, 1); + + // act + var (sdkActual, _) = await Sdk.BuildProject(path, envVars: envVars); + var (cliActual, _) = await MinVerCli.Run(path, envVars: envVars); + + // assert + Assert.Equal(expected, sdkActual); + Assert.Equal(expected.Version, cliActual); + } + } +} diff --git a/MinVerTests.Packages/CustomDefaultPreReleasePhase.cs b/MinVerTests.Packages/CustomDefaultPreReleasePhase.cs new file mode 100644 index 00000000..32beac48 --- /dev/null +++ b/MinVerTests.Packages/CustomDefaultPreReleasePhase.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Threading.Tasks; +using MinVerTests.Infra; +using Xunit; + +namespace MinVerTests.Packages +{ + public static class CustomDefaultPreReleasePhase + { + [Fact] + public static async Task HasCustomDefaultPreReleasePhase() + { + // arrange + var path = MethodBase.GetCurrentMethod().GetTestDirectory(); + await Sdk.CreateProject(path); + + await Git.Init(path); + await Git.Commit(path); + await Git.Tag(path, "2.3.4"); + await Git.Commit(path); + + var envVars = ("MinVerDefaultPreReleasePhase".ToAltCase(), "preview"); + + var expected = Package.WithVersion(2, 3, 5, new[] { "preview", "0" }, 1); + + // act + var (sdkActual, _) = await Sdk.BuildProject(path, envVars: envVars); + var (cliActual, _) = await MinVerCli.Run(path, envVars: envVars); + + // assert + Assert.Equal(expected, sdkActual); + Assert.Equal(expected.Version, cliActual); + } + } +} diff --git a/MinVerTests.Packages/EmptyRepo.cs b/MinVerTests.Packages/EmptyRepo.cs new file mode 100644 index 00000000..93757aa1 --- /dev/null +++ b/MinVerTests.Packages/EmptyRepo.cs @@ -0,0 +1,32 @@ +using System; +using System.Reflection; +using System.Threading.Tasks; +using MinVerTests.Infra; +using Xunit; + +namespace MinVerTests.Packages +{ + public static class EmptyRepo + { + [Fact] + public static async Task HasDefaultVersion() + { + // arrange + var path = MethodBase.GetCurrentMethod().GetTestDirectory(); + await Sdk.CreateProject(path); + await Git.Init(path); + var expected = Package.WithVersion(0, 0, 0, new[] { "alpha", "0" }); + + // act + var (sdkActual, sdkOut) = await Sdk.BuildProject(path); + var (cliActual, cliErr) = await MinVerCli.Run(path); + + // assert + Assert.Equal(expected, sdkActual); + Assert.Contains("No commits found", sdkOut, StringComparison.Ordinal); + + Assert.Equal(expected.Version, cliActual); + Assert.Contains("No commits found", cliErr, StringComparison.Ordinal); + } + } +} diff --git a/MinVerTests.Packages/FirstCommit.cs b/MinVerTests.Packages/FirstCommit.cs new file mode 100644 index 00000000..1f74e071 --- /dev/null +++ b/MinVerTests.Packages/FirstCommit.cs @@ -0,0 +1,31 @@ +using System.Reflection; +using System.Threading.Tasks; +using MinVerTests.Infra; +using Xunit; + +namespace MinVerTests.Packages +{ + public static class FirstCommit + { + [Fact] + public static async Task HasDefaultVersion() + { + // arrange + var path = MethodBase.GetCurrentMethod().GetTestDirectory(); + await Sdk.CreateProject(path); + + await Git.Init(path); + await Git.Commit(path); + + var expected = Package.WithVersion(0, 0, 0, new[] { "alpha", "0" }); + + // act + var (sdkActual, _) = await Sdk.BuildProject(path); + var (cliActual, _) = await MinVerCli.Run(path); + + // assert + Assert.Equal(expected, sdkActual); + Assert.Equal(expected.Version, cliActual); + } + } +} diff --git a/MinVerTests.Packages/MinVerTests.Packages.csproj b/MinVerTests.Packages/MinVerTests.Packages.csproj new file mode 100644 index 00000000..83cb2cd1 --- /dev/null +++ b/MinVerTests.Packages/MinVerTests.Packages.csproj @@ -0,0 +1,20 @@ + + + + major + net5.0 + + + + + + + + + + + + + + + diff --git a/MinVerTests.Packages/MinimumMajorMinorAfterTag.cs b/MinVerTests.Packages/MinimumMajorMinorAfterTag.cs new file mode 100644 index 00000000..84142119 --- /dev/null +++ b/MinVerTests.Packages/MinimumMajorMinorAfterTag.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Threading.Tasks; +using MinVerTests.Infra; +using Xunit; + +namespace MinVerTests.Packages +{ + public static class MinimumMajorMinorAfterTag + { + [Fact] + public static async Task HasMinimumMajorMinorWithHeightOne() + { + // arrange + var path = MethodBase.GetCurrentMethod().GetTestDirectory(); + await Sdk.CreateProject(path); + + await Git.Init(path); + await Git.Commit(path); + await Git.Tag(path, "2.3.4"); + await Git.Commit(path); + + var envVars = ("MinVerMinimumMajorMinor".ToAltCase(), "3.0"); + + var expected = Package.WithVersion(3, 0, 0, new[] { "alpha", "0" }, 1); + + // act + var (sdkActual, _) = await Sdk.BuildProject(path, envVars: envVars); + var (cliActual, _) = await MinVerCli.Run(path, envVars: envVars); + + // assert + Assert.Equal(expected, sdkActual); + Assert.Equal(expected.Version, cliActual); + } + } +} diff --git a/MinVerTests.Packages/MinimumMajorMinorOnTag.cs b/MinVerTests.Packages/MinimumMajorMinorOnTag.cs new file mode 100644 index 00000000..e91ca717 --- /dev/null +++ b/MinVerTests.Packages/MinimumMajorMinorOnTag.cs @@ -0,0 +1,34 @@ +using System.Reflection; +using System.Threading.Tasks; +using MinVerTests.Infra; +using Xunit; + +namespace MinVerTests.Packages +{ + public static class MinimumMajorMinorOnTag + { + [Fact] + public static async Task HasMinimumMajorMinor() + { + // arrange + var path = MethodBase.GetCurrentMethod().GetTestDirectory(); + await Sdk.CreateProject(path); + + await Git.Init(path); + await Git.Commit(path); + await Git.Tag(path, "2.3.4"); + + var envVars = ("MinVerMinimumMajorMinor".ToAltCase(), "3.0"); + + var expected = Package.WithVersion(3, 0, 0, new[] { "alpha", "0" }); + + // act + var (sdkActual, _) = await Sdk.BuildProject(path, envVars: envVars); + var (cliActual, _) = await MinVerCli.Run(path, envVars: envVars); + + // assert + Assert.Equal(expected, sdkActual); + Assert.Equal(expected.Version, cliActual); + } + } +} diff --git a/MinVerTests.Packages/NoRepo.cs b/MinVerTests.Packages/NoRepo.cs new file mode 100644 index 00000000..b10c4a5c --- /dev/null +++ b/MinVerTests.Packages/NoRepo.cs @@ -0,0 +1,31 @@ +using System; +using System.Reflection; +using System.Threading.Tasks; +using MinVerTests.Infra; +using Xunit; + +namespace MinVerTests.Packages +{ + public static class NoRepo + { + [Fact] + public static async Task HasDefaultVersion() + { + // arrange + var path = MethodBase.GetCurrentMethod().GetTestDirectory(); + await Sdk.CreateProject(path); + var expected = Package.WithVersion(0, 0, 0, new[] { "alpha", "0" }); + + // act + var (sdkActual, sdkOut) = await Sdk.BuildProject(path); + var (cliActual, cliErr) = await MinVerCli.Run(path); + + // assert + Assert.Equal(expected, sdkActual); + Assert.Contains("MINVER1001", sdkOut, StringComparison.Ordinal); + + Assert.Equal(expected.Version, cliActual); + Assert.Contains("not a valid Git working directory", cliErr, StringComparison.Ordinal); + } + } +} diff --git a/MinVerTests.Packages/NonVersionTag.cs b/MinVerTests.Packages/NonVersionTag.cs new file mode 100644 index 00000000..5f4a8c4f --- /dev/null +++ b/MinVerTests.Packages/NonVersionTag.cs @@ -0,0 +1,32 @@ +using System.Reflection; +using System.Threading.Tasks; +using MinVerTests.Infra; +using Xunit; + +namespace MinVerTests.Packages +{ + public static class NonVersionTag + { + [Fact] + public static async Task HasDefaultVersion() + { + // arrange + var path = MethodBase.GetCurrentMethod().GetTestDirectory(); + await Sdk.CreateProject(path); + + await Git.Init(path); + await Git.Commit(path); + await Git.Tag(path, "foo"); + + var expected = Package.WithVersion(0, 0, 0, new[] { "alpha", "0" }); + + // act + var (sdkActual, _) = await Sdk.BuildProject(path); + var (cliActual, _) = await MinVerCli.Run(path); + + // assert + Assert.Equal(expected, sdkActual); + Assert.Equal(expected.Version, cliActual); + } + } +} diff --git a/MinVerTests.Packages/OutputVariables.cs b/MinVerTests.Packages/OutputVariables.cs new file mode 100644 index 00000000..1809d4a4 --- /dev/null +++ b/MinVerTests.Packages/OutputVariables.cs @@ -0,0 +1,34 @@ +using System.Reflection; +using System.Threading.Tasks; +using MinVerTests.Infra; +using Xunit; + +namespace MinVerTests.Packages +{ + public static class OutputVariables + { + [Fact] + public static async Task AreSet() + { + // arrange + var path = MethodBase.GetCurrentMethod().GetTestDirectory(); + await Sdk.CreateProject(path); + var envVars = ("MinVerVersionOverride".ToAltCase(), "2.3.4-alpha.5+build.6"); + + // act + var (_, @out) = await Sdk.BuildProject(path, envVars: envVars); + + // assert + Assert.Contains("MinVer: [output] MinVerVersion=2.3.4-alpha.5+build.6", @out); + Assert.Contains("MinVer: [output] MinVerMajor=2", @out); + Assert.Contains("MinVer: [output] MinVerMinor=3", @out); + Assert.Contains("MinVer: [output] MinVerPatch=4", @out); + Assert.Contains("MinVer: [output] MinVerPreRelease=alpha.5", @out); + Assert.Contains("MinVer: [output] MinVerBuildMetadata=build.6", @out); + Assert.Contains("MinVer: [output] AssemblyVersion=2.0.0.0", @out); + Assert.Contains("MinVer: [output] FileVersion=2.3.4.0", @out); + Assert.Contains("MinVer: [output] PackageVersion=2.3.4-alpha.5+build.6", @out); + Assert.Contains("MinVer: [output] Version=2.3.4-alpha.5+build.6", @out); + } + } +} diff --git a/MinVerTests.Packages/PreReleaseTag.cs b/MinVerTests.Packages/PreReleaseTag.cs new file mode 100644 index 00000000..b1b42313 --- /dev/null +++ b/MinVerTests.Packages/PreReleaseTag.cs @@ -0,0 +1,32 @@ +using System.Reflection; +using System.Threading.Tasks; +using MinVerTests.Infra; +using Xunit; + +namespace MinVerTests.Packages +{ + public static class PreReleaseTag + { + [Fact] + public static async Task HasTagVersion() + { + // arrange + var path = MethodBase.GetCurrentMethod().GetTestDirectory(); + await Sdk.CreateProject(path); + + await Git.Init(path); + await Git.Commit(path); + await Git.Tag(path, "2.3.4-alpha.5"); + + var expected = Package.WithVersion(2, 3, 4, new[] { "alpha", "5" }); + + // act + var (sdkActual, _) = await Sdk.BuildProject(path); + var (cliActual, _) = await MinVerCli.Run(path); + + // assert + Assert.Equal(expected, sdkActual); + Assert.Equal(expected.Version, cliActual); + } + } +} diff --git a/MinVerTests.Packages/RtmTag.cs b/MinVerTests.Packages/RtmTag.cs new file mode 100644 index 00000000..81aa9a4f --- /dev/null +++ b/MinVerTests.Packages/RtmTag.cs @@ -0,0 +1,32 @@ +using System.Reflection; +using System.Threading.Tasks; +using MinVerTests.Infra; +using Xunit; + +namespace MinVerTests.Packages +{ + public static class RtmTag + { + [Fact] + public static async Task HasTagVersion() + { + // arrange + var path = MethodBase.GetCurrentMethod().GetTestDirectory(); + await Sdk.CreateProject(path); + + await Git.Init(path); + await Git.Commit(path); + await Git.Tag(path, "2.3.4"); + + var expected = Package.WithVersion(2, 3, 4); + + // act + var (sdkActual, _) = await Sdk.BuildProject(path); + var (cliActual, _) = await MinVerCli.Run(path); + + // assert + Assert.Equal(expected, sdkActual); + Assert.Equal(expected.Version, cliActual); + } + } +} diff --git a/MinVerTests.Packages/Skip.cs b/MinVerTests.Packages/Skip.cs new file mode 100644 index 00000000..0730850f --- /dev/null +++ b/MinVerTests.Packages/Skip.cs @@ -0,0 +1,26 @@ +using System.Reflection; +using System.Threading.Tasks; +using MinVerTests.Infra; +using Xunit; + +namespace MinVerTests.Packages +{ + public static class Skip + { + [Fact] + public static async Task HasDefaultSdkVersion() + { + // arrange + var path = MethodBase.GetCurrentMethod().GetTestDirectory(); + await Sdk.CreateProject(path); + var envVars = ("MinVerSkip".ToAltCase(), "true"); + var expected = Package.WithVersion(1, 0, 0); + + // act + var (actual, _) = await Sdk.BuildProject(path, envVars: envVars); + + // assert + Assert.Equal(expected, actual); + } + } +} diff --git a/MinVerTests.Packages/TagWithBuildMetadata.cs b/MinVerTests.Packages/TagWithBuildMetadata.cs new file mode 100644 index 00000000..4db69220 --- /dev/null +++ b/MinVerTests.Packages/TagWithBuildMetadata.cs @@ -0,0 +1,32 @@ +using System.Reflection; +using System.Threading.Tasks; +using MinVerTests.Infra; +using Xunit; + +namespace MinVerTests.Packages +{ + public static class TagWithBuildMetadata + { + [Fact] + public static async Task HasTagVersion() + { + // arrange + var path = MethodBase.GetCurrentMethod().GetTestDirectory(); + await Sdk.CreateProject(path); + + await Git.Init(path); + await Git.Commit(path); + await Git.Tag(path, "2.3.4-alpha.5+build.6"); + + var expected = Package.WithVersion(2, 3, 4, new[] { "alpha", "5" }, 0, "build.6"); + + // act + var (sdkActual, _) = await Sdk.BuildProject(path); + var (cliActual, _) = await MinVerCli.Run(path); + + // assert + Assert.Equal(expected, sdkActual); + Assert.Equal(expected.Version, cliActual); + } + } +} diff --git a/MinVerTests.Packages/TagWithPrefix.cs b/MinVerTests.Packages/TagWithPrefix.cs new file mode 100644 index 00000000..b04aff60 --- /dev/null +++ b/MinVerTests.Packages/TagWithPrefix.cs @@ -0,0 +1,34 @@ +using System.Reflection; +using System.Threading.Tasks; +using MinVerTests.Infra; +using Xunit; + +namespace MinVerTests.Packages +{ + public static class TagWithPrefix + { + [Fact] + public static async Task HasTagVersion() + { + // arrange + var path = MethodBase.GetCurrentMethod().GetTestDirectory(); + await Sdk.CreateProject(path); + + await Git.Init(path); + await Git.Commit(path); + await Git.Tag(path, "v.2.3.4-alpha.5"); + + var envVars = ("MinVerTagPrefix", "v."); + + var expected = Package.WithVersion(2, 3, 4, new[] { "alpha", "5" }); + + // act + var (sdkActual, _) = await Sdk.BuildProject(path, envVars: envVars); + var (cliActual, _) = await MinVerCli.Run(path, envVars: envVars); + + // assert + Assert.Equal(expected, sdkActual); + Assert.Equal(expected.Version, cliActual); + } + } +} diff --git a/MinVerTests.Packages/TwoCommitsAfterPreReleaseTag.cs b/MinVerTests.Packages/TwoCommitsAfterPreReleaseTag.cs new file mode 100644 index 00000000..8a8a8b08 --- /dev/null +++ b/MinVerTests.Packages/TwoCommitsAfterPreReleaseTag.cs @@ -0,0 +1,34 @@ +using System.Reflection; +using System.Threading.Tasks; +using MinVerTests.Infra; +using Xunit; + +namespace MinVerTests.Packages +{ + public static class TwoCommitsAfterPreReleaseTag + { + [Fact] + public static async Task HasHeightTwo() + { + // arrange + var path = MethodBase.GetCurrentMethod().GetTestDirectory(); + await Sdk.CreateProject(path); + + await Git.Init(path); + await Git.Commit(path); + await Git.Tag(path, "2.3.4-alpha.5"); + await Git.Commit(path); + await Git.Commit(path); + + var expected = Package.WithVersion(2, 3, 4, new[] { "alpha", "5" }, 2); + + // act + var (sdkActual, _) = await Sdk.BuildProject(path); + var (cliActual, _) = await MinVerCli.Run(path); + + // assert + Assert.Equal(expected, sdkActual); + Assert.Equal(expected.Version, cliActual); + } + } +} diff --git a/MinVerTests.Packages/TwoCommitsAfterRtmTag.cs b/MinVerTests.Packages/TwoCommitsAfterRtmTag.cs new file mode 100644 index 00000000..3e07e90c --- /dev/null +++ b/MinVerTests.Packages/TwoCommitsAfterRtmTag.cs @@ -0,0 +1,34 @@ +using System.Reflection; +using System.Threading.Tasks; +using MinVerTests.Infra; +using Xunit; + +namespace MinVerTests.Packages +{ + public static class TwoCommitsAfterRtmTag + { + [Fact] + public static async Task HasNextPatchWithHeightTwo() + { + // arrange + var path = MethodBase.GetCurrentMethod().GetTestDirectory(); + await Sdk.CreateProject(path); + + await Git.Init(path); + await Git.Commit(path); + await Git.Tag(path, "2.3.4"); + await Git.Commit(path); + await Git.Commit(path); + + var expected = Package.WithVersion(2, 3, 5, new[] { "alpha", "0" }, 2); + + // act + var (sdkActual, _) = await Sdk.BuildProject(path); + var (cliActual, _) = await MinVerCli.Run(path); + + // assert + Assert.Equal(expected, sdkActual); + Assert.Equal(expected.Version, cliActual); + } + } +} diff --git a/MinVerTests.Packages/VersionOverride.cs b/MinVerTests.Packages/VersionOverride.cs new file mode 100644 index 00000000..a9d10e81 --- /dev/null +++ b/MinVerTests.Packages/VersionOverride.cs @@ -0,0 +1,34 @@ +using System.Reflection; +using System.Threading.Tasks; +using MinVerTests.Infra; +using Xunit; + +namespace MinVerTests.Packages +{ + public static class VersionOverride + { + [Fact] + public static async Task HasVersionOverride() + { + // arrange + var path = MethodBase.GetCurrentMethod().GetTestDirectory(); + await Sdk.CreateProject(path); + + await Git.Init(path); + await Git.Commit(path); + await Git.Tag(path, "2.3.4"); + + var envVars = ("MinVerVersionOverride".ToAltCase(), "3.4.5-alpha.6+build.7"); + + var expected = Package.WithVersion(3, 4, 5, new[] { "alpha", "6" }, 0, "build.7"); + + // act + var (sdkActual, _) = await Sdk.BuildProject(path, envVars: envVars); + var (cliActual, _) = await MinVerCli.Run(path, envVars: envVars); + + // assert + Assert.Equal(expected, sdkActual); + Assert.Equal(expected.Version, cliActual); + } + } +} diff --git a/targets/Program.cs b/targets/Program.cs index ebf09b7b..2b5ad870 100644 --- a/targets/Program.cs +++ b/targets/Program.cs @@ -1,397 +1,77 @@ using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.IO.Compression; -using System.Linq; -using System.Reflection; -using System.Runtime.Loader; -using System.Threading.Tasks; -using Xunit; +using MinVerTests.Infra; using static Bullseye.Targets; -using static MinVerTests.Lib.Infra.FileSystem; -using static MinVerTests.Lib.Infra.Git; using static SimpleExec.Command; -var sdk = Environment.GetEnvironmentVariable("MINVER_TESTS_SDK"); -var testPackageBaseOutput = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); -var buildNumber = 1; - Target("build", () => RunAsync("dotnet", "build --configuration Release --nologo --verbosity quiet")); Target( "test-lib", "test the MinVer.Lib library", DependsOn("build"), - () => RunAsync("dotnet", $"test --framework {Environment.GetEnvironmentVariable("MINVER_TESTS_FRAMEWORK") ?? "net5.0"} --configuration Release --no-build --nologo")); - -string testProject = default; + () => RunAsync("dotnet", $"test ./MinVerTests.Lib --framework {Environment.GetEnvironmentVariable("MINVER_TESTS_FRAMEWORK") ?? "net5.0"} --configuration Release --no-build --nologo")); Target( - "create-test-project", + "test-packages", + "test the MinVer package and the minver-cli console app", DependsOn("build"), - async () => - { - testProject = GetScenarioDirectory("package"); - EnsureEmptyDirectory(testProject); - - var source = Path.GetFullPath("./MinVer/bin/Release/"); - var version = Path.GetFileNameWithoutExtension(Directory.EnumerateFiles(source, "*.nupkg").First()).Split("MinVer.", 2)[1]; - - if (!string.IsNullOrWhiteSpace(sdk)) - { - File.WriteAllText( - Path.Combine(testProject, "global.json"), -$@"{{ -{" "}""sdk"": {{ -{" "}""version"": ""{sdk.Trim()}"", -{" "}""rollForward"": ""disable"" -{" "}}} -}} -"); - } - - await RunAsync("dotnet", "new classlib", testProject); - await RunAsync("dotnet", $"add package MinVer --source {source} --version {version} --package-directory packages", testProject); - await RunAsync("dotnet", $"restore --source {source} --packages packages", testProject); - }); - -Target( - "test-package-no-repo", - DependsOn("create-test-project"), - async () => - { - // arrange - var output = Path.Combine(testPackageBaseOutput, $"{buildNumber}-test-package-no-repo"); - - // act - await CleanAndPack(testProject, output, "diagnostic", sdk); - - // assert - AssertVersion(new Version(0, 0, 0, new[] { "alpha", "0" }), output); - - // cli - Assert.Equal($"0.0.0-alpha.0+build.{buildNumber}", await RunCliAsync(testProject, "trace")); - }); - -Target( - "test-package-no-commits", - DependsOn("test-package-no-repo"), - async () => - { - // arrange - Init(testProject); - - var output = Path.Combine(testPackageBaseOutput, $"{buildNumber}-test-package-no-commits"); - - // act - await CleanAndPack(testProject, output, "diagnostic", sdk); - - // assert - AssertVersion(new Version(0, 0, 0, new[] { "alpha", "0" }), output); - - // cli - Assert.Equal($"0.0.0-alpha.0+build.{buildNumber}", await RunCliAsync(testProject, "trace")); - }); - -Target( - "test-package-commit", - DependsOn("test-package-no-commits"), - async () => - { - // arrange - PrepareForCommits(testProject); - Commit(testProject); - - var output = Path.Combine(testPackageBaseOutput, $"{buildNumber}-test-package-commit"); - - // act - await CleanAndPack(testProject, output, "diagnostic", sdk); - - // assert - AssertVersion(new Version(0, 0, 0, new[] { "alpha", "0" }), output); - - // cli - Assert.Equal($"0.0.0-alpha.0+build.{buildNumber}", await RunCliAsync(testProject, "trace")); - }); - -Target( - "test-package-non-version-tag", - DependsOn("test-package-commit"), - async () => - { - // arrange - Tag(testProject, "foo"); - - var output = Path.Combine(testPackageBaseOutput, $"{buildNumber}-test-package-non-version-tag"); - - // act - await CleanAndPack(testProject, output, "diagnostic", sdk); - - // assert - AssertVersion(new Version(0, 0, 0, new[] { "alpha", "0" }), output); - - // cli - Assert.Equal($"0.0.0-alpha.0+build.{buildNumber}", await RunCliAsync(testProject, "trace")); - }); - -Target( - "test-package-version-tag", - DependsOn("test-package-non-version-tag"), - async () => - { - // arrange - Tag(testProject, "v.1.2.3+foo"); - - var output = Path.Combine(testPackageBaseOutput, $"{buildNumber}-test-package-version-tag"); - - // act - await CleanAndPack(testProject, output, "normal", sdk, env => env.Add(AltCase("MinVerTagPrefix"), "v.")); - - // assert - AssertVersion(new Version(1, 2, 3, default, default, "foo"), output); - - // cli - Assert.Equal($"1.2.3+foo.build.{buildNumber}", await RunCliAsync(testProject, "info", env => env.Add(AltCase("MinVerTagPrefix"), "v."))); - }); - -Target( - "test-package-commit-after-tag", - DependsOn("test-package-version-tag"), - async () => - { - // arrange - Tag(testProject, "1.2.3+foo"); - Commit(testProject); - - var output = Path.Combine(testPackageBaseOutput, $"{buildNumber}-test-package-commit-after-tag"); - - // act - await CleanAndPack(testProject, output, "detailed", sdk); - - // assert - AssertVersion(new Version(1, 2, 4, new[] { "alpha", "0" }, 1), output); - - // cli - Assert.Equal($"1.2.4-alpha.0.1+build.{buildNumber}", await RunCliAsync(testProject, "debug")); - }); - -Target( - "test-package-non-default-auto-increment", - DependsOn("test-package-commit-after-tag"), - async () => - { - // arrange - var output = Path.Combine(testPackageBaseOutput, $"{buildNumber}-test-package-non-default-auto-increment"); - - // act - await CleanAndPack(testProject, output, "diagnostic", sdk, env => env.Add(AltCase("MinVerAutoIncrement"), "minor")); - - // assert - AssertVersion(new Version(1, 3, 0, new[] { "alpha", "0" }, 1), output); - - // cli - Assert.Equal($"1.3.0-alpha.0.1+build.{buildNumber}", await RunCliAsync(testProject, "trace", env => env.Add(AltCase("MinVerAutoIncrement"), "minor"))); - }); - -Target( - "test-package-annotated-tag", - DependsOn("test-package-non-default-auto-increment"), - async () => - { - // arrange - AnnotatedTag(testProject, "1.4.0", "foo"); - - var output = Path.Combine(testPackageBaseOutput, $"{buildNumber}-test-package-annotated-tag"); - - // act - await CleanAndPack(testProject, output, "diagnostic", sdk); - - // assert - AssertVersion(new Version(1, 4, 0), output); - - // cli - Assert.Equal($"1.4.0+build.{buildNumber}", await RunCliAsync(testProject, "trace")); - }); - -Target( - "test-package-minimum-major-minor-on-tag", - DependsOn("test-package-annotated-tag"), - async () => - { - // arrange - Commit(testProject); - Tag(testProject, "1.5.0"); - - var output = Path.Combine(testPackageBaseOutput, $"{buildNumber}-test-package-minimum-major-minor-on-tag"); - - // act - await CleanAndPack(testProject, output, "diagnostic", sdk, env => env.Add(AltCase("MinVerMinimumMajorMinor"), "2.0")); - - // assert - AssertVersion(new Version(2, 0, 0, new[] { "alpha", "0" }), output); - - // cli - Assert.Equal($"2.0.0-alpha.0+build.{buildNumber}", await RunCliAsync(testProject, "trace", env => env.Add(AltCase("MinVerMinimumMajorMinor"), "2.0"))); - }); - -Target( - "test-package-minimum-major-minor-after-tag", - DependsOn("test-package-minimum-major-minor-on-tag"), - async () => - { - // arrange - Commit(testProject); - - var output = Path.Combine(testPackageBaseOutput, $"{buildNumber}-test-package-minimum-major-minor-after-tag"); - - // act - await CleanAndPack(testProject, output, "diagnostic", sdk, env => env.Add(AltCase("MinVerMinimumMajorMinor"), "2.0")); - - // assert - AssertVersion(new Version(2, 0, 0, new[] { "alpha", "0" }, 1), output); - - // cli - Assert.Equal($"2.0.0-alpha.0.1+build.{buildNumber}", await RunCliAsync(testProject, "trace", env => env.Add(AltCase("MinVerMinimumMajorMinor"), "2.0"))); - }); + () => RunAsync("dotnet", "test ./MinVerTests.Packages --configuration Release --no-build --nologo --verbosity normal")); Target( - "test-package-default-pre-release-phase", - DependsOn("test-package-minimum-major-minor-after-tag"), - async () => - { - // arrange - var output = Path.Combine(testPackageBaseOutput, $"{buildNumber}-test-package-default-pre-release-phase"); - - // act - await CleanAndPack(testProject, output, "diagnostic", sdk, env => env.Add(AltCase("MinVerDefaultPreReleasePhase"), "preview")); - - // assert - AssertVersion(new Version(1, 5, 1, new[] { "preview", "0" }, 1), output); - - // cli - Assert.Equal($"1.5.1-preview.0.1+build.{buildNumber}", await RunCliAsync(testProject, "trace", env => env.Add(AltCase("MinVerDefaultPreReleasePhase"), "preview"))); - }); - -Target( - "test-package-version-override", - DependsOn("test-package-default-pre-release-phase"), + "eyeball-minver-logs", + "build a test project with the MinVer package to eyeball the diagnostic logs", + DependsOn("build"), async () => { - // arrange - var output = Path.Combine(testPackageBaseOutput, $"{buildNumber}-test-package-version-override"); - - // act - await CleanAndPack(testProject, output, "diagnostic", sdk, env => env.Add(AltCase("MinVerVersionOverride"), "3.2.1-rc.4+build.5")); - - // assert - AssertVersion(new Version(3, 2, 1, new[] { "rc", "4" }, default, "build.5"), output); - - // cli - Assert.Equal("3.2.1-rc.4+build.5", await RunCliAsync(testProject, "trace", env => env.Add(AltCase("MinVerVersionOverride"), "3.2.1-rc.4+build.5"))); + var path = TestDirectory.Get("MinVer.Targets", "eyeball-minver-logs"); + + await Sdk.CreateProject(path, "Release"); + + await Git.Init(path); + await Git.Commit(path); + await Git.Tag(path, "v.2.3.4-alpha.5"); + await Git.Commit(path); + + await RunAsync( + "dotnet", + $"build --no-restore{((Sdk.Version?.StartsWith("2.") ?? false) ? "" : " --nologo")}", + path, + configureEnvironment: env => + { + env.Add("MinVerBuildMetadata", "build.6"); + env.Add("MinVerTagPrefix", "v."); + env.Add("MinVerVerbosity", "diagnostic"); + }); }); Target( - "test-package-skip", - DependsOn("test-package-version-override"), + "eyeball-minver-cli-logs", + "run the minver-cli console app on a test directory to eyeball the trace logs", + DependsOn("build"), async () => { - // arrange - var output = Path.Combine(testPackageBaseOutput, $"{buildNumber}-test-package-skip"); - - // act - await CleanAndPack(testProject, output, "diagnostic", sdk, env => env.Add(AltCase("MinVerSkip"), "true")); - - // assert - AssertVersion(new Version(1, 0, 0), output); + var path = TestDirectory.Get("MinVer.Targets", "eyeball-minver-cli-logs"); + + FileSystem.EnsureEmptyDirectory(path); + + await Git.Init(path); + await Git.Commit(path); + await Git.Tag(path, "v.2.3.4-alpha.5"); + await Git.Commit(path); + + await RunAsync( + "dotnet", + $"exec {MinVerCli.GetPath("Release")} {path}", + configureEnvironment: env => + { + env.Add("MinVerBuildMetadata", "build.6"); + env.Add("MinVerTagPrefix", "v."); + env.Add("MinVerVerbosity", "trace"); + }); }); -Target("test-package", "test the MinVer package and the minver-cli console app", DependsOn("test-package-skip")); - -Target("default", DependsOn("test-lib", "test-package")); - -RunTargetsAndExit(args); - -async Task CleanAndPack(string path, string output, string verbosity, string packageTestsSdk, Action> configureEnvironment = null) -{ - EnsureEmptyDirectory(output); - - var noLogo = (packageTestsSdk?.StartsWith("2.") ?? false) ? "" : " --nologo"; - - await RunAsync("dotnet", $"build --no-restore{noLogo}", path, configureEnvironment: configureEnvironment); - await RunAsync( - "dotnet", - $"pack --no-build --output {output}{noLogo}", - path, - configureEnvironment: env => - { - configureEnvironment?.Invoke(env); - env.Add(AltCase("MinVerBuildMetadata"), $"build.{buildNumber++}"); - env.Add(AltCase("MinVerVerbosity"), verbosity ?? ""); - env.Add("NoPackageAnalysis", "true"); - }); -} - -static void AssertVersion(Version expected, string path) -{ - var packagePath = Directory.EnumerateFiles(path, "*.nupkg", new EnumerationOptions { RecurseSubdirectories = true }) - .First(); - - Assert.EndsWith(expected.ToString().Split('+')[0], Path.GetFileNameWithoutExtension(packagePath)); - - ZipFile.ExtractToDirectory( - packagePath, - Path.Combine(Path.GetDirectoryName(packagePath), Path.GetFileNameWithoutExtension(packagePath))); - - var assemblyPath = Directory.EnumerateFiles(path, "*.dll", new EnumerationOptions { RecurseSubdirectories = true }) - .First(); - - var context = new AssemblyLoadContext(default, true); - var assembly = context.LoadFromAssemblyPath(assemblyPath); - var assemblyVersion = assembly.GetName().Version; - context.Unload(); - - var fileVersion = FileVersionInfo.GetVersionInfo(assemblyPath); - - Assert.Equal(expected.Major, assemblyVersion.Major); - Assert.Equal(0, assemblyVersion.Minor); - Assert.Equal(0, assemblyVersion.Build); - - Assert.Equal(expected.Major, fileVersion.FileMajorPart); - Assert.Equal(expected.Minor, fileVersion.FileMinorPart); - Assert.Equal(expected.Patch, fileVersion.FileBuildPart); - - Assert.Equal(expected.ToString(), fileVersion.ProductVersion); -} - -async Task RunCliAsync(string repo, string verbosity, Action> configureEnvironment = null) => - (await ReadAsync( - "dotnet", - $"exec ./minver-cli/bin/Release/netcoreapp2.1/minver-cli.dll {repo}", - configureEnvironment: env => - { - configureEnvironment?.Invoke(env); - env.Add(AltCase("MinVerBuildMetadata"), $"build.{buildNumber}"); - env.Add(AltCase("MinVerVerbosity"), verbosity ?? ""); - })).Trim(); - -static string AltCase(string value) => new string(value.Select((c, i) => i % 2 == 0 ? c.ToString().ToLowerInvariant()[0] : c.ToString().ToUpperInvariant()[0]).ToArray()); - -#pragma warning disable format -public record Version -{ - public Version(int major, int minor, int patch, IEnumerable preReleaseIdentifiers = null, int height = 0, string buildMetadata = null) => - (this.Major, this.Minor, this.Patch, this.PreReleaseIdentifiers, this.Height, this.BuildMetadata) = - (major, minor, patch, preReleaseIdentifiers?.ToList() ?? new List(), height, buildMetadata); +Target("eyeball-logs", DependsOn("eyeball-minver-logs", "eyeball-minver-cli-logs")); - public int Major { get; } - public int Minor { get; } - public int Patch { get; } - private List PreReleaseIdentifiers { get; } - private int Height { get; } - private string BuildMetadata { get; } +Target("default", DependsOn("test-lib", "test-packages", "eyeball-logs")); - public override string ToString() => - $"{this.Major}.{this.Minor}.{this.Patch}{(this.PreReleaseIdentifiers.Count == 0 ? "" : $"-{string.Join(".", this.PreReleaseIdentifiers)}")}{(this.Height == 0 ? "" : $".{this.Height}")}{(string.IsNullOrEmpty(this.BuildMetadata) ? "" : $"+{this.BuildMetadata}")}"; -} -#pragma warning restore format +await RunTargetsAndExitAsync(args, ex => ex is SimpleExec.NonZeroExitCodeException); diff --git a/targets/Targets.csproj b/targets/Targets.csproj index 588cd025..43dd3ecf 100644 --- a/targets/Targets.csproj +++ b/targets/Targets.csproj @@ -1,4 +1,4 @@ - + Exe @@ -7,14 +7,12 @@ - - + + - - - +