Merge pull request 'added PDF output, tag filtering functionality' (#6) from staging into master
Reviewed-on: #6
This commit is contained in:
commit
022f3a8937
@ -93,11 +93,19 @@ public class CommitDetail
|
|||||||
{
|
{
|
||||||
var branchResult = repo.Branches[branchName];
|
var branchResult = repo.Branches[branchName];
|
||||||
|
|
||||||
if (branchResult == null)
|
try
|
||||||
{
|
{
|
||||||
branchResult = repo.Branches[$"origin/{branchName}"];
|
if (branchResult == null)
|
||||||
var remoteBranch = repo.CreateBranch(branchName, branchResult.Tip);
|
{
|
||||||
repo.Branches.Update(remoteBranch, b => b.UpstreamBranch = $"refs/heads/{branchName}");
|
branchResult = repo.Branches[$"origin/{branchName}"];
|
||||||
|
var remoteBranch = repo.CreateBranch(branchName, branchResult.Tip);
|
||||||
|
repo.Branches.Update(remoteBranch, b => b.UpstreamBranch = $"refs/heads/{branchName}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (System.Exception)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Cannot fetch {branchName} branch.");
|
||||||
|
Environment.Exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var c in branchResult.Commits)
|
foreach (var c in branchResult.Commits)
|
||||||
@ -120,8 +128,36 @@ public class CommitDetail
|
|||||||
{
|
{
|
||||||
using (var repo = new Repository(Directory.GetCurrentDirectory()))
|
using (var repo = new Repository(Directory.GetCurrentDirectory()))
|
||||||
{
|
{
|
||||||
var tagResult = repo.Tags[tagName];
|
try
|
||||||
System.Console.WriteLine(tagResult);
|
{
|
||||||
|
var tagResult = repo.Tags[tagName].Target.Sha;
|
||||||
|
|
||||||
|
var commitFilter = new CommitFilter
|
||||||
|
{
|
||||||
|
IncludeReachableFrom = tagResult,
|
||||||
|
};
|
||||||
|
|
||||||
|
var query = repo.Commits.QueryBy(commitFilter);
|
||||||
|
|
||||||
|
foreach (var c in query)
|
||||||
|
{
|
||||||
|
if (!_authors.Contains(c.Author.Name))
|
||||||
|
{
|
||||||
|
_authors.Add(c.Author.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var a in _authors)
|
||||||
|
{
|
||||||
|
int commitCount = query.Where(r => r.Author.Name == a).Count();
|
||||||
|
_commitDetails.Add(a, commitCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (System.Exception)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Cannot find the tag {tagName}");
|
||||||
|
Environment.Exit(3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
43
DAL/PdfDataService.cs
Normal file
43
DAL/PdfDataService.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
using PdfSharpCore.Drawing;
|
||||||
|
using PdfSharpCore.Pdf;
|
||||||
|
|
||||||
|
public class PdfDataService : IDataService
|
||||||
|
{
|
||||||
|
private string _fileName;
|
||||||
|
private string _pathName;
|
||||||
|
private string _dateTime;
|
||||||
|
|
||||||
|
public PdfDataService()
|
||||||
|
{
|
||||||
|
_dateTime = DateTime.Now.ToString("yyyyMMddhhmm");
|
||||||
|
_fileName = $"CommitReport-{_dateTime}.pdf";
|
||||||
|
_pathName = Directory.GetCurrentDirectory() + "/" + _fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteAll(SortedList<string, int> dictResults)
|
||||||
|
{
|
||||||
|
// sort the dictionary passed in
|
||||||
|
var sortedResults = dictResults.OrderByDescending(d => d.Value).ToList();
|
||||||
|
|
||||||
|
// setting the created document
|
||||||
|
var document = new PdfDocument();
|
||||||
|
var page = document.AddPage();
|
||||||
|
|
||||||
|
// heading
|
||||||
|
var gfx = XGraphics.FromPdfPage(page);
|
||||||
|
var fontHeading = new XFont("Times New Roman", 36, XFontStyle.Underline);
|
||||||
|
gfx.DrawString("Commit Report", fontHeading, XBrushes.Black, new XRect(0, 0, page.Width, page.Height), XStringFormats.TopCenter);
|
||||||
|
|
||||||
|
// details
|
||||||
|
var fontDetails = new XFont("Times New Roman", 16, XFontStyle.Regular);
|
||||||
|
int positionValue = 50;
|
||||||
|
|
||||||
|
foreach (var i in sortedResults)
|
||||||
|
{
|
||||||
|
gfx.DrawString($"{i.Key}: {i.Value}", fontDetails, XBrushes.Black, new XRect(0, positionValue, page.Width, page.Width), XStringFormats.TopCenter);
|
||||||
|
positionValue += 25;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.Save(_fileName);
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,7 @@
|
|||||||
<PackageReference Include="Libgit2sharp" Version="0.27.0-preview-0182" />
|
<PackageReference Include="Libgit2sharp" Version="0.27.0-preview-0182" />
|
||||||
<PackageReference Include="LibGit2Sharp.NativeBinaries" Version="2.0.315-alpha.0.9" />
|
<PackageReference Include="LibGit2Sharp.NativeBinaries" Version="2.0.315-alpha.0.9" />
|
||||||
<PackageReference Include="Pastel" Version="3.0.1" />
|
<PackageReference Include="Pastel" Version="3.0.1" />
|
||||||
|
<PackageReference Include="PdfSharpCore" Version="1.3.32" />
|
||||||
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
|
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
105
Program.cs
105
Program.cs
@ -7,7 +7,7 @@ static class Program
|
|||||||
var outputOption = new Option<string>(
|
var outputOption = new Option<string>(
|
||||||
"--output",
|
"--output",
|
||||||
"Specify the output given to the user"
|
"Specify the output given to the user"
|
||||||
).FromAmong("stdout", "xlsx");
|
).FromAmong("stdout", "xlsx", "pdf");
|
||||||
outputOption.AddAlias("-o");
|
outputOption.AddAlias("-o");
|
||||||
|
|
||||||
var branchOption = new Option<string>(
|
var branchOption = new Option<string>(
|
||||||
@ -16,13 +16,20 @@ static class Program
|
|||||||
);
|
);
|
||||||
branchOption.AddAlias("-b");
|
branchOption.AddAlias("-b");
|
||||||
|
|
||||||
|
var tagOption = new Option<string>(
|
||||||
|
"--tag",
|
||||||
|
"Specify the tag to filter by"
|
||||||
|
);
|
||||||
|
tagOption.AddAlias("-t");
|
||||||
|
|
||||||
var rootCommand = new RootCommand("Get a tally of contributors' commits")
|
var rootCommand = new RootCommand("Get a tally of contributors' commits")
|
||||||
{
|
{
|
||||||
outputOption,
|
outputOption,
|
||||||
branchOption,
|
branchOption,
|
||||||
|
tagOption,
|
||||||
};
|
};
|
||||||
|
|
||||||
rootCommand.SetHandler((outputOptionValue, branchOptionValue) => {
|
rootCommand.SetHandler((outputOptionValue, branchOptionValue, tagOptionValue) => {
|
||||||
CommitDetail commits = new CommitDetail();
|
CommitDetail commits = new CommitDetail();
|
||||||
|
|
||||||
switch (outputOptionValue)
|
switch (outputOptionValue)
|
||||||
@ -31,31 +38,65 @@ static class Program
|
|||||||
StdOutDataService outDataService = new StdOutDataService();
|
StdOutDataService outDataService = new StdOutDataService();
|
||||||
DataAccess dataAccess = new DataAccess(outDataService);
|
DataAccess dataAccess = new DataAccess(outDataService);
|
||||||
|
|
||||||
switch (branchOptionValue)
|
if (branchOptionValue != null && tagOptionValue != null) {
|
||||||
{
|
Console.WriteLine("Please specify either a branch or a tag");
|
||||||
case null:
|
Environment.Exit(2);
|
||||||
commits.GetCurrentCommitsByName();
|
} else if (branchOptionValue != null && tagOptionValue == null) {
|
||||||
dataAccess.WriteData(commits.CommitDetails);
|
switch (branchOptionValue)
|
||||||
break;
|
{
|
||||||
default:
|
case null:
|
||||||
commits.GetCommitsByBranch(branchOptionValue);
|
commits.GetCurrentCommitsByName();
|
||||||
dataAccess.WriteData(commits.CommitDetails);
|
dataAccess.WriteData(commits.CommitDetails);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
commits.GetCommitsByBranch(branchOptionValue);
|
||||||
|
dataAccess.WriteData(commits.CommitDetails);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else if (branchOptionValue == null && tagOptionValue != null) {
|
||||||
|
commits.GetCommitsByTag(tagOptionValue);
|
||||||
|
dataAccess.WriteData(commits.CommitDetails);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "xlsx":
|
case "xlsx":
|
||||||
ExcelDataService excelDataService = new ExcelDataService();
|
ExcelDataService excelDataService = new ExcelDataService();
|
||||||
DataAccess dataAccessExcelCase = new DataAccess(excelDataService);
|
DataAccess dataAccessExcelCase = new DataAccess(excelDataService);
|
||||||
|
|
||||||
|
if (branchOptionValue != null && tagOptionValue != null) {
|
||||||
|
Console.WriteLine("Please specify either a branch or a tag.");
|
||||||
|
Environment.Exit(2);
|
||||||
|
} else if (branchOptionValue != null && tagOptionValue == null) {
|
||||||
|
switch (branchOptionValue)
|
||||||
|
{
|
||||||
|
case null:
|
||||||
|
commits.GetCurrentCommitsByName();
|
||||||
|
dataAccessExcelCase.WriteData(commits.CommitDetails);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
commits.GetCommitsByBranch(branchOptionValue);
|
||||||
|
dataAccessExcelCase.WriteData(commits.CommitDetails);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else if (branchOptionValue == null && tagOptionValue != null) {
|
||||||
|
commits.GetCommitsByTag(tagOptionValue);
|
||||||
|
dataAccessExcelCase.WriteData(commits.CommitDetails);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "pdf":
|
||||||
|
PdfDataService pdfDataService = new PdfDataService();
|
||||||
|
DataAccess dataAccessPdfCase = new DataAccess(pdfDataService);
|
||||||
|
|
||||||
switch (branchOptionValue)
|
switch (branchOptionValue)
|
||||||
{
|
{
|
||||||
case null:
|
case null:
|
||||||
commits.GetCurrentCommitsByName();
|
commits.GetCurrentCommitsByName();
|
||||||
dataAccessExcelCase.WriteData(commits.CommitDetails);
|
dataAccessPdfCase.WriteData(commits.CommitDetails);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
commits.GetCommitsByBranch(branchOptionValue);
|
commits.GetCommitsByBranch(branchOptionValue);
|
||||||
dataAccessExcelCase.WriteData(commits.CommitDetails);
|
dataAccessPdfCase.WriteData(commits.CommitDetails);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -63,25 +104,37 @@ static class Program
|
|||||||
StdOutDataService stdOutDataService = new StdOutDataService();
|
StdOutDataService stdOutDataService = new StdOutDataService();
|
||||||
DataAccess dataAccessNullCase = new DataAccess(stdOutDataService);
|
DataAccess dataAccessNullCase = new DataAccess(stdOutDataService);
|
||||||
|
|
||||||
switch (branchOptionValue)
|
if (branchOptionValue != null && tagOptionValue != null) {
|
||||||
{
|
Console.WriteLine("Please specify either a branch or a tag.");
|
||||||
case null:
|
Environment.Exit(2);
|
||||||
commits.GetCurrentCommitsByName();
|
} else if (branchOptionValue != null && tagOptionValue == null) {
|
||||||
dataAccessNullCase.WriteData(commits.CommitDetails);
|
switch (branchOptionValue)
|
||||||
break;
|
{
|
||||||
default:
|
case null:
|
||||||
commits.GetCommitsByBranch(branchOptionValue);
|
commits.GetCurrentCommitsByName();
|
||||||
dataAccessNullCase.WriteData(commits.CommitDetails);
|
dataAccessNullCase.WriteData(commits.CommitDetails);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
commits.GetCommitsByBranch(branchOptionValue);
|
||||||
|
dataAccessNullCase.WriteData(commits.CommitDetails);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else if (branchOptionValue == null && tagOptionValue != null) {
|
||||||
|
commits.GetCommitsByTag(tagOptionValue);
|
||||||
|
dataAccessNullCase.WriteData(commits.CommitDetails);
|
||||||
|
} else {
|
||||||
|
commits.GetCurrentCommitsByName();
|
||||||
|
dataAccessNullCase.WriteData(commits.CommitDetails);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
System.Console.WriteLine("This should not happen...");
|
System.Console.WriteLine("This should not happen...");
|
||||||
Environment.Exit(90);
|
Environment.Exit(4);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
outputOption, branchOption);
|
outputOption, branchOption, tagOption);
|
||||||
|
|
||||||
rootCommand.Invoke(args);
|
rootCommand.Invoke(args);
|
||||||
}
|
}
|
||||||
|
71
README.md
71
README.md
@ -9,6 +9,7 @@ Licensed by the Mozilla Public License v2.0 (see [LICENSE](./LICENSE.md))
|
|||||||
###### Table of Contents
|
###### Table of Contents
|
||||||
|
|
||||||
- [Overview](#overview)
|
- [Overview](#overview)
|
||||||
|
- [Usage](#usage)
|
||||||
- [Installation](#installation)
|
- [Installation](#installation)
|
||||||
- [Release](#release)
|
- [Release](#release)
|
||||||
- [Source](#source)
|
- [Source](#source)
|
||||||
@ -24,17 +25,65 @@ Licensed by the Mozilla Public License v2.0 (see [LICENSE](./LICENSE.md))
|
|||||||
|
|
||||||
When I was in university, I wanted a program that would tally up my git commits in a certain project that I'm working on. Based on search engine ninja skills, I couldn't find a program that did this. I decided to scratch my own itch.
|
When I was in university, I wanted a program that would tally up my git commits in a certain project that I'm working on. Based on search engine ninja skills, I couldn't find a program that did this. I decided to scratch my own itch.
|
||||||
|
|
||||||
I present DrillSergeant, where you can get a tally of the contributors' commits in a certain project. Additionally, you can filter by branch to get commits by branch.
|
I present DrillSergeant. This is a command-line application to tally up commits, ordered by commit count per contributor. In other words, DrillSergeant orders the contributors by how many commits they have made in descending order. For example, the first contributor listed will have the most commits in the project. The second contributor will have the second most commits, and so on.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Please see the wiki for information.
|
To use this command-line application, you must be in a git project. Otherwise, a nasty error will appear and you won't get your report. You can filter by branch or by tag (cannot be both, another nasty error appears here). You can get your report in your terminal, in a spreadsheet, or a PDF.
|
||||||
|
|
||||||
|
### Command-line arguments
|
||||||
|
|
||||||
|
```bash
|
||||||
|
-o, --output <pdf|stdout|xlsx> Specify the output given to the user
|
||||||
|
-b, --branch <branch> Specify the branch to filter by
|
||||||
|
-t, --tag <tag> Specify the tag to filter by
|
||||||
|
```
|
||||||
|
|
||||||
|
Throw the `-h` flag for quick assistance. Throw the `--version` flag for version information.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
To get a commit report to your terminal:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
drillsergeant -o stdout
|
||||||
|
```
|
||||||
|
|
||||||
|
Or you can simply:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
drillsergeant
|
||||||
|
```
|
||||||
|
|
||||||
|
To get a commit report to your terminal filtered by the `devel` branch:
|
||||||
|
|
||||||
|
```
|
||||||
|
drillsergeant -b devel
|
||||||
|
```
|
||||||
|
|
||||||
|
To get a commit report to a spreadsheet:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
drillsergeant -o xlsx
|
||||||
|
```
|
||||||
|
|
||||||
|
To get a commit report to a PDF file filtered by the `devel` branch:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
drillsergeant -o pdf -b devel
|
||||||
|
```
|
||||||
|
|
||||||
|
Got too many contributors to fit onto your terminal? Run this by installing [bat](https://github.com/sharkdp/bat):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
drillsergeant | bat
|
||||||
|
```
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
There's are two forms of installation: releases and building from sources. This readme goes through both.
|
There's are two forms of installation: releases and building from sources. This readme goes through both.
|
||||||
|
|
||||||
### Releases
|
### Release
|
||||||
|
|
||||||
You may get releases from the [releases page](https://scm.wyattjmiller.com/wymiller/DrillSergeant/releases). This is the recommended way to start using DrillSergeant.
|
You may get releases from the [releases page](https://scm.wyattjmiller.com/wymiller/DrillSergeant/releases). This is the recommended way to start using DrillSergeant.
|
||||||
|
|
||||||
@ -42,6 +91,20 @@ There will be three separate downloads: Windows (x86 64-bit), Linux (x86 64-bit)
|
|||||||
|
|
||||||
Once downloaded and extracted, you can move it to your `$PATH`.
|
Once downloaded and extracted, you can move it to your `$PATH`.
|
||||||
|
|
||||||
|
On Windows (Powershell):
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Copy-Item drillsergeant C:\Windows\
|
||||||
|
```
|
||||||
|
|
||||||
|
On Linux:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp drillsergeant /usr/local/bin
|
||||||
|
```
|
||||||
|
|
||||||
|
The following commands assume you have elevated privileges.
|
||||||
|
|
||||||
If you do not have any of these platforms, read on to source installation as that's the next best option.
|
If you do not have any of these platforms, read on to source installation as that's the next best option.
|
||||||
|
|
||||||
### Source
|
### Source
|
||||||
@ -97,3 +160,5 @@ Thank you to the developers, engineers, project managers, and contributors of th
|
|||||||
- [OpenXML](https://docs.microsoft.com/en-us/office/open-xml/open-xml-sdk)
|
- [OpenXML](https://docs.microsoft.com/en-us/office/open-xml/open-xml-sdk)
|
||||||
- [System.CommandLine](https://github.com/dotnet/command-line-api)
|
- [System.CommandLine](https://github.com/dotnet/command-line-api)
|
||||||
- [Pastel](https://github.com/silkfire/Pastel)
|
- [Pastel](https://github.com/silkfire/Pastel)
|
||||||
|
- [PdfSharpCore](https://github.com/ststeiger/PdfSharpCore)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user