diff --git a/SS14.MapServer/BuildRunners/LocalBuildService.cs b/SS14.MapServer/BuildRunners/LocalBuildService.cs index 1715bc3..c025254 100644 --- a/SS14.MapServer/BuildRunners/LocalBuildService.cs +++ b/SS14.MapServer/BuildRunners/LocalBuildService.cs @@ -72,7 +72,7 @@ public async Task Build(string directory, CancellationToken cancellationToken = _log.Information("Build finished"); } - public async Task Run(string directory, string command, List arguments, bool joinExecutablePath = false, CancellationToken cancellationToken = default) + public async Task Run(string directory, string command, List arguments, bool joinExecutablePath = false, CancellationToken cancellationToken = default) { var executablePath = joinExecutablePath ? Path.Join(directory, command) : command; @@ -114,6 +114,7 @@ public async Task Run(string directory, string command, List arguments, } _log.Information("Run finished"); + return log; } private void SetUpProcess(Process process, string? executable = "dotnet") @@ -147,6 +148,6 @@ private void ProcessLocalBuildException(string log, string fileName, Exception e }); } - [GeneratedRegex("error?|exception")] + [GeneratedRegex("error?|exception|fatal")] private static partial Regex LogErrorRegex(); } diff --git a/SS14.MapServer/SS14.MapServer.csproj b/SS14.MapServer/SS14.MapServer.csproj index e271f11..b879fef 100644 --- a/SS14.MapServer/SS14.MapServer.csproj +++ b/SS14.MapServer/SS14.MapServer.csproj @@ -12,7 +12,6 @@ - runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/SS14.MapServer/Services/GitService.cs b/SS14.MapServer/Services/GitService.cs index 127d9cd..a1a134e 100644 --- a/SS14.MapServer/Services/GitService.cs +++ b/SS14.MapServer/Services/GitService.cs @@ -1,5 +1,4 @@ -using LibGit2Sharp; -using LibGit2Sharp.Handlers; +using System.Diagnostics; using Serilog; using SS14.MapServer.BuildRunners; using SS14.MapServer.Configuration; @@ -9,6 +8,8 @@ namespace SS14.MapServer.Services; public sealed class GitService { + private const string GitCommand = "git"; + private readonly LocalBuildService _buildService; private readonly GitConfiguration _configuration = new(); @@ -22,12 +23,28 @@ public GitService(IConfiguration configuration, LocalBuildService buildService) } /// - /// + /// Gets the git version. Used for determining it git is installed + /// + public async Task GetGitVersion(CancellationToken cancellationToken = default) + { + using var process = new Process(); + process.StartInfo.UseShellExecute = false; + process.StartInfo.RedirectStandardOutput = true; + process.StartInfo.RedirectStandardError = true; + process.StartInfo.FileName = GitCommand; + process.StartInfo.Arguments = "--version"; + process.Start(); + await process.WaitForExitAsync(cancellationToken); + return await process.StandardOutput.ReadToEndAsync(cancellationToken); + } + + /// + /// Clones the repo if it hasn't been cloned yet and pulls the provided git ref or the current branch /// /// /// [Optional] The Ref to pull /// - /// + /// The directory the repository is in public string Sync(string workingDirectory, string? gitRef = null, string? repoUrl = null) { gitRef ??= _configuration.Branch; @@ -55,8 +72,9 @@ public string Sync(string workingDirectory, string? gitRef = null, string? repoU /// public string GetRepoCommitHash(string directory) { - using var repository = new Repository(directory); - return repository.Head.Tip.Sha; + var task = _buildService.Run(directory, GitCommand, new List { "rev-parse HEAD" }); + task.Wait(); + return task.Result; } public static string StripRef(string gitRef) @@ -68,26 +86,14 @@ private void Clone(string repoUrl, string directory, string gitRef) { _log.Information("Cloning branch/commit {Ref}...", gitRef); + var sshConfig = _configuration.SshCommand != null + ? $"--config core.sshcommand=\"{_configuration.SshCommand}\"" + : ""; + + RunCommand(Path.GetFullPath("./..", directory), "clone --recurse-submodules", sshConfig, repoUrl); + RunCommand(directory, "fetch -fu origin", gitRef); + RunCommand(directory, "checkout", StripRef(gitRef)); - /*var repoDirectory = Repository.Clone(repoUrl, directory, new CloneOptions - { - RecurseSubmodules = true, - OnProgress = LogProgress - }); - - using var repository = new Repository(repoDirectory); - - Commands.Fetch( - repository, - "origin", - new []{gitRef}, - new FetchOptions - { - OnProgress = LogProgress - }, - null); - - Commands.Checkout(repository, StripRef(gitRef));*/ _log.Information("Done cloning"); } @@ -96,45 +102,36 @@ private void Pull(string repoDirectory, string gitRef) _log.Information( "Pulling branch/commit {Ref}...", gitRef); _log.Debug("Opening repository in: {RepositoryPath}", repoDirectory); - using var repository = new Repository(repoDirectory); //Set an identity _log.Debug("Setting identity"); - repository.Config.Set("user.name", _configuration.Identity.Name); - repository.Config.Set("user.email", _configuration.Identity.Email); + RunCommand(repoDirectory, "config user.name", $"\"{_configuration.Identity.Name}\""); + RunCommand(repoDirectory, "config user.email", $"\"{_configuration.Identity.Email}\""); if (_configuration.SshCommand != null) { _log.Debug("Setting ssh command"); - repository.Config.Set("core.sshcommand", _configuration.SshCommand); + RunCommand(repoDirectory, "config core.sshcommand", $"\"{_configuration.SshCommand}\""); } _log.Debug("Fetching ref"); - _buildService.Run(repoDirectory, "git", new List { "fetch -fu origin", gitRef }).Wait(); + RunCommand(repoDirectory, "fetch -fu origin", gitRef); _log.Debug("Checking out {Ref}", StripRef(gitRef)); - Commands.Checkout(repository, StripRef(gitRef)); + RunCommand(repoDirectory, "checkout", StripRef(gitRef)); _log.Debug("Pulling latest changes"); - _buildService.Run(repoDirectory, "git", new List { "pull origin HEAD --ff-only" }).Wait(); + RunCommand(repoDirectory, "pull origin HEAD --ff-only --force"); _log.Debug("Updating submodules"); - foreach (var submodule in repository.Submodules) - { - if (submodule.UpdateRule == SubmoduleUpdate.None) - continue; - - repository.Submodules.Update(submodule.Name, new SubmoduleUpdateOptions - { - OnProgress = LogProgress - }); - } + RunCommand(repoDirectory, "submodule update --init --recursive"); _log.Information("Done pulling"); } - private bool LogProgress(string? progress) + private string RunCommand(string directory, params string[] arguments) { - _log.Verbose("Progress: {Progress}", progress); - return true; + var task = _buildService.Run(directory, GitCommand, new List(arguments)); + task.Wait(); + return task.Result; } } diff --git a/SS14.MapServer/Services/StartupCheckService.cs b/SS14.MapServer/Services/StartupCheckService.cs index f1536d2..1a7d1e8 100644 --- a/SS14.MapServer/Services/StartupCheckService.cs +++ b/SS14.MapServer/Services/StartupCheckService.cs @@ -11,14 +11,16 @@ public sealed class StartupCheckService private readonly BuildConfiguration _buildConfiguration = new(); private readonly GitConfiguration _gitConfiguration = new(); private readonly ProcessingConfiguration _processingConfiguration = new(); + private readonly GitService _gitService; private readonly ContainerService _containerService; private readonly LocalBuildService _localBuildService; - public StartupCheckService(ContainerService containerService, IConfiguration configuration, LocalBuildService localBuildService) + public StartupCheckService(ContainerService containerService, IConfiguration configuration, LocalBuildService localBuildService, GitService gitService) { _containerService = containerService; _localBuildService = localBuildService; + _gitService = gitService; configuration.Bind(FilePathsConfiguration.Name, _filePathsConfiguration); configuration.Bind(BuildConfiguration.Name, _buildConfiguration); configuration.Bind(GitConfiguration.Name, _gitConfiguration); @@ -66,7 +68,9 @@ private async Task CheckBuildServices() if (!_buildConfiguration.Enabled) return true; - return _buildConfiguration.Runner switch + var result = await CheckGitPrerequisites(); + + return result && _buildConfiguration.Runner switch { BuildRunnerName.Local => await CheckLocalRunnerPrerequisites(), BuildRunnerName.Container => await CheckContainerPrerequisites(), @@ -74,6 +78,24 @@ private async Task CheckBuildServices() }; } + private async Task CheckGitPrerequisites() + { + Log.Information("Checking Git:"); + + try + { + var version = await _gitService.GetGitVersion(); + Log.Information(" - Git version: {GitVersion}", version.Replace("\n", "")); + } + catch (Exception e) + { + Log.Fatal(e, "Couldn't determine Git version"); + return false; + } + + return true; + } + private async Task CheckContainerPrerequisites() { Log.Information("Checking container manager:");