Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed warning #198

Merged
merged 4 commits into from
Dec 8, 2023
Merged
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
1 change: 1 addition & 0 deletions src/Credfeto.ChangeLog.Cmd/EnumExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ namespace Credfeto.ChangeLog.Cmd;
[SuppressMessage(category: "ReSharper", checkId: "PartialTypeWithSinglePart", Justification = "Needed for generated code")]
internal static partial class EnumExtensions
{
// Code generated by EnumTextGenerator
}
15 changes: 9 additions & 6 deletions src/Credfeto.ChangeLog.Cmd/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,7 @@ private static async Task CheckInsertPositionAsync(Options options, Cancellation
string changeLog = FindChangeLog(options);
Console.WriteLine($"Using Changelog {changeLog}");
Console.WriteLine($"Branch: {originBranchName}");
bool valid = await ChangeLogChecker.ChangeLogModifiedInReleaseSectionAsync(changeLogFileName: changeLog,
originBranchName: originBranchName,
cancellationToken: cancellationToken);
bool valid = await ChangeLogChecker.ChangeLogModifiedInReleaseSectionAsync(changeLogFileName: changeLog, originBranchName: originBranchName, cancellationToken: cancellationToken);

if (valid)
{
Expand Down Expand Up @@ -174,9 +172,7 @@ private static async Task<int> Main(string[] args)

try
{
ParserResult<Options> parser = await Parser.Default.ParseArguments<Options>(args)
.WithNotParsed(NotParsed)
.WithParsedAsync(ParsedOkAsync);
ParserResult<Options> parser = await ParseOptionsAsync(args);

return parser.Tag == ParserResultType.Parsed
? SUCCESS
Expand All @@ -194,4 +190,11 @@ private static async Task<int> Main(string[] args)
return ERROR;
}
}

private static Task<ParserResult<Options>> ParseOptionsAsync(IEnumerable<string> args)
{
return Parser.Default.ParseArguments<Options>(args)
.WithNotParsed(NotParsed)
.WithParsedAsync(ParsedOkAsync);
}
}
7 changes: 6 additions & 1 deletion src/Credfeto.ChangeLog/BuildNumberHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ internal static class BuildNumberHelpers
return null;
}

return new(version);
if (!Version.TryParse(input: version, out Version? parsedVersion))
{
return null;
}

return parsedVersion;
}
}
65 changes: 48 additions & 17 deletions src/Credfeto.ChangeLog/ChangeLogChecker.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -29,7 +30,7 @@ public static async Task<bool> ChangeLogModifiedInReleaseSectionAsync(string cha

using (Repository repo = GitRepository.OpenRepository(changelogDir))
{
string sha = repo.Head.Tip.Sha;
string sha = HeadSha(repo);

Branch? originBranch = repo.Branches.FirstOrDefault(b => b.FriendlyName == originBranchName);

Expand All @@ -49,7 +50,7 @@ public static async Task<bool> ChangeLogModifiedInReleaseSectionAsync(string cha

int firstReleaseVersionIndex = position.Value;

Patch changes = repo.Diff.Compare<Patch>(oldTree: originBranch.Tip.Tree, newTree: repo.Head.Tip.Tree, compareOptions: CompareSettings.BuildCompareOptions);
Patch changes = repo.Diff.Compare<Patch>(oldTree: BranchTree(originBranch), newTree: HeadTree(repo), compareOptions: CompareSettings.BuildCompareOptions);

PatchEntryChanges? change = changes.FirstOrDefault(candidate => candidate.Path == changeLogInRepoPath);

Expand All @@ -64,6 +65,26 @@ public static async Task<bool> ChangeLogModifiedInReleaseSectionAsync(string cha
return true;
}

private static Tree BranchTree(Branch branch)
{
return branch.Tip.Tree;
}

private static Tree HeadTree(Repository repo)
{
return BranchTree(repo.Head);
}

private static string BranchSha(Branch branch)
{
return branch.Tip.Sha;
}

private static string HeadSha(Repository repo)
{
return BranchSha(repo.Head);
}

private static bool CheckForChangesAfterFirstRelease(PatchEntryChanges change, int firstReleaseVersionIndex)
{
Console.WriteLine("Change Details");
Expand All @@ -72,7 +93,7 @@ private static bool CheckForChangesAfterFirstRelease(PatchEntryChanges change, i

MatchCollection matches = CommonRegex.GitHunkPosition.Matches(patchDetails);

foreach (Match? match in matches)
foreach (Match? match in matches.OfType<Match?>())
{
if (match is null)
{
Expand Down Expand Up @@ -109,7 +130,7 @@ private static string ExtractPatchDetails(string patch)

if (lastHunk != -1)
{
CompareHunk(lines: lines, lastHunk: lastHunk, out List<string> before, out List<string> after);
(List<string> before, List<string> after) = CompareHunk(lines: lines, lastHunk: lastHunk);

if (before.SequenceEqual(second: after, comparer: StringComparer.Ordinal))
{
Expand All @@ -120,48 +141,58 @@ private static string ExtractPatchDetails(string patch)
return string.Join(separator: Environment.NewLine, values: lines);
}

private static void CompareHunk(List<string> lines, int lastHunk, out List<string> before, out List<string> after)
private static (List<string> before, List<string> after) CompareHunk(List<string> lines, int lastHunk)
{
before = new();
after = new();
List<string> before = [];
List<string> after = [];

foreach (string line in lines.Skip(lastHunk + 1))
{
switch (line[0])
{
case '+':
after.Add(line.Substring(1));
after.Add(line[1..]);

break;

case '-':
before.Add(line.Substring(1));
before.Add(line[1..]);

break;

case '\\':
if (line == @"\ No newline at end of file")
if (StringComparer.Ordinal.Equals(x: line, y: @"\ No newline at end of file"))
{
break;
}

throw new DiffException($"Could not process diff line: {line}");
return CouldNotProcessDiffLine(line);

default: throw new DiffException($"Could not process diff line: {line}");
default: return CouldNotProcessDiffLine(line);
}
}

return (before, after);
}

[DoesNotReturn]
private static (List<string> before, List<string> after) CouldNotProcessDiffLine(string line)
{
throw new DiffException($"Could not process diff line: {line}");
}

private static void RemoveLastLineIfBlank(List<string> lines)
{
int lastLine = lines.Count - 1;

if (lastLine >= 0)
if (lastLine < 0)
{
if (string.IsNullOrEmpty(lines[lastLine]))
{
lines.RemoveAt(lastLine);
}
return;
}

if (string.IsNullOrEmpty(lines[lastLine]))
{
lines.RemoveAt(lastLine);
}
}

Expand Down
11 changes: 8 additions & 3 deletions src/Credfeto.ChangeLog/ChangeLogReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ public static string ExtractReleaseNotes(string changeLog, string version)
{
Version? releaseVersion = BuildNumberHelpers.DetermineVersionForChangeLog(version);

IReadOnlyList<string> text = CommonRegex.RemoveComments.Replace(input: changeLog, replacement: string.Empty)
.Trim()
.SplitToLines();
IReadOnlyList<string> text = RemoveComments(changeLog);

FindSectionForBuild(text: text, version: releaseVersion, out int foundStart, out int foundEnd);

Expand Down Expand Up @@ -78,6 +76,13 @@ public static string ExtractReleaseNotes(string changeLog, string version)
.Trim();
}

private static IReadOnlyList<string> RemoveComments(string changeLog)
{
return CommonRegex.RemoveComments.Replace(input: changeLog, replacement: string.Empty)
.Trim()
.SplitToLines();
}

public static async Task<int?> FindFirstReleaseVersionPositionAsync(string changeLogFileName, CancellationToken cancellationToken)
{
IReadOnlyList<string> changelog = await File.ReadAllLinesAsync(path: changeLogFileName, encoding: Encoding.UTF8, cancellationToken: cancellationToken);
Expand Down
74 changes: 49 additions & 25 deletions src/Credfeto.ChangeLog/ChangeLogUpdater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,7 @@ public static string AddEntry(string changeLog, string type, string message)

private static string AddEntryCommon(string changeLog, string type, string message)
{
List<string> text = EnsureChangelog(changeLog)
.SplitToLines()
.ToList();
List<string> text = ChangeLogAsLines(changeLog);

string entryText = CreateEntryText(message);
int index = FindInsertPosition(changeLog: text, type: type, entryText: entryText);
Expand All @@ -68,16 +66,21 @@ private static string AddEntryCommon(string changeLog, string type, string messa
.Trim();
}

private static List<string> ChangeLogAsLines(string changeLog)
{
return EnsureChangelog(changeLog)
.SplitToLines()
.ToList();
}

public static string RemoveEntry(string changeLog, string type, string message)
{
return RemoveEntryCommon(changeLog: changeLog, type: type, message: message);
}

private static string RemoveEntryCommon(string changeLog, string type, string message)
{
List<string> text = EnsureChangelog(changeLog)
.SplitToLines()
.ToList();
List<string> text = ChangeLogAsLines(changeLog);

string entryText = CreateEntryText(message);
int index = FindRemovePosition(changeLog: text, type: type, entryText: entryText);
Expand Down Expand Up @@ -120,12 +123,7 @@ private static int FindRemovePosition(List<string> changeLog, string type, strin
findSection: false);
}

private static int FindMatchPosition(List<string> changeLog,
string type,
Func<string, bool> isMatch,
Func<int, int> exactMatchAction,
Func<int, int> emptySectionAction,
bool findSection)
private static int FindMatchPosition(List<string> changeLog, string type, Func<string, bool> isMatch, Func<int, int> exactMatchAction, Func<int, int> emptySectionAction, bool findSection)
{
bool foundUnreleased = false;

Expand Down Expand Up @@ -205,9 +203,7 @@ public static string CreateRelease(string changeLog, string version, bool pendin

private static string CreateReleaseCommon(string changeLog, string version, bool pending)
{
List<string> text = EnsureChangelog(changeLog)
.SplitToLines()
.ToList();
List<string> text = ChangeLogAsLines(changeLog);

Dictionary<string, int> releases = FindReleasePositions(text);

Expand Down Expand Up @@ -283,7 +279,7 @@ private static void RemoveItems(List<string> text, List<int> removeIndexes)
private static string CreateReleaseVersionHeader(string version, bool pending)
{
string releaseDate = CreateReleaseDate(pending);
string releaseVersionHeader = "## [" + version + "] - " + releaseDate;
string releaseVersionHeader = string.Concat("## [", version, "] - ", releaseDate);

return releaseVersionHeader;
}
Expand Down Expand Up @@ -396,9 +392,7 @@ private static string CurrentDate()

private static int FindInsertPosition(string releaseVersionToFind, IReadOnlyDictionary<string, int> releases, int endOfFilePosition)
{
string? latestRelease = releases.Keys.Where(x => x != Constants.Unreleased)
.OrderByDescending(x => new Version(x))
.FirstOrDefault();
string? latestRelease = GetLatestRelease(releases);

int releaseInsertPos;

Expand All @@ -411,12 +405,12 @@ private static int FindInsertPosition(string releaseVersionToFind, IReadOnlyDict

if (latestNumeric == numericalVersion)
{
throw new ReleaseAlreadyExistsException($"Release {releaseVersionToFind} already exists");
return ReleaseAlreadyExists(releaseVersionToFind);
}

if (latestNumeric > numericalVersion)
{
throw new ReleaseTooOldException($"Release {latestRelease} already exists and is newer than {releaseVersionToFind}");
return ReleaseTooOld(releaseVersionToFind: releaseVersionToFind, latestRelease: latestRelease);
}

releaseInsertPos = releases[latestRelease];
Expand All @@ -429,20 +423,50 @@ private static int FindInsertPosition(string releaseVersionToFind, IReadOnlyDict
return releaseInsertPos;
}

[DoesNotReturn]
private static int ReleaseTooOld(string releaseVersionToFind, string latestRelease)
{
throw new ReleaseTooOldException($"Release {latestRelease} already exists and is newer than {releaseVersionToFind}");
}

[DoesNotReturn]
private static int ReleaseAlreadyExists(string releaseVersionToFind)
{
throw new ReleaseAlreadyExistsException($"Release {releaseVersionToFind} already exists");
}

private static string? GetLatestRelease(IReadOnlyDictionary<string, int> releases)
{
return releases.Keys.Where(x => x != Constants.Unreleased)
.OrderByDescending(x => new Version(x))
.FirstOrDefault();
}

private static Dictionary<string, int> FindReleasePositions(IReadOnlyList<string> text)
{
Dictionary<string, int> releases = text.Select((line, index) => new { line, index })
.Where(i => IsRelease(i.line))
.ToDictionary(keySelector: i => ExtractRelease(i.line), elementSelector: i => i.index, comparer: StringComparer.Ordinal);
Dictionary<string, int> releases = GetReleasePositions(text);

if (releases.Count == 0)
{
throw new EmptyChangeLogException("Could not find unreleased section");
return CouldNotFindUnreleasedSection();
}

return releases;
}

[DoesNotReturn]
private static Dictionary<string, int> CouldNotFindUnreleasedSection()
{
throw new EmptyChangeLogException("Could not find unreleased section");
}

private static Dictionary<string, int> GetReleasePositions(IReadOnlyList<string> text)
{
return text.Select((line, index) => new { line, index })
.Where(i => IsRelease(i.line))
.ToDictionary(keySelector: i => ExtractRelease(i.line), elementSelector: i => i.index, comparer: StringComparer.Ordinal);
}

private static string ExtractRelease(string line)
{
if (line == Constants.UnreleasedHeader)
Expand Down
Loading