Skip to content

Commit 294f800

Browse files
committedMar 9, 2024
refactored
1 parent e6cf936 commit 294f800

17 files changed

+395
-42
lines changed
 

‎GitffHistory.Experiment/Controllers/HomeController.cs

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,34 @@
11
using Microsoft.AspNetCore.Mvc;
22
using GitffHistory.Experiment.Domain;
33
using GitffHistory.Experiment.ViewModels;
4+
using GitffHistory.Experiment.IO;
5+
using GitffHistory.Experiment.Models;
46

57
namespace GitffHistory.Experiment.Controllers
68
{
79
public class HomeController : Controller
810
{
911
private readonly ILogger<HomeController> _logger;
1012
private readonly IDiffFiles commitDiffer;
13+
private readonly IReadFiles<Commit> readCommits;
1114

12-
public HomeController(ILogger<HomeController> logger, IDiffFiles compareFiles)
15+
public HomeController(
16+
ILogger<HomeController> logger,
17+
IDiffFiles compareFiles,
18+
IReadFiles<Commit> readFiles)
1319
{
1420
_logger = logger;
1521
this.commitDiffer = compareFiles;
22+
this.readCommits = readFiles;
1623
}
1724

1825
public IActionResult Index()
1926
{
20-
var viewModel = new IndexVewModel(commitDiffer.Diff());
27+
var viewModel = new IndexVewModel(
28+
commitDiffer.Diff(
29+
commitDiffer.BuildParentCurrentHierachi(
30+
readCommits.LoadCommits())));
31+
2132
viewModel.Prettify();
2233

2334
return View(viewModel);

‎GitffHistory.Experiment/Domain/CommitDiffer.cs

+18-17
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,36 @@ namespace GitffHistory.Experiment.Domain
55
{
66
public interface IDiffFiles
77
{
8-
List<Diff> Diff();
8+
List<Diff> Diff(List<Diff> diffs);
9+
List<Diff> BuildParentCurrentHierachi(List<Commit> commits);
910
}
1011

1112
public class CommitDiffer : IDiffFiles
1213
{
13-
private readonly IReadFiles<Commit> commitReader;
14-
15-
public CommitDiffer(IReadFiles<Commit> commitReader)
14+
public List<Diff> Diff(List<Diff> diffs)
1615
{
17-
this.commitReader = commitReader;
16+
EugeneMyersDiffAlgorithm diffAlgorithm = new();
17+
18+
foreach (var d in diffs)
19+
{
20+
d.Diffs = diffAlgorithm.DiffText(d.Parent.RawFileContents, d.Current.RawFileContents);
21+
}
22+
23+
return diffs;
1824
}
1925

20-
public List<Diff> Diff()
26+
public List<Diff> BuildParentCurrentHierachi(List<Commit> commits)
2127
{
22-
var files = commitReader.ReadFilesFromDirectory();
23-
var result = new List<Diff>();
24-
EugeneMyers eugeneMyers = new EugeneMyers(); // yes yes, we could interface this
28+
List<Diff> result = new();
2529

26-
for (var i = 0; i < files.Count; i++)
30+
for (var i = 0; i < commits.Count(); i++)
2731
{
28-
var diff = new Diff();
29-
var history = files[i];
30-
diff.History = history;
32+
Diff diff = new();
3133

32-
if (i + 1 < files.Count)
34+
diff.Parent = commits[i];
35+
if (i + 1 < commits.Count())
3336
{
34-
var current = files[i + 1];
35-
diff.Diffs = eugeneMyers.DiffText(history.RawFileContents, current.RawFileContents);
36-
diff.Current = current;
37+
diff.Current = commits[i + 1];
3738
}
3839

3940
result.Add(diff);

‎GitffHistory.Experiment/Domain/EugeneMyers.cs ‎GitffHistory.Experiment/Domain/EugeneMyersDiffAlgorithm.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace GitffHistory.Experiment.Domain
55
{
66
/// Copyright (c) by Matthias Hertel, http://www.mathertel.de
77
/// This work is licensed under a BSD style license. See http://www.mathertel.de/License.aspx
8-
public class EugeneMyers
8+
public class EugeneMyersDiffAlgorithm
99
{
1010
/// <summary>details of one difference.</summary>
1111
public struct Item

‎GitffHistory.Experiment/IO/CommitsReader.cs

+26-18
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ namespace GitffHistory.Experiment.IO
44
{
55
public interface IReadFiles<T> where T : class
66
{
7-
List<T> ReadFilesFromDirectory();
7+
List<T> LoadCommits();
8+
T LoadCommit(string filePath);
89
}
910

1011
public class CommitsReader : IReadFiles<Commit>
@@ -13,31 +14,38 @@ public class CommitsReader : IReadFiles<Commit>
1314
AppDomain.CurrentDomain.BaseDirectory,
1415
Path.DirectorySeparatorChar,
1516
"Commits");
16-
17-
public List<Commit> ReadFilesFromDirectory()
17+
18+
/// <summary>
19+
/// Ordered by filename, descending
20+
/// </summary>
21+
/// <returns></returns>
22+
/// <exception cref="DirectoryNotFoundException"></exception>
23+
public List<Commit> LoadCommits()
1824
{
19-
List<Commit> commits = new List<Commit>();
20-
21-
if (!Directory.Exists(filesPath))
22-
{
23-
throw new DirectoryNotFoundException($"The directory '{filesPath}' was not found.");
24-
}
25-
2625
string[] filePaths = Directory.GetFiles(filesPath);
2726

27+
List<Commit> commits = new();
28+
2829
foreach (var filePath in filePaths)
2930
{
30-
string lines = File.ReadAllText(filePath);
31-
32-
var commit = new Commit();
33-
commit.RawFileContents = lines;
34-
commit.FileName = Path.GetFileName(filePath);
35-
commits.Add(commit);
31+
commits.Add(
32+
LoadCommit(filePath)
33+
);
3634
}
3735

38-
var orderedByFilenames = commits.OrderByDescending(f => f.FileName).ToList();
36+
// 4, 3, 2, 1....descending order
37+
return commits.OrderByDescending(f => f.FileName).ToList();
38+
}
3939

40-
return orderedByFilenames;
40+
public Commit LoadCommit(string filePath)
41+
{
42+
var commitContent = File.ReadAllText(filePath);
43+
44+
return new Commit()
45+
{
46+
RawFileContents = commitContent,
47+
FileName = Path.GetFileName(filePath)
48+
};
4149
}
4250
}
4351
}

‎GitffHistory.Experiment/Models/Diff.cs

+5-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22

33
namespace GitffHistory.Experiment.Models
44
{
5+
/// <summary>
6+
/// This type is a representation of two commits and the changes between them.
7+
/// </summary>
58
public class Diff
69
{
710
public Commit Current { get; set; } = new Commit();
8-
public Commit History { get; set; } = new Commit();
9-
public EugeneMyers.Item[] Diffs { get; internal set; } = new EugeneMyers.Item[] { };
11+
public Commit Parent { get; set; } = new Commit();
12+
public EugeneMyersDiffAlgorithm.Item[] Diffs { get; internal set; } = new EugeneMyersDiffAlgorithm.Item[] { };
1013
}
1114
}

‎GitffHistory.Experiment/ViewModels/IndexVewModel.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public void Prettify()
2323

2424
var result = new List<LineDetail>() { new LineDetail() };
2525

26-
var linesToExcercise = commit.History.RawFileContents.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None);
26+
var linesToExcercise = commit.Parent.RawFileContents.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None);
2727

2828
for (int i = 0; i < linesToExcercise.Length; i++)
2929
{
@@ -45,7 +45,7 @@ public void Prettify()
4545
result.Add(detail);
4646
}
4747

48-
fileChanges.HistoryFilename = commit.History.FileName;
48+
fileChanges.HistoryFilename = commit.Parent.FileName;
4949
fileChanges.History.AddRange(result);
5050

5151

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
namespace GitffHistory.Tests;
2+
public class CommitDiffCustomization : ICustomization
3+
{
4+
public void Customize(IFixture fixture)
5+
{
6+
CommitReaderStub readerStub = new CommitReaderStub();
7+
var commits = readerStub.LoadCommits();
8+
fixture.Register(() => commits);
9+
10+
CommitDiffer commitDiffer = new CommitDiffer();
11+
var diffs = commitDiffer.BuildParentCurrentHierachi(commits);
12+
fixture.Register(() => diffs);
13+
}
14+
}
+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
namespace GitffHistory.Tests;
2+
3+
public class CommitDifferTests
4+
{
5+
[Theory]
6+
[DiffsData]
7+
public void Previous_Commit_Is_Not_The_Same_As_Current_Commit(
8+
List<Diff> autoDiffs,
9+
CommitDiffer sut)
10+
{
11+
var diffs = sut.Diff(autoDiffs);
12+
13+
diffs.ForEach(e => {
14+
Assert.NotEqual(e.Current.FileName, e.Parent.FileName);
15+
});
16+
}
17+
18+
[Theory]
19+
[DiffsData]
20+
public void History_Commits_Are_In_Descending_Order(
21+
List<Commit> autoCommits,
22+
CommitDiffer sut)
23+
{
24+
var diffs = sut.BuildParentCurrentHierachi(autoCommits);
25+
26+
// find the number in the filename; 999_jsjsjjs.txt, should return 999.
27+
var fileNumbers = diffs.Select(s =>
28+
Convert.ToInt32(s.Parent.FileName.Substring(0, s.Parent.FileName.IndexOf('_'))))
29+
.ToList();
30+
31+
for (int i = 0; i < fileNumbers.Count() - 1; i++)
32+
{
33+
if (fileNumbers[i] < fileNumbers[i + 1])
34+
{
35+
Assert.Fail("numbers are not descending");
36+
}
37+
}
38+
}
39+
}
+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
namespace GitffHistory.Tests;
2+
3+
public class CommitReaderStub : IReadFiles<Commit>
4+
{
5+
private string filesPath = string.Concat(
6+
AppDomain.CurrentDomain.BaseDirectory,
7+
"StubData",
8+
Path.DirectorySeparatorChar,
9+
"Commits");
10+
11+
public Commit LoadCommit(string filePath)
12+
{
13+
throw new NotImplementedException();
14+
}
15+
16+
public List<Commit> LoadCommits()
17+
{
18+
List<Commit> commits = new List<Commit>();
19+
20+
if (!Directory.Exists(filesPath))
21+
{
22+
throw new DirectoryNotFoundException($"The directory '{filesPath}' was not found.");
23+
}
24+
25+
string[] filePaths = Directory.GetFiles(filesPath);
26+
27+
foreach (var filePath in filePaths)
28+
{
29+
string lines = File.ReadAllText(filePath);
30+
31+
var commit = new Commit();
32+
commit.RawFileContents = lines;
33+
commit.FileName = Path.GetFileName(filePath);
34+
commits.Add(commit);
35+
}
36+
37+
var orderedByFilenames = commits.OrderByDescending(f => f.FileName).ToList();
38+
39+
return orderedByFilenames;
40+
}
41+
}
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace GitffHistory.Tests;
2+
3+
public class DiffsDataAttribute : AutoDataAttribute
4+
{
5+
public DiffsDataAttribute()
6+
: base(() => new Fixture().Customize(new CommitDiffCustomization()))
7+
{
8+
}
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net7.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
8+
<IsPackable>false</IsPackable>
9+
<IsTestProject>true</IsTestProject>
10+
</PropertyGroup>
11+
12+
<ItemGroup>
13+
<PackageReference Include="AutoFixture.Xunit2" Version="4.18.1" />
14+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
15+
<PackageReference Include="xunit" Version="2.4.2" />
16+
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
17+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
18+
<PrivateAssets>all</PrivateAssets>
19+
</PackageReference>
20+
<PackageReference Include="coverlet.collector" Version="3.2.0">
21+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
22+
<PrivateAssets>all</PrivateAssets>
23+
</PackageReference>
24+
</ItemGroup>
25+
26+
<ItemGroup>
27+
<ProjectReference Include="..\GitffHistory.Experiment\GitffHistory.Experiment.csproj" />
28+
</ItemGroup>
29+
30+
<ItemGroup>
31+
<None Update="StubData\Commits\1_09176abef779f31035ed8517c099ec1c9e62cf81.txt">
32+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
33+
</None>
34+
<None Update="StubData\Commits\2_db34c323c336d648e40d5d8c5005fee656bd923c.txt">
35+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
36+
</None>
37+
<None Update="StubData\Commits\3_144811de245d02dd105eae5c89d95768105538d8.txt">
38+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
39+
</None>
40+
<None Update="StubData\Commits\4_5858bd7f3067c1908ed3a2b836031ea195705783.txt">
41+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
42+
</None>
43+
</ItemGroup>
44+
45+
</Project>

‎GitffHistory.Tests/GlobalUsings.cs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
global using Xunit;
2+
global using GitffHistory.Experiment.Domain;
3+
global using GitffHistory.Experiment.Models;
4+
global using AutoFixture;
5+
global using AutoFixture.Xunit2;
6+
global using GitffHistory.Experiment.IO;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
namespace Miniblog.Core.Markdown;
2+
3+
public interface IParseMarkdownToPost
4+
{
5+
Task<List<MarkdownPost>> ParseMarkdownToPost();
6+
}
7+
8+
public class ParseMarkdownToPostService : IParseMarkdownToPost
9+
{
10+
private readonly IGithubContentsService githubContentsService;
11+
private readonly IDownloadMarkdown markdownDownloadService;
12+
public ParseMarkdownToPostService(IGithubContentsService githubContentsService, IDownloadMarkdown markdownDownloadService)
13+
{
14+
this.markdownDownloadService = markdownDownloadService;
15+
this.githubContentsService = githubContentsService;
16+
}
17+
18+
public async Task<List<MarkdownPost>> ParseMarkdownToPost()
19+
{
20+
await githubContentsService.LoadContents();
21+
22+
var contents = await markdownDownloadService.DownloadMarkdownAsync(
23+
githubContentsService.GithubContents.Select(d => new Uri(d.DownloadUrl)));
24+
25+
var intermediatePosts = new List<MarkdownPost>();
26+
27+
foreach (var item in contents)
28+
{
29+
var parser = new MarkdownBlogpostParser(item);
30+
31+
await parser.ParseCommentsAsPropertiesAsync();
32+
await parser.ParseContent();
33+
34+
intermediatePosts.Add(parser.MarkdownPost);
35+
}
36+
37+
return intermediatePosts;
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
namespace Miniblog.Core.Markdown;
2+
3+
public interface IParseMarkdownToPost
4+
{
5+
Task<List<MarkdownPost>> GetMarkdownPosts();
6+
}
7+
8+
public class MarkdownPostService : IParseMarkdownToPost
9+
{
10+
private readonly IGithubContentsApi githubContentsService;
11+
private readonly IDownloadMarkdown markdownDownloadService;
12+
public MarkdownPostService(IGithubContentsApi githubContentsService, IDownloadMarkdown markdownDownloadService)
13+
{
14+
this.markdownDownloadService = markdownDownloadService;
15+
this.githubContentsService = githubContentsService;
16+
}
17+
18+
public async Task<List<MarkdownPost>> GetMarkdownPosts()
19+
{
20+
await githubContentsService.LoadContents();
21+
22+
var contents = await markdownDownloadService.DownloadMarkdownAsync(
23+
githubContentsService.GithubContents.Select(d => new Uri(d.DownloadUrl)));
24+
25+
var intermediatePosts = new List<MarkdownPost>();
26+
27+
foreach (var item in contents)
28+
{
29+
var parser = new MarkdownBlogpostParser(item);
30+
31+
await parser.ParseCommentsAsPropertiesAsync();
32+
await parser.ParseContent();
33+
34+
intermediatePosts.Add(parser.MarkdownPost);
35+
}
36+
37+
return intermediatePosts;
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
namespace Miniblog.Core.Markdown;
2+
3+
using Microsoft.VisualBasic;
4+
5+
public interface IParseMarkdownToPost
6+
{
7+
Task<List<MarkdownPost>> ParseMarkdownToPost();
8+
}
9+
10+
public class ParseMarkdownToPostService : IParseMarkdownToPost
11+
{
12+
private readonly IGithubContentsService githubContentsService;
13+
private readonly IDownloadMarkdown markdownDownloadService;
14+
public ParseMarkdownToPostService(IGithubContentsService githubContentsService, IDownloadMarkdown markdownDownloadService)
15+
{
16+
this.markdownDownloadService = markdownDownloadService;
17+
this.githubContentsService = githubContentsService;
18+
}
19+
20+
public async Task<List<MarkdownPost>> ParseMarkdownToPost()
21+
{
22+
await githubContentsService.LoadContents();
23+
24+
var contents = await markdownDownloadService.DownloadMarkdownAsync(
25+
githubContentsService.GithubContents.Select(d => new Uri(d.DownloadUrl)));
26+
27+
return await ParseMarkdownToPost(contents);
28+
}
29+
30+
public async Task<List<MarkdownPost>> ParseMarkdownToPost(List<MardownFile> markdownFiles)
31+
{
32+
var intermediatePosts = new List<MarkdownPost>();
33+
34+
foreach (var item in markdownFiles)
35+
{
36+
var parser = new MarkdownBlogpostParser(item.Contents);
37+
38+
await parser.ParseCommentsAsPropertiesAsync();
39+
await parser.ParseContent();
40+
41+
intermediatePosts.Add(parser.MarkdownPost);
42+
}
43+
44+
return intermediatePosts;
45+
}
46+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
namespace Miniblog.Core.Markdown;
2+
3+
using Microsoft.VisualBasic;
4+
5+
public interface IParseMarkdownToPost
6+
{
7+
Task<List<MarkdownPost>> ParseMarkdownToPost();
8+
}
9+
10+
public class ParseMarkdownToPostService : IParseMarkdownToPost
11+
{
12+
private readonly IGithubContentsService githubContentsService;
13+
private readonly IDownloadMarkdown markdownDownloadService;
14+
public ParseMarkdownToPostService(IGithubContentsService githubContentsService, IDownloadMarkdown markdownDownloadService)
15+
{
16+
this.markdownDownloadService = markdownDownloadService;
17+
this.githubContentsService = githubContentsService;
18+
}
19+
20+
public async Task<List<MarkdownPost>> ParseMarkdownToPost()
21+
{
22+
await githubContentsService.LoadContents();
23+
24+
var contents = await markdownDownloadService.DownloadMarkdownAsync(
25+
githubContentsService.GithubContents.Select(d => new Uri(d.DownloadUrl)));
26+
27+
return await ParseMarkdownToPost(contents);
28+
}
29+
30+
public async Task<List<MarkdownPost>> ParseMarkdownToPost(List<string> markdownFiles)
31+
{
32+
var intermediatePosts = new List<MarkdownPost>();
33+
34+
foreach (var item in markdownFiles)
35+
{
36+
var parser = new MarkdownBlogpostParser(item);
37+
38+
await parser.ParseCommentsAsPropertiesAsync();
39+
await parser.ParseContent();
40+
41+
intermediatePosts.Add(parser.MarkdownPost);
42+
}
43+
44+
return intermediatePosts;
45+
}
46+
}

‎GitffHistory.sln

+6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ VisualStudioVersion = 17.8.34330.188
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GitffHistory.Experiment", "GitffHistory.Experiment\GitffHistory.Experiment.csproj", "{6DDB46B1-BEA8-4F62-BB9F-F379940C54FA}"
77
EndProject
8+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitffHistory.Tests", "GitffHistory.Tests\GitffHistory.Tests.csproj", "{3961527B-5B34-45AE-90D7-C7716E8D4093}"
9+
EndProject
810
Global
911
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1012
Debug|Any CPU = Debug|Any CPU
@@ -15,6 +17,10 @@ Global
1517
{6DDB46B1-BEA8-4F62-BB9F-F379940C54FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
1618
{6DDB46B1-BEA8-4F62-BB9F-F379940C54FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
1719
{6DDB46B1-BEA8-4F62-BB9F-F379940C54FA}.Release|Any CPU.Build.0 = Release|Any CPU
20+
{3961527B-5B34-45AE-90D7-C7716E8D4093}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21+
{3961527B-5B34-45AE-90D7-C7716E8D4093}.Debug|Any CPU.Build.0 = Debug|Any CPU
22+
{3961527B-5B34-45AE-90D7-C7716E8D4093}.Release|Any CPU.ActiveCfg = Release|Any CPU
23+
{3961527B-5B34-45AE-90D7-C7716E8D4093}.Release|Any CPU.Build.0 = Release|Any CPU
1824
EndGlobalSection
1925
GlobalSection(SolutionProperties) = preSolution
2026
HideSolutionNode = FALSE

0 commit comments

Comments
 (0)
Please sign in to comment.