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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions src/GitVersion.App.Tests/ArgumentParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,53 @@ public void OverrideConfigBatchValidationDoesNotApplyAnyValues()
parser.GetOverrideConfiguration().ShouldBeEmpty();
}

[Test]
public void ConfigMigrateParsesItsInputAndOutputOptions()
{
var arguments = this.argumentParser.ParseArguments(
"config migrate --config GitVersion.yml --output GitVersion.v7.yml --force");

arguments.IsConfigurationMigration.ShouldBeTrue();
arguments.MigrationInputFile.ShouldBe("GitVersion.yml");
arguments.MigrationOutputFile.ShouldBe("GitVersion.v7.yml");
arguments.MigrationForce.ShouldBeTrue();
}

[Test]
public void ConfigMigrateUsesPositionalTargetPath()
{
var arguments = this.argumentParser.ParseArguments("path config migrate --in-place");

arguments.IsConfigurationMigration.ShouldBeTrue();
arguments.TargetPath.ShouldBe("path");
}

[Test]
public void ConfigMigrateRejectsOutputAndInPlaceTogether()
{
var exception = Should.Throw<WarningException>(() =>
this.argumentParser.ParseArguments("config migrate --output GitVersion.v7.yml --in-place"));

exception.Message.ShouldBe("Cannot use --output together with --in-place.");
}

[Test]
public void ConfigRequiresASubcommand()
{
var exception = Should.Throw<WarningException>(() => this.argumentParser.ParseArguments("config"));

exception.Message.ShouldBe("The 'config' command requires a subcommand. Use 'gitversion config migrate'.");
}

[Test]
public void TargetPathAllowsDirectoryNamedConfig()
{
var arguments = this.argumentParser.ParseArguments("--target-path config");

arguments.TargetPath.ShouldBe("config");
arguments.IsConfigurationMigration.ShouldBeFalse();
}

[Test]
public void EmptyMeansUseCurrentDirectory()
{
Expand Down
39 changes: 39 additions & 0 deletions src/GitVersion.App.Tests/ConfigurationMigrationExecutorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System.IO.Abstractions;
using GitVersion.Configuration;
using GitVersion.Tests;

namespace GitVersion.App.Tests;

[TestFixture]
public class ConfigurationMigrationExecutorTests
{
[Test]
public void InPlaceMigrationWarnsThatCommentsCannotBePreserved()
{
var directory = Directory.CreateTempSubdirectory();
try
{
var inputFile = Path.Combine(directory.FullName, "legacy.yml");
File.WriteAllText(inputFile, "next-version: 2.0.0");
var logMessages = new List<string>();
var executor = new ConfigurationMigrationExecutor(
new FileSystem(),
new TestConsoleAdapter(new StringBuilder()),
new TestLogger<ConfigurationMigrationExecutor>(logMessages.Add),
Substitute.For<IConfigurationFileLocator>(),
new ConfigurationMigrationService(new ConfigurationSerializer()));
var options = new GitVersionOptions { WorkingDirectory = directory.FullName };
options.ConfigurationMigrationInfo.IsMigration = true;
options.ConfigurationMigrationInfo.InputFile = inputFile;
options.ConfigurationMigrationInfo.InPlace = true;

executor.Execute(options).ShouldBe(0);

logMessages.ShouldContain(message => message.Contains("Comments cannot be preserved during migration.", StringComparison.Ordinal));
}
finally
{
directory.Delete(recursive: true);
}
}
}
155 changes: 155 additions & 0 deletions src/GitVersion.App.Tests/ConfigurationVersionIntegrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,163 @@
namespace GitVersion.App.Tests;

[TestFixture]
[NonParallelizable]
public class ConfigurationVersionIntegrationTests
{
[Test]
public async Task ConfigMigrateWritesMigratedConfigurationToStandardOutput()
{
var directory = Directory.CreateTempSubdirectory();
try
{
var configurationPath = Path.Combine(directory.FullName, ConfigurationFileLocator.DefaultFileName);
await File.WriteAllTextAsync(configurationPath, "next-version: 2.0.0");

var result = await new ProgramFixture(directory.FullName).Run("config", "migrate");

result.ExitCode.ShouldBe(0);
result.Output.ShouldNotBeNull();
result.Output.ShouldContain("calculation:");
result.Output.ShouldContain("next-version: 2.0.0");
result.Output.ShouldContain("output: {}");
}
finally
{
directory.Delete(recursive: true);
}
}

[Test]
public async Task ConfigMigrateDoesNotOverwriteOutputWithoutForce()
{
var directory = Directory.CreateTempSubdirectory();
try
{
var configurationPath = Path.Combine(directory.FullName, ConfigurationFileLocator.DefaultFileName);
var outputPath = Path.Combine(directory.FullName, "GitVersion.v7.yml");
await File.WriteAllTextAsync(configurationPath, "next-version: 2.0.0");
await File.WriteAllTextAsync(outputPath, "existing configuration");

var result = await new ProgramFixture(directory.FullName).Run("config", "migrate", "--output", "GitVersion.v7.yml");

result.ExitCode.ShouldBe(1);
result.Output.ShouldBeEmpty();
var output = await File.ReadAllTextAsync(outputPath);
output.ShouldBe("existing configuration");

var forceResult = GitVersionHelper.ExecuteIn(
directory.FullName,
" config migrate --output GitVersion.v7.yml --force",
logToFile: false);

forceResult.ExitCode.ShouldBe(0);
forceResult.Output.ShouldNotBeNull();
forceResult.Output.ShouldContain("Comments cannot be preserved during migration.");
var forcedOutput = await File.ReadAllTextAsync(outputPath);
forcedOutput.ShouldContain("calculation:");
}
finally
{
directory.Delete(recursive: true);
}
}

[Test]
public async Task ConfigMigrateLeavesNoTemporaryFileAfterWritingOutput()
{
var directory = Directory.CreateTempSubdirectory();
try
{
var configurationPath = Path.Combine(directory.FullName, ConfigurationFileLocator.DefaultFileName);
await File.WriteAllTextAsync(configurationPath, "next-version: 2.0.0");

var result = await new ProgramFixture(directory.FullName).Run("config", "migrate", "--output", "GitVersion.v7.yml");

result.ExitCode.ShouldBe(0);
var files = Directory.GetFiles(directory.FullName).Select(Path.GetFileName).ToArray();
files.Length.ShouldBe(2);
files.ShouldContain(ConfigurationFileLocator.DefaultFileName);
files.ShouldContain("GitVersion.v7.yml");
files.ShouldNotContain(file => file!.StartsWith(".", StringComparison.Ordinal));
}
finally
{
directory.Delete(recursive: true);
}
}

[Test]
public async Task ConfigMigrateInPlaceMigratesExplicitConfigurationOutsideGitRepository()
{
var directory = Directory.CreateTempSubdirectory();
try
{
const string fileName = "legacy.yml";
var configurationPath = Path.Combine(directory.FullName, fileName);
await File.WriteAllTextAsync(configurationPath, "next-version: 2.0.0");

var result = GitVersionHelper.ExecuteIn(
directory.FullName,
$" config migrate --config {fileName} --in-place",
logToFile: false);

result.ExitCode.ShouldBe(0);
result.Output.ShouldNotBeNull();
result.Output.ShouldContain("Comments cannot be preserved during migration.");
var migratedConfiguration = await File.ReadAllTextAsync(configurationPath);
migratedConfiguration.ShouldContain("calculation:");
}
finally
{
directory.Delete(recursive: true);
}
}

[Test]
public async Task ConfigMigrateInPlaceUsesPositionalTargetPath()
{
var directory = Directory.CreateTempSubdirectory();
try
{
var configurationPath = Path.Combine(directory.FullName, ConfigurationFileLocator.DefaultFileName);
await File.WriteAllTextAsync(configurationPath, "next-version: 2.0.0");

var result = await new ProgramFixture().Run(directory.FullName, "config", "migrate", "--in-place");

result.ExitCode.ShouldBe(0);
var migratedConfiguration = await File.ReadAllTextAsync(configurationPath);
migratedConfiguration.ShouldContain("calculation:");
migratedConfiguration.ShouldContain("next-version: 2.0.0");
}
finally
{
directory.Delete(recursive: true);
}
}

[Test]
public async Task ConfigMigrateDoesNotEmitLegacyFallbackWarning()
{
var directory = Directory.CreateTempSubdirectory();
try
{
var configurationPath = Path.Combine(directory.FullName, ConfigurationFileLocator.DefaultFileName);
await File.WriteAllTextAsync(configurationPath, "next-version: 2.0.0");
var fixture = new ProgramFixture(directory.FullName);
fixture.WithEnv(new KeyValuePair<string, string>(ConfigurationVersionSelector.EnvironmentVariableName, "v6"));

var result = await fixture.Run("config", "migrate");

result.ExitCode.ShouldBe(0);
result.Output!.ShouldNotContain("temporary v6 compatibility mode");
result.Log!.ShouldNotContain("temporary v6 compatibility mode");
}
finally
{
directory.Delete(recursive: true);
}
}

[Test]
public void V6AndV7ConfigurationCalculateTheSameVersion()
{
Expand Down
7 changes: 6 additions & 1 deletion src/GitVersion.App.Tests/HelpWriterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,12 @@ public void AllArgsAreInHelp()
var ignored = new[]
{
nameof(Arguments.Authentication),
nameof(Arguments.UpdateAssemblyInfoFileName)
nameof(Arguments.UpdateAssemblyInfoFileName),
nameof(Arguments.IsConfigurationMigration),
nameof(Arguments.MigrationInputFile),
nameof(Arguments.MigrationOutputFile),
nameof(Arguments.MigrationInPlace),
nameof(Arguments.MigrationForce)
};
typeof(Arguments).GetFields()
.Select(p => p.Name)
Expand Down
8 changes: 8 additions & 0 deletions src/GitVersion.App.Tests/LegacyArgumentParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ public void OverrideConfigRejectsV6PathInV7WithReplacement()
exception.Message.ShouldContain("config migrate");
}

[Test]
public void ConfigMigrateIsRejectedAsASubcommand()
{
var exception = Should.Throw<WarningException>(() => this.argumentParser.ParseArguments("config migrate"));

exception.Message.ShouldContain("only available with the POSIX argument parser");
}

[Test]
public void EmptyMeansUseCurrentDirectory()
{
Expand Down
Loading
Loading