Skip to content

Commit

Permalink
feat: handle commits that change different files
Browse files Browse the repository at this point in the history
  • Loading branch information
BusHero committed Sep 1, 2023
1 parent 192a796 commit 924a7c8
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 80 deletions.
2 changes: 0 additions & 2 deletions .nuke/build.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@
"type": "string",
"enum": [
"BuildTemplate",
"Foo",
"GenerateDocumentationFeature",
"GetFeatures",
"GetTemplates",
Expand All @@ -96,7 +95,6 @@
"type": "string",
"enum": [
"BuildTemplate",
"Foo",
"GenerateDocumentationFeature",
"GetFeatures",
"GetTemplates",
Expand Down
79 changes: 53 additions & 26 deletions build.test/Fixture.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System.Text.Json;
using CliWrap;
using Fare;
using Nuke.Common;
using Nuke.Common.IO;

Expand All @@ -10,7 +9,6 @@ internal sealed class CustomFixture : IAsyncDisposable
{
private readonly List<string> tags = new();
private readonly List<string> tempFiles = new();

private int commitsCount = 0;

public bool KeepFiles { get; init; }
Expand All @@ -19,13 +17,10 @@ internal sealed class CustomFixture : IAsyncDisposable

public bool KeepCommits { get; init; }

public AbsolutePath RootDirectory => NukeBuild.RootDirectory;

public async ValueTask DisposeAsync()
{
if (!KeepFiles)
{
RemoveDirectory(tempFiles);
}

if (!KeepTags)
{
await DeleteGitTags(this.tags);
Expand All @@ -35,6 +30,29 @@ public async ValueTask DisposeAsync()
{
await RevertCommits(commitsCount);
}

if (!KeepFiles)
{
RemoveTempFiles(tempFiles);
await RestoreFiles(tempFiles);
}
}

private async Task RestoreFiles(IReadOnlyCollection<string> files)
{
if (files.Count == 0)
{
return;
}

await Cli.Wrap("git")
.WithArguments(args => args
.Add("restore")
.Add("--staged")
.Add("--progress")
.Add(files))
.WithStandardOutputPipe(PipeTarget.ToDelegate(Console.WriteLine))
.ExecuteAsync();
}

public string GetTagForFeature(string feature) => $"feature_{feature}";
Expand All @@ -51,13 +69,12 @@ await Cli.Wrap("git")
.Add("reset")
.Add("--no-refresh")
.Add("--soft")
.Add($"HEAD~{numberOfCommits}")
.Add("--quiet"))
.Add($"HEAD~{numberOfCommits}"))
.WithStandardOutputPipe(PipeTarget.ToDelegate(Console.WriteLine))
.ExecuteAsync();
}

public void RemoveDirectory(IReadOnlyCollection<string> tempFiles)
public void RemoveTempFiles(IReadOnlyCollection<string> tempFiles)
{
if (tempFiles.Count == 0)
{
Expand Down Expand Up @@ -131,9 +148,8 @@ await Cli.Wrap("dotnet")
.Add("Version")
.Add("--feature")
.Add(feature)
.Add("--no-logo")
.Add("--verbosity")
.Add("Quiet"))
.Add("--no-logo"))
.WithStandardOutputPipe(PipeTarget.ToDelegate(Console.WriteLine))
.ExecuteAsync();
}

Expand All @@ -145,6 +161,7 @@ await Cli.Wrap("git")
.WithArguments(args => args
.Add("add")
.Add(path))
.WithStandardOutputPipe(PipeTarget.ToDelegate(Console.WriteLine))
.ExecuteAsync();

await Cli.Wrap("git")
Expand All @@ -153,8 +170,8 @@ await Cli.Wrap("git")
.Add("--include")
.Add(path)
.Add("--message")
.Add(message)
.Add("--quiet"))
.Add(message))
.WithStandardOutputPipe(PipeTarget.ToDelegate(Console.WriteLine))
.ExecuteAsync();

this.commitsCount++;
Expand All @@ -169,6 +186,7 @@ await Cli.Wrap("git")
.Add("tag")
.Add(tag)
.Add(commit))
.WithStandardOutputPipe(PipeTarget.ToDelegate(Console.WriteLine))
.ExecuteAsync();
this.tags.Add(tag);
}
Expand All @@ -181,18 +199,27 @@ public async Task DeleteGitTags(IReadOnlyCollection<string> tags)
}

await Cli.Wrap("git")
.WithArguments(args =>
{
args
.Add("tag")
.Add("--delete");
foreach (var tag in tags)
{
args.Add(tag);
}
})
.WithArguments(args => args
.Add("tag")
.Add("--delete")
.Add(tags))
.WithStandardOutputPipe(PipeTarget.ToDelegate(Console.WriteLine))
.ExecuteAsync();
}
}

public static class EnumerableExtenssions
{
public static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
{
foreach (var item in items)
{
action(item);
}
}

public static void ForEach<T, TReturn>(
this IEnumerable<T> items,
Func<T, TReturn> action)
=> items.ForEach(x => { action(x); });
}
45 changes: 37 additions & 8 deletions build.test/VersioningTests.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
using Nuke.Common;
using Xunit.Abstractions;

namespace build.test;

public sealed class VersioningTests : IAsyncLifetime
{
private readonly CustomFixture fixture;

public VersioningTests()
public VersioningTests(ITestOutputHelper outputHelper)
{
this.fixture = new CustomFixture
{
Expand All @@ -16,8 +16,7 @@ public VersioningTests()
};
}

[Theory]
[AutoData]
[Theory, AutoData]
public async Task TwoCommits_FeatAndChore_UpdatesMajor(
string feature,
int major,
Expand Down Expand Up @@ -47,8 +46,7 @@ public async Task TwoCommits_FeatAndChore_UpdatesMajor(
.Be($"{major + 1}.0.0");
}

[Theory]
[AutoData]
[Theory, AutoData]
public async Task TwoCommits_ChoreAndChore_UpdatesChore(
string feature,
int major,
Expand Down Expand Up @@ -77,8 +75,7 @@ public async Task TwoCommits_ChoreAndChore_UpdatesChore(
.Be($"{major}.{minor + 1}.0");
}

[Theory]
[AutoData]
[Theory, AutoData]
public async Task UseTheRightTag(
string feature,
int major,
Expand Down Expand Up @@ -109,6 +106,38 @@ public async Task UseTheRightTag(
.Be($"{major + 1}.0.0");
}

[Theory, AutoData]
public async Task UseTheRightCommit(
string feature,
string tempFileName,
int major,
int minor,
int build,
string wrongTag,
string message)
{
feature = feature.Replace("-", string.Empty);
var featureRoot = fixture.GetFeatureRoot(feature);
var rightTag = fixture.GetTagForFeature(feature);
wrongTag = wrongTag.Replace("-", "");
(major, minor, build) = (Math.Abs(major), Math.Abs(minor), Math.Abs(build));

await fixture.AddGitTag(rightTag);
await fixture.CreateFeatureConfig(feature, major, minor, build);
await fixture.Commit(featureRoot, $"chore: {message}");
await fixture.AddGitTag(wrongTag);
fixture.CreateTempFile(fixture.RootDirectory / tempFileName);
await fixture.Commit(fixture.RootDirectory / tempFileName, $"feat: {message}");

await fixture.RunBuild(feature);

var version = await fixture.GetVersion(feature);

version
.Should()
.Be($"{major}.{minor + 1}.0");
}

public async Task InitializeAsync() => await Task.CompletedTask;

public async Task DisposeAsync() => await fixture.DisposeAsync();
Expand Down
1 change: 0 additions & 1 deletion build/Build.Documentation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ sealed partial class Build

private AbsolutePath PathToReadme => FeaturesRoot / "src" / Feature / "README.md";


Target GenerateDocumentationFeature => _ => _
.Requires(() => Feature)
.Executes(async () =>
Expand Down
2 changes: 2 additions & 0 deletions build/Build.Features.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ sealed partial class Build
{
private AbsolutePath FeaturesRoot => RootDirectory / "features";

private RelativePath RelativeFeatureRoot => RootDirectory.GetRelativePathTo(FeaturesRoot) / "src" / Feature;

[Parameter] private readonly bool SkipAutoGenerated;

[Parameter("Feature to build")] private readonly string Feature = null!;
Expand Down
78 changes: 35 additions & 43 deletions build/Build.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Nuke.Common.Tooling;
using CliWrap;
using Serilog;
using Nuke.Common.IO;

public sealed partial class Build : NukeBuild
{
Expand All @@ -25,14 +26,12 @@ public sealed partial class Build : NukeBuild
Log.Information("old version: {version}", version);
var latestGitTag = await GetLatestTag(Feature);
Log.Information("{tag}", latestGitTag);
var commits = latestGitTag switch
{
null => new List<string>(),
_ => await GetCommitsTillTag(latestGitTag)
_ => await GetCommitsTillTag(latestGitTag, RelativeFeatureRoot)
};
Log.Information("commits: {commits}", commits);
if (commits.Any(x => x.StartsWith("feat:")))
{
version = version.IncrementMajor();
Expand All @@ -49,13 +48,6 @@ public sealed partial class Build : NukeBuild
await File.WriteAllTextAsync(PathToFeatureDefinition, outputJson);
});

private Target Foo => _ => _
.Executes(async () =>
{
var message = await GetLatestCommitMessage();
Log.Information("{tags}", message);
});

private async Task<string?> GetLatestTag(string feature)
{
var tags = new List<string>();
Expand All @@ -73,50 +65,50 @@ await Cli.Wrap("git")
return tags.FirstOrDefault();
}

private async Task<List<string>> GetCommitsTillTag(string tag)
private async Task<List<string>> GetCommitsTillTag(
string tag,
RelativePath path)
{
Log.Information("{msg}", "Here is nice");
var commits = new List<string>();

await Cli.Wrap("git")
.WithArguments(args => args
.Add("rev-list")
.Add($"{tag}..HEAD")
.Add("--pretty=%s")
.Add("--no-commit-header"))
.WithStandardOutputPipe(PipeTarget.ToDelegate(commits.Add))
.ExecuteAsync();

return commits;
}

private async Task<string> GetLatestCommitMessage()
{
var output = new List<string>();

await Cli.Wrap("git")
.WithArguments(args => args
.Add("rev-list")
.Add("HEAD")
.Add("--pretty=%s")
.Add("--no-commit-header")
.Add("-n1"))
.WithStandardOutputPipe(PipeTarget.ToDelegate(output.Add))
.ExecuteAsync();

return output[0];
}

private async Task<List<string>> GetGitTags()
{
var tags = new List<string>();

var foo = await Cli.Wrap("git")
.WithArguments(args => args
.Add("tag"))
.WithStandardOutputPipe(PipeTarget.ToDelegate(tags.Add))
.ExecuteAsync();
var commitMessages = new List<string>();
foreach (var commit in commits)
{
var modifiedFiles = new List<string>();
await Cli.Wrap("git")
.WithArguments(args => args
.Add("diff-tree")
.Add("--no-commit-id")
.Add("--name-only")
.Add("-r")
.Add(commit))
.WithStandardOutputPipe(PipeTarget.ToDelegate(modifiedFiles.Add))
.ExecuteAsync();

if (!modifiedFiles.Any(x => x.StartsWith(path)))
{
continue;
}

return tags;
await Cli.Wrap("git")
.WithArguments(args => args
.Add("rev-list")
.Add("--max-count=1")
.Add("--no-commit-header")
.Add("--format=%s")
.Add(commit))
.WithStandardOutputPipe(PipeTarget.ToDelegate(commitMessages.Add))
.ExecuteAsync();
}

return commitMessages;
}
}
Loading

0 comments on commit 924a7c8

Please sign in to comment.