Skip to content

Commit

Permalink
Change overrides to be passed via source file
Browse files Browse the repository at this point in the history
Decided that passing via json in the settings file was too obtuse

tag: Changed
version: 0.7.0
  • Loading branch information
Ben Zumhagen committed Nov 13, 2019
1 parent 55cf6fa commit 4f7e665
Show file tree
Hide file tree
Showing 19 changed files with 464 additions and 184 deletions.
24 changes: 13 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,7 @@ See `dotnet-gitchanges\appsettings.json` for the default settings file. Any sett
"MinVersion": "0.1.0",
"Repository": {
"Path": ".",
ChangeOverrides": [
{
"Id": "03c5f2382c23e5437027d0c811d9d6da9d92f6f9",
"Version": "0.4.1",
"Tag": "Removed",
"Summary": "Replace this thing",
"Date": "2019-01-10",
"Reference": "REF-1234"
}
]
"OverrideSource": "someOverrideSource.txt"
},
"FileSource": "someHistorialChanges.txt"
}
Expand All @@ -100,7 +91,7 @@ See `dotnet-gitchanges\appsettings.json` for the default settings file. Any sett
| Template | Path to custom template file.
| MinVersion | The minimum version of the changelog, generation will exclude changes lower than this version.
| Repository.Path | Path to repository root.
| Repository.ChangeOverrides | Collection of Change Overrides. Add an entry for every commit you want to override with custom values at generation time where Id is the commit Id.
| Repository.OverrideSource | Path to override source (see [Overriding repository changes](#overriding-repository-changes))
| FileSource | Path to file source (see [Existing repository](#existing-repository)).

#### Custom Template
Expand All @@ -117,6 +108,17 @@ The schema available for you to use in your custom templates is detailed below.
----+---+---+-- reference // Change reference value\
----+---+---+-- summary // Change summary

#### Overriding Repository Changes
In some cases, you may decide that you want to override a commit which exists in the repository history without having to rewrite the history. In this case you can provide an override source file in a [custom settings file](#custom-app-settings).

The file should have one change per line in one of the following formats

`<commitId>|<version>|<tag>|<summary>|<date in yyyy-MM-dd format>`

or

`<commitId>|<reference>|<version>|<tag>|<summary>|<date in yyyy-MM-dd>`

#### Git helpers
See `git\.gitmessage` and `git\hooks\prepare-commit-msg` for examples of how to use git hooks and message templates to construct messages in the desired format, automatically populating metadata where possible.

Expand Down
57 changes: 20 additions & 37 deletions dotnet-gitchanges.Tests/Readers/FileReaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
using System.Linq;
using System.Text;
using Gitchanges.Changes;
using Gitchanges.Configuration;
using Gitchanges.Readers;
using LibGit2Sharp;
using Gitchanges.Readers.Parsers;
using Moq;
using NUnit.Framework;

Expand All @@ -19,72 +18,56 @@ public class FileReaderTests
private const string DateFormat = "yyyy-MM-dd";

[Test]
public void VerifyReaderReadsFromFileWithoutReference()
public void VerifyReaderReadsFromFile()
{
var fileContents = new StringBuilder();
var expectedChanges = new List<IChange>
{
new GitChange("0.2.0", "Added", "Some Summary", DateTimeOffset.Now.Date),
new GitChange("0.1.0", "Removed", "Another Summary", DateTimeOffset.Now.AddDays(-1).Date)
};
var mockParser = new Mock<IRowParser<IChange>>();
foreach (var change in expectedChanges)
{
fileContents.Append($"{change.Version}{Delimiter}{change.Tag}{Delimiter}{change.Summary}{Delimiter}{change.Date.ToString(DateFormat)}\n");
var line = $"{change.Version}{Delimiter}{change.Tag}{Delimiter}{change.Summary}{Delimiter}{change.Date.ToString(DateFormat)}\n";
mockParser.Setup(p => p.Parse(line.Trim())).Returns(change);
fileContents.Append(line);
}
UsingTempFile(fileContents.ToString(), path =>
{
var reader = new FileReader(path, Delimiter, null);
var reader = new FileReader<IChange>(path, mockParser.Object);

Assert.That(reader.Changes(), Is.EquivalentTo(expectedChanges));
Assert.That(reader.Values(), Is.EquivalentTo(expectedChanges));
});
}

[Test]
public void VerifyReaderReadsFromFileWithReference()
public void VerifyReaderReadsFromFileSkippingUnparseableRecords()
{
var fileContents = new StringBuilder();
var expectedChanges = new List<IChange>
{
new GitChange("0.2.0", "Added", "Some Summary", DateTimeOffset.Now.Date, "REF-1234"),
new GitChange("0.1.0", "Removed", "Another Summary", DateTimeOffset.Now.AddDays(-1).Date, "REF-5678")
};
foreach (var change in expectedChanges)
{
fileContents.Append($"{change.Reference}{Delimiter}{change.Version}{Delimiter}{change.Tag}{Delimiter}{change.Summary}{Delimiter}{change.Date.ToString(DateFormat)}\n");
}
UsingTempFile(fileContents.ToString(), path =>
{
var reader = new FileReader(path, Delimiter, null);

Assert.That(reader.Changes(), Is.EquivalentTo(expectedChanges));
});
}

[Test]
public void VerifyReaderSkipsUnparseableRecords()
{
var errorWriter = new StringWriter();
var fileContents = new StringBuilder();
var allChanges = new List<IChange>
{
new GitChange("|0.2.0", "Added", "Some Summary", DateTimeOffset.Now.Date, "REF-1234"),
new GitChange("0.1.5", "Added|", "Some Summary", DateTimeOffset.Now.Date, "REF-1234"),
new GitChange("0.1.0", "Removed", "Another Summary", DateTimeOffset.Now.AddDays(-1).Date, "REF-5678")
new GitChange("0.2.0", "Added", "Some Summary", DateTimeOffset.Now.Date),
new GitChange("0.1.0", "Removed", "Another Summary", DateTimeOffset.Now.AddDays(-1).Date)
};
var expectedChanges = new List<IChange>
{
new GitChange("0.1.0", "Removed", "Another Summary", DateTimeOffset.Now.AddDays(-1).Date, "REF-5678")
allChanges.First()
};
var mockParser = new Mock<IRowParser<IChange>>();
mockParser.SetupSequence(p => p.Parse(It.IsAny<string>())).Returns((IChange)null).Returns(expectedChanges.First());

foreach (var change in allChanges)
{
fileContents.Append($"{change.Reference}{Delimiter}{change.Version}{Delimiter}{change.Tag}{Delimiter}{change.Summary}{Delimiter}{change.Date.ToString(DateFormat)}\n");
var line = $"{change?.Version}{Delimiter}{change?.Tag}{Delimiter}{change?.Summary}{Delimiter}{change?.Date.ToString(DateFormat)}\n";
fileContents.Append(line);
}

UsingTempFile(fileContents.ToString(), path =>
{
var reader = new FileReader(path, Delimiter, errorWriter);
var reader = new FileReader<IChange>(path, mockParser.Object);

Assert.That(reader.Changes(), Is.EquivalentTo(expectedChanges));
Assert.That(errorWriter.ToString().Split("\n").Length, Is.EqualTo(3));
Assert.That(reader.Values(), Is.EquivalentTo(expectedChanges));
});
}

Expand Down
31 changes: 31 additions & 0 deletions dotnet-gitchanges.Tests/Readers/GitReaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,37 @@ public void VerifyOverriddenChangesAreUsed()
repoMock.VerifyAll();
}

[Test]
public void VerifyOverriddenChangeVersionsAreUsedForPrecedingUnreleasedVersions()
{
var overriddenChange = new GitChange("0.2.0", "Added", "Some Summary", DateTimeOffset.Now.Date);
var overrideChange = new GitChange(overriddenChange.Version, overriddenChange.Tag, "Some other summary", overriddenChange.Date);
var unreleasedChange = new GitChange("Unreleased", overriddenChange.Tag, overriddenChange.Summary, overriddenChange.Date);
var badChangeId = ToSha1String(overriddenChange);
var idToOverrideChange = new Dictionary<string, IChange>
{
{badChangeId, overrideChange}
};
var repositoryChanges = new List<IChange>
{
overriddenChange,
unreleasedChange
};
var expectedChanges = new List<IChange>
{
overrideChange,
new GitChange(overrideChange.Version, unreleasedChange.Tag, unreleasedChange.Summary, unreleasedChange.Date)
};
var repoMock = new Mock<IRepository>();
var commitLog = Mock.Of<IQueryableCommitLog>(cl => cl.GetEnumerator() == MockCommitEnumerator(repositoryChanges));
var reader = new GitReader(repoMock.Object, _defaultPatterns);

repoMock.Setup(r => r.Commits).Returns(commitLog);
var actualChanges = reader.Changes(idToOverrideChange).ToList();
Assert.That(actualChanges, Is.EquivalentTo(expectedChanges));
repoMock.VerifyAll();
}

private static IEnumerator<Commit> MockCommitEnumerator(IEnumerable<IChange> expectedChanges)
{
return expectedChanges.Select(MockCommit).GetEnumerator();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System;
using System.IO;
using Gitchanges.Changes;
using Gitchanges.Readers.Parsers;
using NUnit.Framework;

namespace Gitchanges.Tests.Readers.Parsers
{
[TestFixture]
public class FileSourceRowParserTests
{
[Test]
public void VerifyParserParsesLineWithReferenceSuccessfully()
{
var expectedChange = new GitChange("0.1.0", "Some Tag", "Some Summary", DateTimeOffset.Now.Date, "Some Reference");
var line = $"{expectedChange.Reference}|{expectedChange.Version}|{expectedChange.Tag}|{expectedChange.Summary}|{expectedChange.Date:yyyy-MM-dd}";
var writer = new StringWriter();
var parser = new FileSourceRowParser(writer);
var actual = parser.Parse(line);

Assert.That(actual, Is.EqualTo(expectedChange));
}

[Test]
public void VerifyParserParsesLineWithoutReferenceSuccessfully()
{
var expectedChange = new GitChange("0.1.0", "Some Tag", "Some Summary", DateTimeOffset.Now.Date);
var line = $"{expectedChange.Version}|{expectedChange.Tag}|{expectedChange.Summary}|{expectedChange.Date:yyyy-MM-dd}";
var writer = new StringWriter();
var parser = new FileSourceRowParser(writer);
var actual = parser.Parse(line);

Assert.That(actual, Is.EqualTo(expectedChange));
}

[Test]
public void VerifyParserHandlesTooFewDelimitersIssues()
{
var expectedChange = new GitChange("0.1.0", "Some Tag", "Some Summary", DateTimeOffset.Now.Date);
var line = $"{expectedChange.Version}{expectedChange.Tag}|{expectedChange.Summary}|{expectedChange.Date:yyyy-MM-dd}";
var writer = new StringWriter();
var parser = new FileSourceRowParser(writer);
var actual = parser.Parse(line);

Assert.That(actual, Is.Null);
Assert.That(writer.ToString().Trim(), Is.EqualTo($"Error parsing line '{line}'. Wrong number of values. Expected 4 or 5 but was 3"));
}

[Test]
public void VerifyParserHandlesTooManyDelimiterIssues()
{
var expectedChange = new GitChange("0.1.0", "Some Tag", "Some Summary", DateTimeOffset.Now.Date);
var line = $"{expectedChange.Version}|||{expectedChange.Tag}|{expectedChange.Summary}|{expectedChange.Date:yyyy-MM-dd}";
var writer = new StringWriter();
var parser = new FileSourceRowParser(writer);
var actual = parser.Parse(line);

Assert.That(actual, Is.Null);
Assert.That(writer.ToString().Trim(), Is.EqualTo($"Error parsing line '{line}'. Wrong number of values. Expected 4 or 5 but was 6"));
}

[Test]
public void VerifyParserHandlesDateFormatIssues()
{
var expectedChange = new GitChange("0.1.0", "Some Tag", "Some Summary", DateTimeOffset.Now.Date);
var line = $"{expectedChange.Version}|{expectedChange.Tag}|{expectedChange.Summary}|{expectedChange.Date}";
var writer = new StringWriter();
var parser = new FileSourceRowParser(writer);
var actual = parser.Parse(line);

Assert.That(actual, Is.Null);
Assert.That(writer.ToString().Trim(), Is.EqualTo($"Error parsing line '{line}'. Date should match the format 'yyyy-MM-dd'"));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System;
using System.IO;
using Gitchanges.Changes;
using Gitchanges.Readers.Parsers;
using NUnit.Framework;

namespace Gitchanges.Tests.Readers.Parsers
{
[TestFixture]
public class OverrideSourceRowParserTests
{
[Test]
public void VerifyParserParsesLineWithReferenceSuccessfully()
{
var expectedChange = new OverrideChange("123456", "0.1.0", "Some Tag", "Some Summary", DateTimeOffset.Now.Date, "Some Reference");
var line = $"{expectedChange.Id}|{expectedChange.Reference}|{expectedChange.Version}|{expectedChange.Tag}|{expectedChange.Summary}|{expectedChange.Date:yyyy-MM-dd}";
var writer = new StringWriter();
var parser = new OverrideSourceRowParser(writer);
var actual = parser.Parse(line);

Assert.That(actual, Is.EqualTo(expectedChange));
}

[Test]
public void VerifyParserParsesLineWithoutReferenceSuccessfully()
{
var expectedChange = new OverrideChange("123456", "0.1.0", "Some Tag", "Some Summary", DateTimeOffset.Now.Date);
var line = $"{expectedChange.Id}|{expectedChange.Version}|{expectedChange.Tag}|{expectedChange.Summary}|{expectedChange.Date:yyyy-MM-dd}";
var writer = new StringWriter();
var parser = new OverrideSourceRowParser(writer);
var actual = parser.Parse(line);

Assert.That(actual, Is.EqualTo(expectedChange));
}

[Test]
public void VerifyParserHandlesTooFewDelimitersIssues()
{
var expectedChange = new OverrideChange("123456", "0.1.0", "Some Tag", "Some Summary", DateTimeOffset.Now.Date);
var line = $"{expectedChange.Id}|{expectedChange.Version}{expectedChange.Tag}|{expectedChange.Summary}|{expectedChange.Date:yyyy-MM-dd}";
var writer = new StringWriter();
var parser = new OverrideSourceRowParser(writer);
var actual = parser.Parse(line);

Assert.That(actual, Is.Null);
Assert.That(writer.ToString().Trim(), Is.EqualTo($"Error parsing line '{line}'. Wrong number of values. Expected 5 or 6 but was 4"));
}

[Test]
public void VerifyParserHandlesTooManyDelimitersIssues()
{
var expectedChange = new OverrideChange("123456", "0.1.0", "Some Tag", "Some Summary", DateTimeOffset.Now.Date);
var line = $"{expectedChange.Id}|||{expectedChange.Version}|{expectedChange.Tag}|{expectedChange.Summary}|{expectedChange.Date:yyyy-MM-dd}";
var writer = new StringWriter();
var parser = new OverrideSourceRowParser(writer);
var actual = parser.Parse(line);

Assert.That(actual, Is.Null);
Assert.That(writer.ToString().Trim(), Is.EqualTo($"Error parsing line '{line}'. Wrong number of values. Expected 5 or 6 but was 7"));
}

[Test]
public void VerifyParserHandlesDateFormatIssues()
{
var expectedChange = new OverrideChange("123456", "0.1.0", "Some Tag", "Some Summary", DateTimeOffset.Now.Date);
var line = $"{expectedChange.Id}|{expectedChange.Version}|{expectedChange.Tag}|{expectedChange.Summary}|{expectedChange.Date}";
var writer = new StringWriter();
var parser = new OverrideSourceRowParser(writer);
var actual = parser.Parse(line);

Assert.That(actual, Is.Null);
Assert.That(writer.ToString().Trim(), Is.EqualTo($"Error parsing line '{line}'. Date should match the format 'yyyy-MM-dd'"));
}
}
}
Loading

0 comments on commit 4f7e665

Please sign in to comment.