feat: Add GitRepoRegistration cmdlets #5

Merged
pascal_nulah merged 69 commits from feature/git-provider into dev 2026-09-06 09:33:36 +10:00
2 changed files with 84 additions and 0 deletions
Showing only changes of commit a666a49db0 - Show all commits

feat(git-provider): Implement RemoveGitRepoCommand

Scott 2026-08-25 11:18:03 +10:00

View file

@ -117,6 +117,54 @@ public class GitManager
});
}
public void UnregisterRepo(string registrationName)
pascal_nulah marked this conversation as resolved

todo: Document public method

todo: Document public method
{
_db.InConnection(conn =>
{
var existingRegistration = conn.Query<InternalGitRegistration>(
$"""
SELECT {nameof(InternalGitRegistration.Id)}
,{nameof(InternalGitRegistration.Name)}
,{nameof(InternalGitRegistration.Location)}
FROM {InternalGitRegistration.TableName}
WHERE {nameof(InternalGitRegistration.Name)} = ?
pascal_nulah marked this conversation as resolved

thought: Not sure if I should be suspect about this as the value is coming from arbitrary user supplied input, but also it's a local sqlite database and if an attacker has access to the command that could exploit this then they already have the same privileges (or higher) than the current user so it's very who cares to me

thought: Not sure if I should be suspect about this as the value is coming from arbitrary user supplied input, but also it's a local sqlite database and if an attacker has access to the command that could exploit this then they already have the same privileges (or higher) than the current user so it's very who cares to me
[Investigate if user supplied input for commands for SQLite are a concern or not #14](https://moar.ws/git/pascal_nulah/Nulah.PowerShell/issues/14)
""",
registrationName)
.FirstOrDefault();
if (existingRegistration is null)
{
throw new Exception($"No registration exists for '{registrationName}'.")
{
Source = "unregister-repository",
};
}
var deleted = conn.Delete<InternalGitRegistration>(existingRegistration.Id);
// If we somehow found a registration but delete returned nothing, just return and assume we've already
// removed it from registrations.
// Seems a bit risky when you read it logically, but by this point the registration shouldn't exist so it doesn't
// matter.
if (deleted == 0)
{
return;
}
// Remove by the name we get from the database instead of what was passed in
if (_registrations.TryRemove(registrationName, out var removedItem))
{
_debugWriterDelegate?.Invoke($"Removed {registrationName}.");
}
// Weird error to throw, but by this stage we shouldn't have a git repo registered under this name
throw new Exception("Failed to remove registration - no registration exists.")
{
Source = "unregister-repository",
};
});
}
public List<GitRegistration> ListRepos()
{
return _registrations.Select(x =>

View file

@ -0,0 +1,36 @@
using System;
using System.Management.Automation;
using ModuleCore.Git;
namespace PowershellModule.Git.Commands;
[Cmdlet(VerbsCommon.Remove, GitCommands.GitRepoNoun)]
public class RemoveGitRepoCommand : PSCmdlet
{
[Parameter(
Position = 0,
ValueFromPipeline = true,
HelpMessage = "Reference name for the repo")]
public string? Name { get; set; }
protected override void BeginProcessing()
{
try
{
GitManager.SetDebugWriter(WriteDebug);
var repoFolder = GitManager.IsGitRepo(SessionState.Path.CurrentLocation.Path);
// Removing a registration works similar to registering a new one - we either remove by exact name, or by
// the folder if no name is given (so a user can remove a registration from a git repo they're currently in)
GitManager.Instance.UnregisterRepo(Name ?? repoFolder.Folder);
GitManager.ClearDebugWriter();
base.BeginProcessing();
}
catch (Exception ex)
{
WriteError(new ErrorRecord(ex, ex.Source, ErrorCategory.FromStdErr, null));
}
}
}