diff --git a/src/Tgstation.Server.Host/Components/InstanceFactory.cs b/src/Tgstation.Server.Host/Components/InstanceFactory.cs index 9c57799c91..a04d0c7747 100644 --- a/src/Tgstation.Server.Host/Components/InstanceFactory.cs +++ b/src/Tgstation.Server.Host/Components/InstanceFactory.cs @@ -108,9 +108,14 @@ namespace Tgstation.Server.Host.Components readonly IPlatformIdentifier platformIdentifier; /// - /// The for the . + /// The for the . /// - readonly IRepositoryFactory repositoryFactory; + readonly ILibGit2RepositoryFactory repositoryFactory; + + /// + /// The for the . + /// + readonly ILibGit2Commands repositoryCommands; /// /// The for the . @@ -138,6 +143,7 @@ namespace Tgstation.Server.Host.Components /// The value of /// The value of /// The value of . + /// The value of . /// The value of . public InstanceFactory( IIOManager ioManager, @@ -157,7 +163,8 @@ namespace Tgstation.Server.Host.Components INetworkPromptReaper networkPromptReaper, IGitHubClientFactory gitHubClientFactory, IPlatformIdentifier platformIdentifier, - IRepositoryFactory repositoryFactory, + ILibGit2RepositoryFactory repositoryFactory, + ILibGit2Commands repositoryCommands, IServerPortProvider serverPortProvider) { this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager)); @@ -178,6 +185,7 @@ namespace Tgstation.Server.Host.Components this.gitHubClientFactory = gitHubClientFactory ?? throw new ArgumentNullException(nameof(gitHubClientFactory)); this.platformIdentifier = platformIdentifier ?? throw new ArgumentNullException(nameof(platformIdentifier)); this.repositoryFactory = repositoryFactory ?? throw new ArgumentNullException(nameof(repositoryFactory)); + this.repositoryCommands = repositoryCommands ?? throw new ArgumentNullException(nameof(repositoryCommands)); this.serverPortProvider = serverPortProvider ?? throw new ArgumentNullException(nameof(serverPortProvider)); } @@ -198,6 +206,7 @@ namespace Tgstation.Server.Host.Components var eventConsumer = new EventConsumer(configuration); var repoManager = new RepositoryManager( repositoryFactory, + repositoryCommands, repoIoManager, eventConsumer, loggerFactory.CreateLogger(), diff --git a/src/Tgstation.Server.Host/Components/Repository/ILibGit2Commands.cs b/src/Tgstation.Server.Host/Components/Repository/ILibGit2Commands.cs new file mode 100644 index 0000000000..c125fafdd6 --- /dev/null +++ b/src/Tgstation.Server.Host/Components/Repository/ILibGit2Commands.cs @@ -0,0 +1,29 @@ +using LibGit2Sharp; +using System.Collections.Generic; + +namespace Tgstation.Server.Host.Components.Repository +{ + /// + /// For low level interactions with a . + /// + interface ILibGit2Commands + { + /// + /// Runs a blocking fetch operation on a given . + /// + /// The to fetch with. + /// The refspecs to fetch. + /// The to fetch. + /// The . + /// The message to write in the git log. + void Fetch(LibGit2Sharp.IRepository repository, IEnumerable refSpecs, Remote remote, FetchOptions fetchOptions, string logMessage); + + /// + /// Runs a blocking checkout operation on a given . + /// + /// The to checkout with. + /// The . + /// The git object to checkout. + void Checkout(LibGit2Sharp.IRepository repository, CheckoutOptions checkoutOptions, string commitish); + } +} diff --git a/src/Tgstation.Server.Host/Components/Repository/IRepositoryFactory.cs b/src/Tgstation.Server.Host/Components/Repository/ILibGit2RepositoryFactory.cs similarity index 96% rename from src/Tgstation.Server.Host/Components/Repository/IRepositoryFactory.cs rename to src/Tgstation.Server.Host/Components/Repository/ILibGit2RepositoryFactory.cs index 1b9d7b8c41..ac5ee07b91 100644 --- a/src/Tgstation.Server.Host/Components/Repository/IRepositoryFactory.cs +++ b/src/Tgstation.Server.Host/Components/Repository/ILibGit2RepositoryFactory.cs @@ -8,7 +8,7 @@ namespace Tgstation.Server.Host.Components.Repository /// /// Factory for creating s. /// - interface IRepositoryFactory : ICredentialsProvider + interface ILibGit2RepositoryFactory : ICredentialsProvider { /// /// Create an in-memeory . diff --git a/src/Tgstation.Server.Host/Components/Repository/LibGit2Commands.cs b/src/Tgstation.Server.Host/Components/Repository/LibGit2Commands.cs new file mode 100644 index 0000000000..65c1f21049 --- /dev/null +++ b/src/Tgstation.Server.Host/Components/Repository/LibGit2Commands.cs @@ -0,0 +1,34 @@ +using LibGit2Sharp; +using System; +using System.Collections.Generic; + +namespace Tgstation.Server.Host.Components.Repository +{ + /// + sealed class LibGit2Commands : ILibGit2Commands + { + /// + public void Checkout(LibGit2Sharp.IRepository libGit2Repo, CheckoutOptions checkoutOptions, string commitish) + => Commands.Checkout(libGit2Repo, commitish, checkoutOptions); + + /// + public void Fetch( + LibGit2Sharp.IRepository libGit2Repo, + IEnumerable refSpecs, + Remote remote, + FetchOptions fetchOptions, + string logMessage) + { + if (libGit2Repo == null) + throw new ArgumentNullException(nameof(libGit2Repo)); + + if (!(libGit2Repo is LibGit2Sharp.Repository concreteRepo)) + throw new ArgumentException("libGit2Repo must be an instance of LibGit2Sharp.Repository!", nameof(libGit2Repo)); + + if (remote == null) + throw new ArgumentNullException(nameof(remote)); + + Commands.Fetch(concreteRepo, remote.Name, refSpecs, fetchOptions, logMessage); + } + } +} diff --git a/src/Tgstation.Server.Host/Components/Repository/RepositoryFactory.cs b/src/Tgstation.Server.Host/Components/Repository/LibGit2RepositoryFactory.cs similarity index 73% rename from src/Tgstation.Server.Host/Components/Repository/RepositoryFactory.cs rename to src/Tgstation.Server.Host/Components/Repository/LibGit2RepositoryFactory.cs index 69865ce950..06eb1926c9 100644 --- a/src/Tgstation.Server.Host/Components/Repository/RepositoryFactory.cs +++ b/src/Tgstation.Server.Host/Components/Repository/LibGit2RepositoryFactory.cs @@ -9,18 +9,18 @@ using Tgstation.Server.Host.Jobs; namespace Tgstation.Server.Host.Components.Repository { /// - sealed class RepositoryFactory : IRepositoryFactory + sealed class LibGit2RepositoryFactory : ILibGit2RepositoryFactory { /// - /// The for the . + /// The for the . /// - readonly ILogger logger; + readonly ILogger logger; /// - /// Initializes a new instance of the . + /// Initializes a new instance of the . /// /// The value of . - public RepositoryFactory(ILogger logger) + public LibGit2RepositoryFactory(ILogger logger) { this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); } @@ -28,8 +28,18 @@ namespace Tgstation.Server.Host.Components.Repository /// public LibGit2Sharp.IRepository CreateInMemory() { - logger.LogTrace("Creating in-memory repository..."); - return new LibGit2Sharp.Repository(); + logger.LogTrace("Creating in-memory libgit2 repository..."); + var repo = new LibGit2Sharp.Repository(); + try + { + logger.LogTrace("Successfully created in-memory libgit2 repository."); + return repo; + } + catch + { + repo.Dispose(); + throw; + } } /// @@ -37,9 +47,13 @@ namespace Tgstation.Server.Host.Components.Repository { if (path == null) throw new ArgumentNullException(nameof(path)); - logger.LogTrace("Creating repostory at {0}...", path); - return Task.Factory.StartNew( - () => (LibGit2Sharp.IRepository)new LibGit2Sharp.Repository(path), + + return Task.Factory.StartNew( + () => + { + logger.LogTrace("Creating libgit2 repostory at {0}...", path); + return new LibGit2Sharp.Repository(path); + }, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current); diff --git a/src/Tgstation.Server.Host/Components/Repository/Repository.cs b/src/Tgstation.Server.Host/Components/Repository/Repository.cs index 961a7910b8..6a1c0abf2d 100644 --- a/src/Tgstation.Server.Host/Components/Repository/Repository.cs +++ b/src/Tgstation.Server.Host/Components/Repository/Repository.cs @@ -43,21 +43,26 @@ namespace Tgstation.Server.Host.Components.Repository public string GitHubRepoName { get; } /// - public bool Tracking => Reference != null && repository.Head.IsTracking; + public bool Tracking => Reference != null && libGitRepo.Head.IsTracking; /// - public string Head => repository.Head.Tip.Sha; + public string Head => libGitRepo.Head.Tip.Sha; /// - public string Reference => repository.Head.FriendlyName; + public string Reference => libGitRepo.Head.FriendlyName; /// - public string Origin => repository.Network.Remotes.First().Url; + public string Origin => libGitRepo.Network.Remotes.First().Url; /// /// The for the /// - readonly LibGit2Sharp.IRepository repository; + readonly LibGit2Sharp.IRepository libGitRepo; + + /// + /// The for the . + /// + readonly ILibGit2Commands commands; /// /// The for the @@ -99,21 +104,32 @@ namespace Tgstation.Server.Host.Components.Repository /// /// Construct a /// - /// The value of + /// The value of + /// The value of . /// The value of /// The value of /// The value of /// The value of /// The value if - public Repository(LibGit2Sharp.IRepository repository, IIOManager ioMananger, IEventConsumer eventConsumer, ICredentialsProvider credentialsProvider, ILogger logger, Action onDispose) + public Repository( + LibGit2Sharp.IRepository libGitRepo, + ILibGit2Commands commands, + IIOManager ioMananger, + IEventConsumer eventConsumer, + ICredentialsProvider credentialsProvider, + ILogger logger, + Action onDispose) { - this.repository = repository ?? throw new ArgumentNullException(nameof(repository)); + this.libGitRepo = libGitRepo ?? throw new ArgumentNullException(nameof(libGitRepo)); + this.commands = commands ?? throw new ArgumentNullException(nameof(commands)); this.ioMananger = ioMananger ?? throw new ArgumentNullException(nameof(ioMananger)); this.eventConsumer = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer)); this.credentialsProvider = credentialsProvider ?? throw new ArgumentNullException(nameof(credentialsProvider)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); this.onDispose = onDispose ?? throw new ArgumentNullException(nameof(onDispose)); + IsGitHubRepository = Origin.Contains(GitHubUrl, StringComparison.InvariantCultureIgnoreCase); + if (IsGitHubRepository) { GetRepositoryOwnerName(Origin, out var owner, out var name); @@ -134,7 +150,7 @@ namespace Tgstation.Server.Host.Components.Repository } logger.LogTrace("Disposing..."); - repository.Dispose(); + libGitRepo.Dispose(); onDispose(); } @@ -191,15 +207,18 @@ namespace Tgstation.Server.Host.Components.Repository progressReporter(0); cancellationToken.ThrowIfCancellationRequested(); - Commands.Checkout(repository, committish, new CheckoutOptions - { - CheckoutModifiers = CheckoutModifiers.Force, - OnCheckoutProgress = CheckoutProgressHandler(progressReporter) - }); + commands.Checkout( + libGitRepo, + new CheckoutOptions + { + CheckoutModifiers = CheckoutModifiers.Force, + OnCheckoutProgress = CheckoutProgressHandler(progressReporter) + }, + committish); cancellationToken.ThrowIfCancellationRequested(); - repository.RemoveUntrackedFiles(); + libGitRepo.RemoveUntrackedFiles(); } /// @@ -248,7 +267,7 @@ namespace Tgstation.Server.Host.Components.Repository var refSpecList = new List { refSpec }; var logMessage = String.Format(CultureInfo.InvariantCulture, "Merge remote pull request #{0}", testMergeParameters.Number); - var originalCommit = repository.Head; + var originalCommit = libGitRepo.Head; MergeResult result = null; @@ -261,37 +280,42 @@ namespace Tgstation.Server.Host.Components.Repository { logger.LogTrace("Fetching refspec {0}...", refSpec); - var remote = repository.Network.Remotes.First(); + var remote = libGitRepo.Network.Remotes.First(); progressReporter(0); - Commands.Fetch((LibGit2Sharp.Repository)repository, remote.Name, refSpecList, new FetchOptions - { - Prune = true, - OnProgress = (a) => !cancellationToken.IsCancellationRequested, - OnTransferProgress = (a) => + commands.Fetch( + libGitRepo, + refSpecList, + remote, + new FetchOptions { - var percentage = 50 * (((float)a.IndexedObjects + a.ReceivedObjects) / (a.TotalObjects * 2)); - progressReporter((int)percentage); - return !cancellationToken.IsCancellationRequested; + Prune = true, + OnProgress = (a) => !cancellationToken.IsCancellationRequested, + OnTransferProgress = (a) => + { + var percentage = 50 * (((float)a.IndexedObjects + a.ReceivedObjects) / (a.TotalObjects * 2)); + progressReporter((int)percentage); + return !cancellationToken.IsCancellationRequested; + }, + OnUpdateTips = (a, b, c) => !cancellationToken.IsCancellationRequested, + CredentialsProvider = credentialsProvider.GenerateCredentialsHandler(username, password) }, - OnUpdateTips = (a, b, c) => !cancellationToken.IsCancellationRequested, - CredentialsProvider = credentialsProvider.GenerateCredentialsHandler(username, password) - }, logMessage); + logMessage); } catch (UserCancelledException) { } cancellationToken.ThrowIfCancellationRequested(); - repository.RemoveUntrackedFiles(); + libGitRepo.RemoveUntrackedFiles(); cancellationToken.ThrowIfCancellationRequested(); - testMergeParameters.PullRequestRevision = repository.Lookup(testMergeParameters.PullRequestRevision ?? localBranchName).Sha; + testMergeParameters.PullRequestRevision = libGitRepo.Lookup(testMergeParameters.PullRequestRevision ?? localBranchName).Sha; cancellationToken.ThrowIfCancellationRequested(); logger.LogTrace("Merging {0} into {1}...", testMergeParameters.PullRequestRevision.Substring(0, 7), Reference); - result = repository.Merge(testMergeParameters.PullRequestRevision, sig, new MergeOptions + result = libGitRepo.Merge(testMergeParameters.PullRequestRevision, sig, new MergeOptions { CommitOnSuccess = commitMessage == null, FailOnConflict = true, @@ -302,7 +326,7 @@ namespace Tgstation.Server.Host.Components.Repository } finally { - repository.Branches.Remove(localBranchName); + libGitRepo.Branches.Remove(localBranchName); } cancellationToken.ThrowIfCancellationRequested(); @@ -315,7 +339,7 @@ namespace Tgstation.Server.Host.Components.Repository cancellationToken.ThrowIfCancellationRequested(); } - repository.RemoveUntrackedFiles(); + libGitRepo.RemoveUntrackedFiles(); }, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current).ConfigureAwait(false); if (result.Status == MergeStatus.Conflicts) @@ -327,7 +351,7 @@ namespace Tgstation.Server.Host.Components.Repository if (commitMessage != null && result.Status != MergeStatus.UpToDate) { logger.LogTrace("Committing merge: \"{0}\"...", commitMessage); - await Task.Factory.StartNew(() => repository.Commit(commitMessage, sig, sig, new CommitOptions + await Task.Factory.StartNew(() => libGitRepo.Commit(commitMessage, sig, sig, new CommitOptions { PrettifyMessage = true }), cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current).ConfigureAwait(false); @@ -359,7 +383,7 @@ namespace Tgstation.Server.Host.Components.Repository await eventConsumer.HandleEvent(EventType.RepoCheckout, new List { committish }, cancellationToken).ConfigureAwait(false); await Task.Factory.StartNew(() => { - repository.RemoveUntrackedFiles(); + libGitRepo.RemoveUntrackedFiles(); RawCheckout(committish, progressReporter, cancellationToken); }, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current).ConfigureAwait(false); } @@ -373,10 +397,10 @@ namespace Tgstation.Server.Host.Components.Repository await eventConsumer.HandleEvent(EventType.RepoFetch, Array.Empty(), cancellationToken).ConfigureAwait(false); await Task.Factory.StartNew(() => { - var remote = repository.Network.Remotes.First(); + var remote = libGitRepo.Network.Remotes.First(); try { - Commands.Fetch((LibGit2Sharp.Repository)repository, remote.Name, remote.FetchRefSpecs.Select(x => x.Specification), new FetchOptions + Commands.Fetch((LibGit2Sharp.Repository)libGitRepo, remote.Name, remote.FetchRefSpecs.Select(x => x.Specification), new FetchOptions { Prune = true, OnProgress = (a) => !cancellationToken.IsCancellationRequested, @@ -408,17 +432,17 @@ namespace Tgstation.Server.Host.Components.Repository Task PushHeadToTemporaryBranch(string username, string password, Action progressReporter, CancellationToken cancellationToken) => Task.Factory.StartNew(() => { logger.LogInformation("Pushing changes to temporary remote branch..."); - var branch = repository.CreateBranch(RemoteTemporaryBranchName); + var branch = libGitRepo.CreateBranch(RemoteTemporaryBranchName); try { cancellationToken.ThrowIfCancellationRequested(); - var remote = repository.Network.Remotes.First(); + var remote = libGitRepo.Network.Remotes.First(); try { var forcePushString = String.Format(CultureInfo.InvariantCulture, "+{0}:{0}", branch.CanonicalName); - repository.Network.Push(remote, forcePushString, GeneratePushOptions(progress => progressReporter((int)(0.9f * progress)), username, password, cancellationToken)); + libGitRepo.Network.Push(remote, forcePushString, GeneratePushOptions(progress => progressReporter((int)(0.9f * progress)), username, password, cancellationToken)); var removalString = String.Format(CultureInfo.InvariantCulture, ":{0}", branch.CanonicalName); - repository.Network.Push(remote, removalString, GeneratePushOptions(progress => progressReporter(90 + (int)(0.1f * progress)), username, password, cancellationToken)); + libGitRepo.Network.Push(remote, removalString, GeneratePushOptions(progress => progressReporter(90 + (int)(0.1f * progress)), username, password, cancellationToken)); } catch (UserCancelledException) { @@ -431,7 +455,7 @@ namespace Tgstation.Server.Host.Components.Repository } finally { - repository.Branches.Remove(branch); + libGitRepo.Branches.Remove(branch); } }, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current); @@ -443,7 +467,7 @@ namespace Tgstation.Server.Host.Components.Repository if (!Tracking) throw new JobException("Cannot reset to origin while not on a tracked reference!"); logger.LogTrace("Reset to origin..."); - var trackedBranch = repository.Head.TrackedBranch; + var trackedBranch = libGitRepo.Head.TrackedBranch; await eventConsumer.HandleEvent(EventType.RepoResetOrigin, new List { trackedBranch.FriendlyName, trackedBranch.Tip.Sha }, cancellationToken).ConfigureAwait(false); await ResetToSha(trackedBranch.Tip.Sha, progressReporter, cancellationToken).ConfigureAwait(false); } @@ -458,16 +482,16 @@ namespace Tgstation.Server.Host.Components.Repository logger.LogDebug("Reset to sha: {0}", sha.Substring(0, 7)); - repository.RemoveUntrackedFiles(); + libGitRepo.RemoveUntrackedFiles(); cancellationToken.ThrowIfCancellationRequested(); - var gitObject = repository.Lookup(sha, ObjectType.Commit); + var gitObject = libGitRepo.Lookup(sha, ObjectType.Commit); cancellationToken.ThrowIfCancellationRequested(); if (gitObject == null) throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Cannot reset to non-existent SHA: {0}", sha)); - repository.Reset(ResetMode.Hard, gitObject.Peel(), new CheckoutOptions + libGitRepo.Reset(ResetMode.Hard, gitObject.Peel(), new CheckoutOptions { OnCheckoutProgress = CheckoutProgressHandler(progressReporter) }); @@ -491,7 +515,7 @@ namespace Tgstation.Server.Host.Components.Repository MergeResult result = null; Branch trackedBranch = null; - var oldHead = repository.Head; + var oldHead = libGitRepo.Head; var oldTip = oldHead.Tip; await Task.Factory.StartNew(() => @@ -499,13 +523,13 @@ namespace Tgstation.Server.Host.Components.Repository if (!Tracking) throw new JobException("Cannot reset to origin while not on a tracked reference!"); - repository.RemoveUntrackedFiles(); + libGitRepo.RemoveUntrackedFiles(); cancellationToken.ThrowIfCancellationRequested(); - trackedBranch = repository.Head.TrackedBranch; + trackedBranch = libGitRepo.Head.TrackedBranch; logger.LogDebug("Merge origin/{2}: <{0} ({1})>", committerName, committerEmail, trackedBranch.FriendlyName); - result = repository.Merge(trackedBranch, new Signature(new Identity(committerName, committerEmail), DateTimeOffset.Now), new MergeOptions + result = libGitRepo.Merge(trackedBranch, new Signature(new Identity(committerName, committerEmail), DateTimeOffset.Now), new MergeOptions { CommitOnSuccess = true, FailOnConflict = true, @@ -519,14 +543,14 @@ namespace Tgstation.Server.Host.Components.Repository if (result.Status == MergeStatus.Conflicts) { logger.LogDebug("Merge conflict, aborting and reverting to {0}", oldHead.FriendlyName); - repository.Reset(ResetMode.Hard, oldTip, new CheckoutOptions + libGitRepo.Reset(ResetMode.Hard, oldTip, new CheckoutOptions { OnCheckoutProgress = CheckoutProgressHandler(progressReporter) }); cancellationToken.ThrowIfCancellationRequested(); } - repository.RemoveUntrackedFiles(); + libGitRepo.RemoveUntrackedFiles(); }, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current).ConfigureAwait(false); if (result.Status == MergeStatus.Conflicts) @@ -566,9 +590,9 @@ namespace Tgstation.Server.Host.Components.Repository logger.LogTrace("Configuring <{0} ({1})> as author/committer", committerName, committerEmail); await Task.Factory.StartNew(() => { - repository.Config.Set("user.name", committerName); + libGitRepo.Config.Set("user.name", committerName); cancellationToken.ThrowIfCancellationRequested(); - repository.Config.Set("user.email", committerEmail); + libGitRepo.Config.Set("user.email", committerEmail); }, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); @@ -592,9 +616,9 @@ namespace Tgstation.Server.Host.Components.Repository logger.LogTrace("Resetting and cleaning untracked files..."); await Task.Factory.StartNew(() => { - repository.RemoveUntrackedFiles(); + libGitRepo.RemoveUntrackedFiles(); cancellationToken.ThrowIfCancellationRequested(); - repository.Reset(ResetMode.Hard, repository.Head.Tip, new CheckoutOptions + libGitRepo.Reset(ResetMode.Hard, libGitRepo.Head.Tip, new CheckoutOptions { OnCheckoutProgress = CheckoutProgressHandler(progress => progressReporter(progress / 10)) }); @@ -620,10 +644,10 @@ namespace Tgstation.Server.Host.Components.Repository return await Task.Factory.StartNew(() => { - var remote = repository.Network.Remotes.First(); + var remote = libGitRepo.Network.Remotes.First(); try { - repository.Network.Push(repository.Head, GeneratePushOptions(FinalReporter, username, password, cancellationToken)); + libGitRepo.Network.Push(libGitRepo.Head, GeneratePushOptions(FinalReporter, username, password, cancellationToken)); return true; } catch (NonFastForwardException) @@ -648,18 +672,18 @@ namespace Tgstation.Server.Host.Components.Repository public Task IsSha(string committish, CancellationToken cancellationToken) => Task.Factory.StartNew(() => { // check if it's a tag - var gitObject = repository.Lookup(committish, ObjectType.Tag); + var gitObject = libGitRepo.Lookup(committish, ObjectType.Tag); if (gitObject != null) return false; cancellationToken.ThrowIfCancellationRequested(); // check if it's a branch - if (repository.Branches[committish] != null) + if (libGitRepo.Branches[committish] != null) return false; cancellationToken.ThrowIfCancellationRequested(); // err on the side of references, if we can't look it up, assume its a reference - if (repository.Lookup(committish) != null) + if (libGitRepo.Lookup(committish) != null) return true; return false; }, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current); diff --git a/src/Tgstation.Server.Host/Components/Repository/RepositoryManager.cs b/src/Tgstation.Server.Host/Components/Repository/RepositoryManager.cs index aa988f1380..fc053ed6cf 100644 --- a/src/Tgstation.Server.Host/Components/Repository/RepositoryManager.cs +++ b/src/Tgstation.Server.Host/Components/Repository/RepositoryManager.cs @@ -19,9 +19,14 @@ namespace Tgstation.Server.Host.Components.Repository public bool CloneInProgress { get; private set; } /// - /// The for the + /// The for the /// - readonly IRepositoryFactory repositoryFactory; + readonly ILibGit2RepositoryFactory repositoryFactory; + + /// + /// The for the . + /// + readonly ILibGit2Commands commands; /// /// The for the @@ -57,13 +62,15 @@ namespace Tgstation.Server.Host.Components.Repository /// Construct a /// /// The value of . + /// The value of . /// The value of /// The value of /// The value of /// The value of /// The value of public RepositoryManager( - IRepositoryFactory repositoryFactory, + ILibGit2RepositoryFactory repositoryFactory, + ILibGit2Commands commands, IIOManager ioManager, IEventConsumer eventConsumer, ILogger repositoryLogger, @@ -71,6 +78,7 @@ namespace Tgstation.Server.Host.Components.Repository RepositorySettings repositorySettings) { this.repositoryFactory = repositoryFactory ?? throw new ArgumentNullException(nameof(repositoryFactory)); + this.commands = commands ?? throw new ArgumentNullException(nameof(commands)); this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager)); this.eventConsumer = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer)); this.repositoryLogger = repositoryLogger ?? throw new ArgumentNullException(nameof(repositoryLogger)); @@ -175,12 +183,18 @@ namespace Tgstation.Server.Host.Components.Repository using (var context = await SemaphoreSlimContext.Lock(semaphore, cancellationToken).ConfigureAwait(false)) try { - var repo = await repositoryFactory.CreateFromPath(ioManager.ResolvePath(), cancellationToken).ConfigureAwait(false); + var libGitRepo = await repositoryFactory.CreateFromPath(ioManager.ResolvePath(), cancellationToken).ConfigureAwait(false); - if (repo == null) + if (libGitRepo == null) return null; - return new Repository(repo, ioManager, eventConsumer, repositoryFactory, repositoryLogger, () => + return new Repository( + libGitRepo, + commands, + ioManager, + eventConsumer, + repositoryFactory, + repositoryLogger, () => { logger.LogTrace("Releasing semaphore due to Repository disposal..."); semaphore.Release(); diff --git a/src/Tgstation.Server.Host/Core/Application.cs b/src/Tgstation.Server.Host/Core/Application.cs index 47fc4e4d30..42376e4c6e 100644 --- a/src/Tgstation.Server.Host/Core/Application.cs +++ b/src/Tgstation.Server.Host/Core/Application.cs @@ -289,7 +289,8 @@ namespace Tgstation.Server.Host.Core }); // configure component services - services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); diff --git a/tests/Tgstation.Server.Host.Tests/Components/Repository/TestRepositoryFactory.cs b/tests/Tgstation.Server.Host.Tests/Components/Repository/TestRepositoryFactory.cs index 8d34683556..5d11ac34dc 100644 --- a/tests/Tgstation.Server.Host.Tests/Components/Repository/TestRepositoryFactory.cs +++ b/tests/Tgstation.Server.Host.Tests/Components/Repository/TestRepositoryFactory.cs @@ -9,26 +9,26 @@ using System.Threading.Tasks; namespace Tgstation.Server.Host.Components.Repository.Tests { /// - /// Tests for . + /// Tests for . /// [TestClass] public sealed class TestRepositoryFactory { - static IRepositoryFactory CreateFactory() => new RepositoryFactory(Mock.Of>()); + static ILibGit2RepositoryFactory CreateFactory() => new LibGit2RepositoryFactory(Mock.Of>()); static Task TestRepoLoading( string path, - IRepositoryFactory repositoryFactory = null) => + ILibGit2RepositoryFactory repositoryFactory = null) => (repositoryFactory ?? CreateFactory()) .CreateFromPath(path, default); [TestMethod] - public void TestConstructionThrows() => Assert.ThrowsException(() => new RepositoryFactory(null)); + public void TestConstructionThrows() => Assert.ThrowsException(() => new LibGit2RepositoryFactory(null)); [TestMethod] public void TestInMemoryRepoCreation() { - new RepositoryFactory(Mock.Of>()).CreateInMemory().Dispose(); + new LibGit2RepositoryFactory(Mock.Of>()).CreateInMemory().Dispose(); } [TestMethod]