Skip to content

Commit

Permalink
refactor: Provide customization to RelationshipResolver
Browse files Browse the repository at this point in the history
Rather than raw configuration
  • Loading branch information
Crown0815 committed Dec 17, 2023
1 parent b89d599 commit ba3ca58
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 43 deletions.
10 changes: 5 additions & 5 deletions src/ConventionalChangelog/Changelog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ public class Changelog

public Changelog(Configuration configuration)
{
IConfigured configured = new Configured(configuration);
_relationshipResolver = new RelationshipResolver(configuration);
_repositoryReader = new RepositoryReader(configured);
_parser = new MessageParser(configured);
_logWriter = new LogWriter(configured);
ICustomization customization = new Customization(configuration);
_repositoryReader = new RepositoryReader(customization);
_parser = new MessageParser(customization);
_relationshipResolver = new RelationshipResolver(customization);
_logWriter = new LogWriter(customization);
}

public string FromRepository(string path)
Expand Down
18 changes: 9 additions & 9 deletions src/ConventionalChangelog/Conventional/MessageParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ namespace ConventionalChangelog.Conventional;

public class MessageParser
{
private readonly IConfigured _configured;
private readonly ICustomization _customization;

public MessageParser(Configuration configuration) : this(new Configured(configuration))
public MessageParser(Configuration configuration) : this(new Customization(configuration))
{
}

internal MessageParser(IConfigured configured) => _configured = configured;
internal MessageParser(ICustomization customization) => _customization = customization;

public CommitMessage Parse(Commit commit)
{
Expand All @@ -28,22 +28,22 @@ private CommitMessage Read(TextReader lines)
{
var (typeIndicator, description) = HeaderFrom(lines.ReadLine());
var (body, footers) = BodyFrom(lines);
typeIndicator = _configured.Sanitize(typeIndicator, footers);
typeIndicator = _customization.Sanitize(typeIndicator, footers);

return new CommitMessage(typeIndicator, description, body, footers);
}

#if NET6_0
private (string, string) HeaderFrom(string? header)
{
var twoParts = header?.Split(_configured.Separator);
var twoParts = header?.Split(_customization.Separator);
return twoParts?.Length == 2
? (twoParts.First(), twoParts.Last().Trim())
: ("", "");
}
#elif NET7_0_OR_GREATER
private (string, string) HeaderFrom(string? header) =>
header?.Split(_configured.Separator) is [var first, var second]
header?.Split(_customization.Separator) is [var first, var second]
? (first,second.Trim())
: ("", "");
#endif
Expand All @@ -54,7 +54,7 @@ private CommitMessage Read(TextReader lines)
var footers = Enumerable.Empty<Footer>();
while (reader.ReadLine() is { } line)
{
if (_configured.IsFooter(line))
if (_customization.IsFooter(line))
{
footers = FootersFrom(LinesFrom(reader).Prepend(line));
break;
Expand All @@ -76,15 +76,15 @@ private IEnumerable<Footer> FootersFrom(IEnumerable<string> lines)
Footer? buffer = null;
foreach (var line in lines)
{
if (buffer is not null && _configured.IsFooter(line))
if (buffer is not null && _customization.IsFooter(line))
{
yield return buffer with {Value = buffer.Value.Trim()};
buffer = null;
}
if (buffer is not null)
buffer = buffer with { Value = buffer.Value + Environment.NewLine + line};
else
buffer = _configured.FooterFrom(line);
buffer = _customization.FooterFrom(line);
}

if (buffer is not null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace ConventionalChangelog;

internal class Configured : IConfigured, IComparer<string>
internal class Customization : ICustomization, IComparer<string>
{
private const string ConventionalCommitSeparator = ": "; // see https://www.conventionalcommits.org/en/v1.0.0/#specification

Expand All @@ -13,16 +13,23 @@ internal class Configured : IConfigured, IComparer<string>
private readonly string _footerPattern;
private readonly string _semanticVersionPattern;

public Configured(Configuration configuration)
public Customization(Configuration configuration)
{
_commitTypes = configuration.CommitTypes.ToImmutableArray();
_versionTagPrefix = configuration.VersionTagPrefix;
_changelogOrder = configuration.ChangelogOrder;
_footerPattern = configuration.FooterPattern;
_semanticVersionPattern = configuration.SemanticVersionPattern;
Relationships = new Relationship[]
{
new(configuration.DropSelf, true, false),
new(configuration.DropOther, false, true),
new(configuration.DropBoth, true, true),
};
}

public string Separator => ConventionalCommitSeparator;
public IReadOnlyCollection<Relationship> Relationships { get; }

public string Sanitize(string typeIndicator, IEnumerable<CommitMessage.Footer> footers)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace ConventionalChangelog;

public interface IConfigured
internal interface ICustomization
{
string Sanitize(string typeIndicator, IEnumerable<CommitMessage.Footer> footers);
ChangelogType TypeFor(string typeIndicator);
Expand All @@ -15,4 +15,5 @@ public interface IConfigured
bool IsVersionTag(string tagName);

string Separator { get; }
IReadOnlyCollection<Relationship> Relationships { get; }
}
10 changes: 5 additions & 5 deletions src/ConventionalChangelog/LogWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@ internal class LogWriter

private static readonly string EmptyChangelog = ChangelogTitle + NewLine;

private readonly IConfigured _configured;
private readonly ICustomization _customization;


public LogWriter(IConfigured configured)
public LogWriter(ICustomization customization)
{
_configured = configured;
_customization = customization;
}

public string Print(IEnumerable<IPrintable> writable)
{
var writtenLog = new WrittenLog(EmptyChangelog);
foreach (var printable in _configured.Ordered(writable))
writtenLog.Add(printable, _configured.TypeFor(printable.TypeIndicator));
foreach (var printable in _customization.Ordered(writable))
writtenLog.Add(printable, _customization.TypeFor(printable.TypeIndicator));
return writtenLog.Print();
}

Expand Down
40 changes: 23 additions & 17 deletions src/ConventionalChangelog/RelationshipResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,53 @@

namespace ConventionalChangelog;

internal record Relationship(string Token, bool DropSelf, bool DropOther);

internal class RelationshipResolver
{
private readonly record struct Relationship(string Token, bool Add, bool Register, bool Remove);
private readonly record struct Rule(string Token, bool Add, bool Register, bool Remove);

private readonly IEnumerable<Relationship> _relationships;
private readonly IEnumerable<Rule> _rules;

public RelationshipResolver(Configuration configuration)
public RelationshipResolver(ICustomization customization)
{
_relationships = new Relationship[] {
new(configuration.DropSelf, true, true, true),
new(configuration.DropBoth, false, false, true),
new(configuration.DropOther, false, true, false),
};
_rules = customization.Relationships.Select(AsRule);
}

private static Rule AsRule(Relationship relationship) => new
(
relationship.Token,
relationship is { DropOther: false },
relationship.DropSelf != relationship.DropOther,
relationship is { DropSelf: true}
);

public IEnumerable<CommitMessage> ResolveRelationshipsBetween(IEnumerable<CommitMessage> messages)
{
return _relationships.Aggregate(messages, Reduce);
return _rules.Aggregate(messages, Reduce);
}

private static IEnumerable<CommitMessage> Reduce(IEnumerable<CommitMessage> messages, Relationship relationship)
private static IEnumerable<CommitMessage> Reduce(IEnumerable<CommitMessage> messages, Rule rule)
{
return messages.Aggregate(new Resolver(relationship), (c, m) => c.Add(m)).Messages;
return messages.Aggregate(new Resolver(rule), (c, m) => c.Add(m)).Messages;
}


private class Resolver
{
private readonly Relationship _relationship;
private readonly Rule _rule;
private readonly List<CommitMessage> _messages = new();
private readonly Dictionary<string, List<CommitMessage>> _references = new();

public Resolver(Relationship relationship) => _relationship = relationship;
public Resolver(Rule rule) => _rule = rule;

public Resolver Add(CommitMessage message)
{
var found = _references.TryGetValue(message.Hash, out var referenced);

if (!found || _relationship.Add) _messages.Add(message);
if (!found || _relationship.Register) CacheReferences(message);
if (found && _relationship.Remove) _messages.RemoveAll(referenced!.Contains);
if (!found || _rule.Add) _messages.Add(message);
if (!found || _rule.Register) CacheReferences(message);
if (found && _rule.Remove) _messages.RemoveAll(referenced!.Contains);
return this;
}

Expand All @@ -53,7 +59,7 @@ private void CacheReferences(CommitMessage source)
}

private IEnumerable<string> ReferencesFrom(CommitMessage commitMessage) =>
commitMessage.Footers.Where(_relationship.Token.Matches).Select(Target);
commitMessage.Footers.Where(_rule.Token.Matches).Select(Target);

private static string Target(CommitMessage.Footer f) => f.Value;

Expand Down
8 changes: 4 additions & 4 deletions src/ConventionalChangelog/RepositoryReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ namespace ConventionalChangelog;

internal class RepositoryReader
{
private readonly IConfigured _configured;
private readonly ICustomization _customization;

public RepositoryReader(IConfigured configured)
public RepositoryReader(ICustomization customization)
{
_configured = configured;
_customization = customization;
}

public IEnumerable<Commit> CommitsFrom(string path)
Expand All @@ -25,7 +25,7 @@ public IEnumerable<Commit> CommitsFrom(string path)
private object? NewestVersionCommitIn(IRepository repository)
{
var versionCommits = repository.Tags
.Where(tag => _configured.IsVersionTag(tag.FriendlyName))
.Where(tag => _customization.IsVersionTag(tag.FriendlyName))
.Select(x => x.Target)
.ToHashSet();

Expand Down

0 comments on commit ba3ca58

Please sign in to comment.