diff --git a/src/ScriptRunner/ScriptRunner.GUI/BackgroundTasks/ConfigRepositoryUpdater.cs b/src/ScriptRunner/ScriptRunner.GUI/BackgroundTasks/ConfigRepositoryUpdater.cs index 4cd022f..52ae922 100644 --- a/src/ScriptRunner/ScriptRunner.GUI/BackgroundTasks/ConfigRepositoryUpdater.cs +++ b/src/ScriptRunner/ScriptRunner.GUI/BackgroundTasks/ConfigRepositoryUpdater.cs @@ -5,8 +5,6 @@ using System.Text; using System.Threading.Tasks; using CliWrap; -using LibGit2Sharp; -using LibGit2Sharp.Handlers; using ScriptRunner.GUI.Settings; namespace ScriptRunner.GUI.BackgroundTasks; @@ -17,8 +15,20 @@ public interface IRepositoryClient Task PullRepository(string path); } +public record CliCommand(string Command, string Parameters, string WorkingDirectory); + +public delegate Task CliCommandExecutor(CliCommand command); + +public record CliCommandOutputs(string StandardOutput, string StandardError); class CliRepositoryClient : IRepositoryClient { + private readonly CliCommandExecutor _cliCommandExecutor; + + public CliRepositoryClient(CliCommandExecutor cliCommandExecutor) + { + _cliCommandExecutor = cliCommandExecutor; + } + public async Task IsOutdated(string repoPath) { _ = await ExecuteCommand(repoPath, "git", "fetch --prune origin --verbose"); @@ -28,8 +38,8 @@ public async Task IsOutdated(string repoPath) public async Task PullRepository(string path) { - var (success,_) = await ExecuteCommand(path, "git", "pull --rebase=true origin --prune --verbose"); - return success; + var result = await _cliCommandExecutor.Invoke(new CliCommand("git", "pull --rebase=true origin --prune --verbose", path)); + return result.StandardError.Contains("error", StringComparison.InvariantCultureIgnoreCase) == false; } private static async Task<(bool, string)> ExecuteCommand(string repoPath, string command, string parameters) @@ -56,11 +66,17 @@ await Cli.Wrap(command) -public static class ConfigRepositoryUpdater +public class ConfigRepositoryUpdater { - private static readonly IRepositoryClient repositoryClient = new CliRepositoryClient(); + private readonly IRepositoryClient repositoryClient; - public static async Task> CheckAllRepositories() + + public ConfigRepositoryUpdater(IRepositoryClient repositoryClient) + { + this.repositoryClient = repositoryClient; + } + + public async Task> CheckAllRepositories() { var outOfDateRepos = new List(); var entries = AppSettingsService.Load().ConfigScripts?.Where(e => e.Type == ConfigScriptType.Directory) ?? @@ -87,10 +103,8 @@ public static async Task> CheckAllRepositories() - public static Task PullRepository(string path) + public Task RefreshRepository(string path) { return repositoryClient.PullRepository(path); } - - } \ No newline at end of file diff --git a/src/ScriptRunner/ScriptRunner.GUI/ViewModels/MainWindowViewModel.cs b/src/ScriptRunner/ScriptRunner.GUI/ViewModels/MainWindowViewModel.cs index f205c40..68bbba0 100644 --- a/src/ScriptRunner/ScriptRunner.GUI/ViewModels/MainWindowViewModel.cs +++ b/src/ScriptRunner/ScriptRunner.GUI/ViewModels/MainWindowViewModel.cs @@ -204,6 +204,25 @@ public bool ShowNewVersionAvailable public MainWindowViewModel(ParamsPanelFactory paramsPanelFactory, VaultProvider vaultProvider) { + this._configRepositoryUpdater = new ConfigRepositoryUpdater(new CliRepositoryClient(command => + { + var tcs = new TaskCompletionSource(); + + var job = new RunningJobViewModel + { + Tile = $"Update repository", + ExecutedCommand = $"{command.Command} {command.Parameters}", + }; + this.RunningJobs.Add(job); + SelectedRunningJob = job; + + job.ExecutionCompleted += (sender, args) => + { + tcs.SetResult(new(job.RawOutput, job.RawErrorOutput)); + }; + job.RunJob(command.Command, command.Parameters, command.WorkingDirectory, Array.Empty(), Array.Empty()); + return tcs.Task; + })); IsScriptListVisible = true; SaveAsPredefinedCommand = ReactiveCommand.Create(() => { }); _paramsPanelFactory = paramsPanelFactory; @@ -300,7 +319,7 @@ public MainWindowViewModel(ParamsPanelFactory paramsPanelFactory, VaultProvider _outdatedRepoCheckingScheduler = new RealTimeScheduler(TimeSpan.FromHours( 4), TimeSpan.FromHours(1), async () => { - var outOfDateRepos = await ConfigRepositoryUpdater.CheckAllRepositories(); + var outOfDateRepos = await _configRepositoryUpdater.CheckAllRepositories(); Dispatcher.UIThread.Post(() => { OutOfDateConfigRepositories.Clear(); @@ -555,7 +574,7 @@ public async void PullRepoChanges(object arg) if (arg is OutdatedRepositoryModel record) { var result = false; - await Task.Run(async () => result = await ConfigRepositoryUpdater.PullRepository(record.Path)); + await Task.Run(async () => result = await _configRepositoryUpdater.RefreshRepository(record.Path)); if (result) { OutOfDateConfigRepositories.Remove(record); @@ -830,10 +849,9 @@ public ExecutionLogAction SelectedRecentExecution } private ExecutionLogAction _selectedRecentExecution; + private readonly ConfigRepositoryUpdater _configRepositoryUpdater; - - private void AddExecutionAudit(ScriptConfig selectedAction) { AppSettingsService.UpdateRecent(recent => diff --git a/src/ScriptRunner/ScriptRunner.GUI/ViewModels/RunningJobViewModel.cs b/src/ScriptRunner/ScriptRunner.GUI/ViewModels/RunningJobViewModel.cs index d504961..69a0932 100644 --- a/src/ScriptRunner/ScriptRunner.GUI/ViewModels/RunningJobViewModel.cs +++ b/src/ScriptRunner/ScriptRunner.GUI/ViewModels/RunningJobViewModel.cs @@ -97,6 +97,7 @@ public void RunJob(string commandPath, string args, string? workingDirectory, var stopWatch = new Stopwatch(); stopWatch.Start(); var rawOutput = new StringBuilder(); + var rawErrorOutput = new StringBuilder(); try { await using var inputStream = new MultiplexerStream(); @@ -113,9 +114,13 @@ await Cli.Wrap(commandPath) rawOutput.Append(s); AppendToOutput(s, ConsoleOutputLevel.Normal); })) - .WithStandardErrorPipe(PipeTarget.ToDelegate(s => AppendToOutput(s, ConsoleOutputLevel.Error))) + .WithStandardErrorPipe(PipeTarget.ToDelegate(s => + { + rawErrorOutput.Append(s); + AppendToOutput(s, ConsoleOutputLevel.Error); + })) .WithValidation(CommandResultValidation.None) - .WithEnvironmentVariables(EnvironmentVariables) + .WithEnvironmentVariables(EnvironmentVariables ?? new()) .ExecuteAsync(ExecutionCancellation.Token); ChangeStatus(RunningJobStatus.Finished); } @@ -146,6 +151,7 @@ await Cli.Wrap(commandPath) { ExecutionPending = false; RawOutput = rawOutput.ToString(); + RawErrorOutput = rawErrorOutput.ToString(); RaiseExecutionCompleted(); }); _logForwarder.Finish(); @@ -698,6 +704,7 @@ public bool ExecutionPending } public string RawOutput { get; set; } + public string RawErrorOutput { get; set; } private int _outputIndex; private bool _executionPending;