Browse Source

Merge pull request #156 from ionite34/fix-linux-updater

pull/55/head
Ionite 1 year ago committed by GitHub
parent
commit
e8ebf9eb00
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      StabilityMatrix.Avalonia/App.axaml.cs
  2. 28
      StabilityMatrix.Avalonia/Models/AppArgs.cs
  3. 20
      StabilityMatrix.Avalonia/Program.cs
  4. 7
      StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs
  5. 13
      StabilityMatrix.Core/Updater/UpdateHelper.cs

7
StabilityMatrix.Avalonia/App.axaml.cs

@ -13,6 +13,7 @@ using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using Avalonia.Platform;
using Avalonia.Platform.Storage; using Avalonia.Platform.Storage;
using Avalonia.Styling; using Avalonia.Styling;
using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Controls;
@ -108,6 +109,9 @@ public sealed class App : Application
setupWindow.ShowActivated = true; setupWindow.ShowActivated = true;
setupWindow.ShowAsyncCts = new CancellationTokenSource(); setupWindow.ShowAsyncCts = new CancellationTokenSource();
setupWindow.ExtendClientAreaChromeHints = Program.Args.NoWindowChromeEffects ?
ExtendClientAreaChromeHints.NoChrome : ExtendClientAreaChromeHints.PreferSystemChrome;
DesktopLifetime.MainWindow = setupWindow; DesktopLifetime.MainWindow = setupWindow;
setupWindow.ShowAsyncCts.Token.Register(() => setupWindow.ShowAsyncCts.Token.Register(() =>
@ -142,6 +146,9 @@ public sealed class App : Application
mainWindow.DataContext = mainViewModel; mainWindow.DataContext = mainViewModel;
mainWindow.NotificationService = notificationService; mainWindow.NotificationService = notificationService;
mainWindow.ExtendClientAreaChromeHints = Program.Args.NoWindowChromeEffects ?
ExtendClientAreaChromeHints.NoChrome : ExtendClientAreaChromeHints.PreferSystemChrome;
var settingsManager = Services.GetRequiredService<ISettingsManager>(); var settingsManager = Services.GetRequiredService<ISettingsManager>();
var windowSettings = settingsManager.Settings.WindowSettings; var windowSettings = settingsManager.Settings.WindowSettings;
if (windowSettings != null) if (windowSettings != null)

28
StabilityMatrix.Avalonia/Models/AppArgs.cs

@ -0,0 +1,28 @@
namespace StabilityMatrix.Avalonia.Models;
/// <summary>
/// Command line arguments passed to the application.
/// </summary>
public class AppArgs
{
/// <summary>
/// Whether to use the exception dialog while debugger is attached.
/// When no debugger is attached, the exception dialog is always used.
/// </summary>
public bool DebugExceptionDialog { get; set; }
/// <summary>
/// Whether to use Sentry when a debugger is attached.
/// </summary>
public bool DebugSentry { get; set; }
/// <summary>
/// Whether to disable Sentry.
/// </summary>
public bool NoSentry { get; set; }
/// <summary>
/// Whether to disable window chrome effects
/// </summary>
public bool NoWindowChromeEffects { get; set; }
}

20
StabilityMatrix.Avalonia/Program.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -16,6 +17,7 @@ using Projektanker.Icons.Avalonia;
using Projektanker.Icons.Avalonia.FontAwesome; using Projektanker.Icons.Avalonia.FontAwesome;
using Semver; using Semver;
using Sentry; using Sentry;
using StabilityMatrix.Avalonia.Models;
using StabilityMatrix.Avalonia.ViewModels.Dialogs; using StabilityMatrix.Avalonia.ViewModels.Dialogs;
using StabilityMatrix.Avalonia.Views.Dialogs; using StabilityMatrix.Avalonia.Views.Dialogs;
using StabilityMatrix.Core.Helper; using StabilityMatrix.Core.Helper;
@ -27,7 +29,7 @@ namespace StabilityMatrix.Avalonia;
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")] [SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
public class Program public class Program
{ {
private static bool isExceptionDialogEnabled; public static AppArgs Args { get; } = new();
// Initialization code. Don't use any Avalonia, third-party APIs or any // Initialization code. Don't use any Avalonia, third-party APIs or any
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized // SynchronizationContext-reliant code before AppMain is called: things aren't initialized
@ -35,6 +37,11 @@ public class Program
[STAThread] [STAThread]
public static void Main(string[] args) public static void Main(string[] args)
{ {
Args.DebugExceptionDialog = args.Contains("--debug-exception-dialog");
Args.DebugSentry = args.Contains("--debug-sentry");
Args.NoSentry = args.Contains("--no-sentry");
Args.NoWindowChromeEffects = args.Contains("--no-window-chrome-effects");
HandleUpdateReplacement(); HandleUpdateReplacement();
var infoVersion = Assembly.GetExecutingAssembly() var infoVersion = Assembly.GetExecutingAssembly()
@ -42,14 +49,13 @@ public class Program
Compat.AppVersion = SemVersion.Parse(infoVersion ?? "0.0.0", SemVersionStyles.Strict); Compat.AppVersion = SemVersion.Parse(infoVersion ?? "0.0.0", SemVersionStyles.Strict);
// Configure exception dialog for unhandled exceptions // Configure exception dialog for unhandled exceptions
if (!Debugger.IsAttached || args.Contains("--debug-exception-dialog")) if (!Debugger.IsAttached || Args.DebugExceptionDialog)
{ {
isExceptionDialogEnabled = true;
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
} }
// Configure Sentry // Configure Sentry
if ((Debugger.IsAttached && args.Contains("--debug-sentry")) || !args.Contains("--no-sentry")) if (!Args.NoSentry && (!Debugger.IsAttached || Args.DebugSentry))
{ {
ConfigureSentry(); ConfigureSentry();
} }
@ -89,6 +95,12 @@ public class Program
{ {
currentExe.CopyTo(targetExe, true); currentExe.CopyTo(targetExe, true);
// Ensure permissions are set for unix
if (Compat.IsUnix)
{
File.SetUnixFileMode(targetExe, (UnixFileMode) 0x755);
}
// Start the new app // Start the new app
Process.Start(targetExe); Process.Start(targetExe);

7
StabilityMatrix.Avalonia/ViewModels/Dialogs/UpdateViewModel.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.IO;
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using AsyncAwaitBestPractices; using AsyncAwaitBestPractices;
@ -78,6 +79,12 @@ public partial class UpdateViewModel : ContentDialogViewModelBase
ProgressValue = Convert.ToInt32(report.Percentage); ProgressValue = Convert.ToInt32(report.Percentage);
})); }));
// On unix, we need to set the executable bit
if (Compat.IsUnix)
{
File.SetUnixFileMode(UpdateHelper.ExecutablePath, (UnixFileMode) 0x755);
}
UpdateText = "Update complete. Restarting Stability Matrix in 3 seconds..."; UpdateText = "Update complete. Restarting Stability Matrix in 3 seconds...";
await Task.Delay(1000); await Task.Delay(1000);
UpdateText = "Update complete. Restarting Stability Matrix in 2 seconds..."; UpdateText = "Update complete. Restarting Stability Matrix in 2 seconds...";

13
StabilityMatrix.Core/Updater/UpdateHelper.cs

@ -35,14 +35,14 @@ public class UpdateHelper : IUpdateHelper
this.downloadService = downloadService; this.downloadService = downloadService;
this.debugOptions = debugOptions.Value; this.debugOptions = debugOptions.Value;
timer.Elapsed += async (_, _) => { await CheckForUpdate(); }; timer.Elapsed += async (_, _) => { await CheckForUpdate().ConfigureAwait(false); };
} }
public async Task StartCheckingForUpdates() public async Task StartCheckingForUpdates()
{ {
timer.Enabled = true; timer.Enabled = true;
timer.Start(); timer.Start();
await CheckForUpdate(); await CheckForUpdate().ConfigureAwait(false);
} }
public async Task DownloadUpdate(UpdateInfo updateInfo, public async Task DownloadUpdate(UpdateInfo updateInfo,
@ -54,7 +54,7 @@ public class UpdateHelper : IUpdateHelper
// download the file from URL // download the file from URL
await downloadService.DownloadToFileAsync(downloadUrl, ExecutablePath, progress: progress, await downloadService.DownloadToFileAsync(downloadUrl, ExecutablePath, progress: progress,
httpClientName: "UpdateClient"); httpClientName: "UpdateClient").ConfigureAwait(false);
} }
@ -77,17 +77,18 @@ public class UpdateHelper : IUpdateHelper
try try
{ {
var httpClient = httpClientFactory.CreateClient("UpdateClient"); var httpClient = httpClientFactory.CreateClient("UpdateClient");
var response = await httpClient.GetAsync(UpdateManifestUrl); var response = await httpClient.GetAsync(UpdateManifestUrl).ConfigureAwait(false);
if (!response.IsSuccessStatusCode) if (!response.IsSuccessStatusCode)
{ {
logger.LogWarning("Error while checking for update {StatusCode} - {Content}", logger.LogWarning("Error while checking for update {StatusCode} - {Content}",
response.StatusCode, await response.Content.ReadAsStringAsync()); response.StatusCode, await response.Content.ReadAsStringAsync().ConfigureAwait(false));
return; return;
} }
var updateCollection = var updateCollection =
await JsonSerializer.DeserializeAsync<UpdateCollection>( await JsonSerializer.DeserializeAsync<UpdateCollection>(
await response.Content.ReadAsStreamAsync()); await response.Content.ReadAsStreamAsync()
.ConfigureAwait(false)).ConfigureAwait(false);
if (updateCollection is null) if (updateCollection is null)
{ {

Loading…
Cancel
Save