Skip to content

Commit

Permalink
- added a Git plugin
Browse files Browse the repository at this point in the history
- Added Git init
- added git add
- added git commit
- added git initialize
  • Loading branch information
jan-schutte committed Jun 11, 2024
1 parent 12dfcae commit eeedaf0
Show file tree
Hide file tree
Showing 13 changed files with 608 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Nox.Cli.Plugin.Git.Abstractions;

public interface IGitClient
{
Task<GitResponse> Init(string branchName = "main");
Task<GitResponse> Add(string filePattern);
Task<GitResponse> Commit(string message);
}
104 changes: 104 additions & 0 deletions src/Nox.Cli.Plugins/Nox.Cli.Plugin.Git/GitAdd_v1.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
using Nox.Cli.Abstractions;
using Nox.Cli.Abstractions.Extensions;

namespace Nox.Cli.Plugin.Git;

public class GitAdd_v1: INoxCliAddin
{
public NoxActionMetaData Discover()
{
return new NoxActionMetaData
{
Name = "git/add@v1",
Author = "Jan Schutte",
Description = "Add one or more files to the git index.",

Inputs =
{
["path"] = new NoxActionInput {
Id = "path",
Description = "The path to the working folder in which to execute the git command.",
Default = string.Empty,
IsRequired = true
},

["file-pattern"] = new NoxActionInput {
Id = "file-pattern",
Description = "The name of the file to add, or a patten of files to add",
Default = "*",
IsRequired = false
}
},

Outputs =
{
["result"] = new NoxActionOutput
{
Id = "result",
Description = "The message returned from the git command, if any."
},
}
};
}

private string? _path;
private string? _filePattern;

public Task BeginAsync(IDictionary<string,object> inputs)
{
_path = inputs.Value<string>("path");
_filePattern = inputs.ValueOrDefault<string>("file-pattern", this);
return Task.CompletedTask;
}

public async Task<IDictionary<string, object>> ProcessAsync(INoxWorkflowContext ctx)
{
var outputs = new Dictionary<string, object>();

ctx.SetState(ActionState.Error);

if (string.IsNullOrEmpty(_path) ||
string.IsNullOrEmpty(_filePattern))
{
ctx.SetErrorMessage("The Git add action was not initialized");
}
else
{
try
{ var fullPath = Path.GetFullPath(_path);
if (!Directory.Exists(fullPath))
{
ctx.SetState(ActionState.Error);
ctx.SetErrorMessage("Working folder does not exist!");
}
else
{
var client = new GitClient(fullPath);
var response = await client.Add(_filePattern);
if (response.Status == GitCommandStatus.Error)
{
ctx.SetState(ActionState.Error);
ctx.SetErrorMessage(response.Message);
}
else
{
ctx.SetState(ActionState.Success);
}

outputs["result"] = response.Message;
}
}
catch (Exception ex)
{
ctx.SetErrorMessage(ex.Message);
}
}

return outputs;
}

public Task EndAsync()
{
return Task.CompletedTask;
}
}
110 changes: 110 additions & 0 deletions src/Nox.Cli.Plugins/Nox.Cli.Plugin.Git/GitClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
using System.Diagnostics;
using Nox.Cli.Plugin.Git.Abstractions;

namespace Nox.Cli.Plugin.Git;

public class GitClient: IGitClient
{
private readonly string _workingDirectory;

public GitClient(string workingDirectory)
{
_workingDirectory = workingDirectory;
//Verify that git is installed
try
{
var response = ExecuteAsync("--version").Result;
if (response.Status == GitCommandStatus.Error)
{
throw new Exception("Git executable not found!");
}
}
catch(Exception ex)

Check failure on line 22 in src/Nox.Cli.Plugins/Nox.Cli.Plugin.Git/GitClient.cs

View workflow job for this annotation

GitHub Actions / build (8.0.x)

The variable 'ex' is declared but never used

Check failure on line 22 in src/Nox.Cli.Plugins/Nox.Cli.Plugin.Git/GitClient.cs

View workflow job for this annotation

GitHub Actions / build (8.0.x)

The variable 'ex' is declared but never used
{
throw new Exception("Git executable not found!");
}

}

public async Task<GitResponse> Init(string branchName = "main")
{
var response = new GitResponse();
try
{
return await ExecuteAsync($"init -b {branchName}");
}
catch (Exception ex)
{
response.Status = GitCommandStatus.Error;
response.Message = ex.Message;
}
return response;
}

public async Task<GitResponse> Add(string filePattern)
{
var response = new GitResponse();
try
{
return await ExecuteAsync($"add --all {filePattern}");
}
catch (Exception ex)
{
response.Status = GitCommandStatus.Error;
response.Message = ex.Message;
}
return response;
}

public async Task<GitResponse> Commit(string message)
{
var response = new GitResponse();
try
{
return await ExecuteAsync($"commit -m \"{message}\"");
}
catch (Exception ex)
{
response.Status = GitCommandStatus.Error;
response.Message = ex.Message;
}
return response;
}

private async Task<GitResponse> ExecuteAsync(string arguments)
{
var response = new GitResponse();
var processInfo = GetProcessStartInfo(arguments);
using var process = new Process();
process.StartInfo = processInfo;
process.Start();
var output = await process.StandardOutput.ReadToEndAsync();
var error = await process.StandardError.ReadToEndAsync();
await process.WaitForExitAsync();
if (!string.IsNullOrWhiteSpace(error))
{
response.Status = GitCommandStatus.Error;
response.Message = error;
}
else
{
response.Status = output.Contains("warning", StringComparison.InvariantCultureIgnoreCase) ? GitCommandStatus.Warning : GitCommandStatus.Success;
response.Message = output;
}
return response;
}

private ProcessStartInfo GetProcessStartInfo(string arguments)
{
return new ProcessStartInfo
{
FileName = "git",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
WorkingDirectory = _workingDirectory,
Arguments = arguments
};
}
}
8 changes: 8 additions & 0 deletions src/Nox.Cli.Plugins/Nox.Cli.Plugin.Git/GitCommandStatus.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Nox.Cli.Plugin.Git;

public enum GitCommandStatus
{
Success = 0,
Warning,
Error
}
104 changes: 104 additions & 0 deletions src/Nox.Cli.Plugins/Nox.Cli.Plugin.Git/GitCommit_v1.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
using Nox.Cli.Abstractions;
using Nox.Cli.Abstractions.Extensions;

namespace Nox.Cli.Plugin.Git;

public class GitCommit_v1: INoxCliAddin
{
public NoxActionMetaData Discover()
{
return new NoxActionMetaData
{
Name = "git/commit@v1",
Author = "Jan Schutte",
Description = "Record changes to the repository.",

Inputs =
{
["path"] = new NoxActionInput {
Id = "path",
Description = "The path to the working folder in which to execute the git command.",
Default = string.Empty,
IsRequired = true
},

["commit-message"] = new NoxActionInput {
Id = "commit-message",
Description = "The message to associate with the commit.",
Default = string.Empty,
IsRequired = true
}
},

Outputs =
{
["result"] = new NoxActionOutput
{
Id = "result",
Description = "The message returned from the git command, if any."
},
}
};
}

private string? _path;
private string? _message;

public Task BeginAsync(IDictionary<string,object> inputs)
{
_path = inputs.Value<string>("path");
_message = inputs.Value<string>("commit-message");
return Task.CompletedTask;
}

public async Task<IDictionary<string, object>> ProcessAsync(INoxWorkflowContext ctx)
{
var outputs = new Dictionary<string, object>();

ctx.SetState(ActionState.Error);

if (string.IsNullOrEmpty(_path) ||
string.IsNullOrEmpty(_message))
{
ctx.SetErrorMessage("The Git commit action was not initialized");
}
else
{
try
{ var fullPath = Path.GetFullPath(_path);
if (!Directory.Exists(fullPath))
{
ctx.SetState(ActionState.Error);
ctx.SetErrorMessage("Working folder does not exist!");
}
else
{
var client = new GitClient(fullPath);
var response = await client.Commit(_message);
if (response.Status == GitCommandStatus.Error)
{
ctx.SetState(ActionState.Error);
ctx.SetErrorMessage(response.Message);
}
else
{
ctx.SetState(ActionState.Success);
}

outputs["result"] = response.Message;
}
}
catch (Exception ex)
{
ctx.SetErrorMessage(ex.Message);
}
}

return outputs;
}

public Task EndAsync()
{
return Task.CompletedTask;
}
}
Loading

0 comments on commit eeedaf0

Please sign in to comment.