From e7adcd21f2434afaa81610e7c00779e293600b4a Mon Sep 17 00:00:00 2001 From: Cezary Piatek Date: Sun, 1 Sep 2024 19:12:19 +0200 Subject: [PATCH 1/2] Add animation for generate button --- .../ScriptRunner.GUI/ParamsPanelFactory.cs | 4 ++++ .../ScriptRunner.GUI/Themes/StyleClasses.axaml | 18 ++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/ScriptRunner/ScriptRunner.GUI/ParamsPanelFactory.cs b/src/ScriptRunner/ScriptRunner.GUI/ParamsPanelFactory.cs index 04dd76a..f6b3c9c 100644 --- a/src/ScriptRunner/ScriptRunner.GUI/ParamsPanelFactory.cs +++ b/src/ScriptRunner/ScriptRunner.GUI/ParamsPanelFactory.cs @@ -82,6 +82,8 @@ public ParamsPanel Create(ScriptConfig action, Dictionary values }; generateButton.Click += async(sender, args) => { + generateButton.IsEnabled = false; + generateButton.Classes.Add("spinning"); var result = await commandExecutor($"Generate parameter for '{param.Name}'", param.ValueGeneratorCommand); Dispatcher.UIThread.Post(() => { @@ -89,6 +91,8 @@ public ParamsPanel Create(ScriptConfig action, Dictionary values if (controlRecord is { Control: TextBox tb }) { tb.Text = result?.Trim() ?? string.Empty; + generateButton.Classes.Remove("spinning"); + generateButton.IsEnabled = true; } }); }; diff --git a/src/ScriptRunner/ScriptRunner.GUI/Themes/StyleClasses.axaml b/src/ScriptRunner/ScriptRunner.GUI/Themes/StyleClasses.axaml index 0250531..6472b82 100644 --- a/src/ScriptRunner/ScriptRunner.GUI/Themes/StyleClasses.axaml +++ b/src/ScriptRunner/ScriptRunner.GUI/Themes/StyleClasses.axaml @@ -1,6 +1,7 @@  + xmlns:views="clr-namespace:ScriptRunner.GUI.Views" + xmlns:tanker="https://github.com/projektanker/icons.avalonia"> @@ -120,5 +121,18 @@ - + \ No newline at end of file From 4856efa9c566ec8e77e6ebc8677463b786239160 Mon Sep 17 00:00:00 2001 From: Cezary Piatek Date: Sun, 1 Sep 2024 19:58:30 +0200 Subject: [PATCH 2/2] Add insight into git repo update --- .../ConfigRepositoryUpdater.cs | 34 +++++++++++++------ .../ViewModels/MainWindowViewModel.cs | 26 +++++++++++--- .../ViewModels/RunningJobViewModel.cs | 11 ++++-- 3 files changed, 55 insertions(+), 16 deletions(-) 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;