Skip to content

Commit

Permalink
feat: partial staged files #23
Browse files Browse the repository at this point in the history
  • Loading branch information
alirezanet committed Jan 27, 2022
1 parent e84a1b7 commit 385811c
Show file tree
Hide file tree
Showing 10 changed files with 366 additions and 80 deletions.
6 changes: 6 additions & 0 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@
"commands": [
"dotnet-format"
]
},
"csharpier": {
"version": "0.14.0",
"commands": [
"dotnet-csharpier"
]
}
}
}
17 changes: 16 additions & 1 deletion .husky/task-runner.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,25 @@
"args": ["husky", "exec", ".husky/csx/commit-lint.csx", "--args", "${args}"]
},
{
"name": "csharpier",
"command": "dotnet",
"group": "pre-commit",
"args": ["dotnet-format", "--include", "${staged}"],
"args": [ "csharpier", "${staged}" ],
"include": [ "**/*.cs" ]
},
{
"name": "dotnet-format",
"command": "dotnet",
"group": "pre-commit",
"args": ["dotnet-format", "--include" , "${staged}"],
"include": ["**/*.cs"]
},
{
"name": "echo staged files",
"pathMode": "absolute",
"command": "cmd",
"group": "pre-commit",
"args": [ "/c", "echo", "${staged}"],
}
]
}
7 changes: 7 additions & 0 deletions src/Husky/Services/Contracts/IGit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,20 @@ namespace Husky.Services.Contracts;

public interface IGit
{
Task<string[]> GetDiffNameOnlyAsync();
Task<string[]> GetStagedFilesAsync();
Task<string[]> GitFilesAsync();
Task<string[]> GetLastCommitFilesAsync();
Task<string> GetGitPathAsync();
Task<string> GetGitDirRelativePathAsync();
Task<string> GetCurrentBranchAsync();
Task<string> GetHuskyPathAsync();

/// <summary>
/// only file additions and modifications
/// </summary>
/// <returns></returns>
Task<string[]> GetDiffStagedRecord();
Task<CommandResult> ExecAsync(string args);
Task<BufferedCommandResult> ExecBufferedAsync(string args);
}
56 changes: 52 additions & 4 deletions src/Husky/Services/Git.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,25 @@ public Git(ICliWrap cliWrap)
_gitDirRelativePath = new AsyncLazy<string>(GetGitDirRelativePath);
}

public async Task<string[]> GetDiffNameOnlyAsync()
{
try
{
var result = await ExecBufferedAsync("diff --name-only");
if (result.ExitCode != 0)
throw new Exception($"Exit code: {result.ExitCode}"); // break execution

return result.StandardOutput
.Trim()
.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
}
catch (Exception e)
{
e.Message.LogVerbose(ConsoleColor.DarkRed);
throw new CommandException("git diff failed", innerException: e);
}
}

public async Task<string[]> GetStagedFilesAsync()
{
return await _stagedFiles;
Expand Down Expand Up @@ -65,6 +84,27 @@ public async Task<string> GetHuskyPathAsync()
return await _huskyPath;
}

public async Task<string[]> GetDiffStagedRecord()
{
try
{
var result = await ExecBufferedAsync(
"diff-index --cached --diff-filter=AM --no-renames HEAD"
);
if (result.ExitCode != 0)
throw new Exception($"Exit code: {result.ExitCode}"); // break execution

return result.StandardOutput
.Trim()
.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
}
catch (Exception e)
{
e.Message.LogVerbose(ConsoleColor.DarkRed);
throw new CommandException("Could not find the staged files", innerException: e);
}
}

private async Task<string> GetGitDirRelativePath()
{
try
Expand Down Expand Up @@ -151,7 +191,9 @@ private async Task<string[]> GetLastCommitFiles()
if (result.ExitCode != 0)
throw new Exception($"Exit code: {result.ExitCode}"); // break execution

return result.StandardOutput.Trim().Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
return result.StandardOutput
.Trim()
.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
}
catch (Exception e)
{
Expand All @@ -165,11 +207,15 @@ private async Task<string[]> GetStagedFiles()
try
{
// '--diff-filter=AM', # select only file additions and modifications
var result = await ExecBufferedAsync("diff-index --cached --diff-filter=AM --no-renames --name-only HEAD");
var result = await ExecBufferedAsync(
"diff-index --cached --diff-filter=AM --no-renames --name-only HEAD"
);
if (result.ExitCode != 0)
throw new Exception($"Exit code: {result.ExitCode}"); // break execution

return result.StandardOutput.Trim().Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
return result.StandardOutput
.Trim()
.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
}
catch (Exception e)
{
Expand All @@ -186,7 +232,9 @@ private async Task<string[]> GetGitFiles()
if (result.ExitCode != 0)
throw new Exception($"Exit code: {result.ExitCode}"); // break execution

return result.StandardOutput.Trim().Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
return result.StandardOutput
.Trim()
.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
}
catch (Exception e)
{
Expand Down
65 changes: 41 additions & 24 deletions src/Husky/Services/HuskyCliWrap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ public async Task<BufferedCommandResult> ExecBufferedAsync(string fileName, stri
{
try
{
var result = await CliWrap.Cli.Wrap(fileName)
.WithArguments(args)
.ExecuteBufferedAsync();
var result = await CliWrap.Cli
.Wrap(fileName)
.WithArguments(args)
.ExecuteBufferedAsync();
return result;
}
catch (Exception)
Expand All @@ -27,37 +28,45 @@ public async Task<BufferedCommandResult> ExecBufferedAsync(string fileName, stri

public async ValueTask SetExecutablePermission(params string[] files)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) return;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
return;
var args = new[] { "+x" }.Concat(files);
var ps = CliWrap.Cli.Wrap("chmod")
.WithArguments(args)
.WithStandardErrorPipe(PipeTarget.ToDelegate(q => q.LogVerbose(ConsoleColor.DarkRed)))
.WithValidation(CommandResultValidation.None);
var ps = CliWrap.Cli
.Wrap("chmod")
.WithArguments(args)
.WithStandardErrorPipe(PipeTarget.ToDelegate(q => q.LogVerbose(ConsoleColor.DarkRed)))
.WithValidation(CommandResultValidation.None);
var result = await ps.ExecuteAsync();
if (result.ExitCode != 0)
"failed to add executable permissions".Log(ConsoleColor.Yellow);
}

public async Task<CommandResult> ExecDirectAsync(string fileName, string args)
{
var result = await CliWrap.Cli.Wrap(fileName)
.WithArguments(args)
.WithValidation(CommandResultValidation.None)
.WithStandardOutputPipe(PipeTarget.ToDelegate(q => q.Log()))
.WithStandardErrorPipe(PipeTarget.ToDelegate(q => q.LogErr()))
.ExecuteAsync();
var result = await CliWrap.Cli
.Wrap(fileName)
.WithArguments(args)
.WithValidation(CommandResultValidation.None)
.WithStandardOutputPipe(PipeTarget.ToDelegate(q => q.Log()))
.WithStandardErrorPipe(PipeTarget.ToDelegate(q => q.LogErr()))
.ExecuteAsync();
return result;
}

public async Task<CommandResult> RunCommandAsync(string fileName, IEnumerable<string> args, string cwd,
OutputTypes output = OutputTypes.Verbose)
public async Task<CommandResult> RunCommandAsync(
string fileName,
IEnumerable<string> args,
string cwd,
OutputTypes output = OutputTypes.Verbose
)
{
var ps = CliWrap.Cli.Wrap(fileName)
.WithWorkingDirectory(cwd)
.WithArguments(args)
.WithValidation(CommandResultValidation.None)
.WithStandardOutputPipe(PipeTarget.ToDelegate(q => LogStandardOutput(q, output)))
.WithStandardErrorPipe(PipeTarget.ToDelegate(q => LogStandardError(q, output)));
var ps = CliWrap.Cli
.Wrap(fileName)
.WithWorkingDirectory(cwd)
.WithArguments(args)
.WithValidation(CommandResultValidation.None)
.WithStandardOutputPipe(PipeTarget.ToDelegate(q => LogStandardOutput(q, output)))
.WithStandardErrorPipe(PipeTarget.ToDelegate(q => LogStandardError(q, output)));

if (!string.IsNullOrEmpty(cwd))
ps = ps.WithWorkingDirectory(cwd);
Expand All @@ -78,7 +87,11 @@ private static void LogStandardOutput(string stdout, OutputTypes output)
case OutputTypes.Never:
break;
default:
throw new ArgumentOutOfRangeException(nameof(output), output, "Supported (always, never, verbose)");
throw new ArgumentOutOfRangeException(
nameof(output),
output,
"Supported (always, never, verbose)"
);
}
}

Expand All @@ -95,7 +108,11 @@ private static void LogStandardError(string stdout, OutputTypes output)
case OutputTypes.Never:
break;
default:
throw new ArgumentOutOfRangeException(nameof(output), output, "Supported (always, never, verbose)");
throw new ArgumentOutOfRangeException(
nameof(output),
output,
"Supported (always, never, verbose)"
);
}
}
}
17 changes: 12 additions & 5 deletions src/Husky/TaskRunner/ExecutableTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,27 @@

namespace Husky.TaskRunner;

public class ExecutableTask : ExecutableTaskBase
public partial class ExecutableTask : ExecutableTaskBase
{
private readonly TaskInfo _taskInfo;
protected TaskInfo TaskInfo { get; }

public ExecutableTask(TaskInfo taskInfo) : base(ExecutableTaskTypes.Normal)
{
_taskInfo = taskInfo;
TaskInfo = taskInfo;
}

public override async Task<double> Execute(ICliWrap cli)
{
var result = await cli.RunCommandAsync(_taskInfo.Command, _taskInfo.Arguments, _taskInfo.WorkingDirectory, _taskInfo.OutputType);
var result = await cli.RunCommandAsync(
TaskInfo.Command,
TaskInfo.Arguments,
TaskInfo.WorkingDirectory,
TaskInfo.OutputType
);
if (result.ExitCode != 0)
throw new CommandException($"\n ❌ Task '{_taskInfo.Name}' failed in {result.RunTime.TotalMilliseconds:n0}ms\n");
throw new CommandException(
$"\n ❌ Task '{TaskInfo.Name}' failed in {result.RunTime.TotalMilliseconds:n0}ms\n"
);

return result.RunTime.TotalMilliseconds;
}
Expand Down
Loading

0 comments on commit 385811c

Please sign in to comment.