Skip to content

Commit

Permalink
Merge branch 'hotfix/0.18.1' into master
Browse files Browse the repository at this point in the history
* hotfix/0.18.1:
  (#831) Add missing backtick in nuspec
  (#832) Ensure to correctly dispose of database
  (#829) Ensure application starts without global db
  (#830) Send correct settings to event
  • Loading branch information
gep13 committed Mar 29, 2021
2 parents 3d49015 + 0beac9b commit f2615ab
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 58 deletions.
21 changes: 21 additions & 0 deletions Source/ChocolateyGui.Common.Windows/Bootstrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
using ChocolateyGui.Common.ViewModels.Items;
using ChocolateyGui.Common.Windows.Startup;
using ChocolateyGui.Common.Windows.ViewModels;
using LiteDB;
using Serilog;
using ILogger = Serilog.ILogger;
using Log = Serilog.Log;
Expand Down Expand Up @@ -82,6 +83,7 @@ public Task OnExitAsync()
{
IsExiting = true;
Log.CloseAndFlush();
FinalizeDatabaseTransaction();
Container.Dispose();
return Task.FromResult(true);
}
Expand Down Expand Up @@ -181,6 +183,7 @@ protected override void OnExit(object sender, EventArgs e)

private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
FinalizeDatabaseTransaction();
if (e.IsTerminating)
{
Logger.Fatal(Resources.Application_UnhandledException, e.ExceptionObject as Exception);
Expand All @@ -202,5 +205,23 @@ private static void CurrentDomain_UnhandledException(object sender, UnhandledExc
Logger.Error(Resources.Application_UnhandledException, e.ExceptionObject as Exception);
}
}

private static void FinalizeDatabaseTransaction()
{
if (Container != null)
{
if (Container.IsRegisteredWithName<LiteDatabase>(GlobalConfigurationDatabaseName))
{
var globalDatabase = Container.ResolveNamed<LiteDatabase>(GlobalConfigurationDatabaseName);
globalDatabase.Dispose();
}

if (Container.IsRegisteredWithName<LiteDatabase>(UserConfigurationDatabaseName))
{
var userDatabase = Container.ResolveNamed<LiteDatabase>(UserConfigurationDatabaseName);
userDatabase.Dispose();
}
}
}
}
}
30 changes: 24 additions & 6 deletions Source/ChocolateyGui.Common.Windows/Startup/ChocolateyGuiModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,30 @@ protected override void Load(ContainerBuilder builder)
{
var userDatabase = new LiteDatabase($"filename={Path.Combine(Bootstrapper.LocalAppDataPath, "data.db")};upgrade=true");

LiteDatabase globalDatabase = null;

globalDatabase = Hacks.IsElevated
? new LiteDatabase($"filename={Path.Combine(Bootstrapper.AppDataPath, "Config", "data.db")};upgrade=true")
: new LiteDatabase($"filename={Path.Combine(Bootstrapper.AppDataPath, "Config", "data.db")};upgrade=true;readonly=true");
LiteDatabase globalDatabase;
if (Hacks.IsElevated)
{
globalDatabase = new LiteDatabase($"filename={Path.Combine(Bootstrapper.AppDataPath, "Config", "data.db")};upgrade=true");
}
else
{
if (!File.Exists(Path.Combine(Bootstrapper.AppDataPath, "Config", "data.db")))
{
// Since the global configuration database file doesn't exist, we must be running in a state where an administrator user
// has never run Chocolatey GUI. In this case, use null, which will mean attempts to use the global database will be ignored.
globalDatabase = null;
}
else
{
// Since this is a non-administrator user, they should only have read permissions to this database
globalDatabase = new LiteDatabase($"filename={Path.Combine(Bootstrapper.AppDataPath, "Config", "data.db")};readonly=true");
}
}

if (globalDatabase != null)
{
builder.RegisterInstance(globalDatabase).As<LiteDatabase>().SingleInstance().Named<LiteDatabase>(Bootstrapper.GlobalConfigurationDatabaseName);
}

var configService = new ConfigService(globalDatabase, userDatabase);
configService.SetEffectiveConfiguration();
Expand All @@ -128,7 +147,6 @@ protected override void Load(ContainerBuilder builder)

// Since there are two instances of LiteDB, they are added as named instances, so that they can be retrieved when required
builder.RegisterInstance(userDatabase).As<LiteDatabase>().SingleInstance().Named<LiteDatabase>(Bootstrapper.UserConfigurationDatabaseName);
builder.RegisterInstance(globalDatabase).As<LiteDatabase>().SingleInstance().Named<LiteDatabase>(Bootstrapper.GlobalConfigurationDatabaseName);
}
catch (IOException ex)
{
Expand Down
28 changes: 23 additions & 5 deletions Source/ChocolateyGui.Common/Services/ConfigService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ public class ConfigService : IConfigService
{
public ConfigService(LiteDatabase globalDatabase, LiteDatabase userDatabase)
{
GlobalCollection = globalDatabase.GetCollection<AppConfiguration>(nameof(AppConfiguration));
UserCollection = userDatabase.GetCollection<AppConfiguration>(nameof(AppConfiguration));

var defaultGlobalSettings = new AppConfiguration()
{
Id = "v0.18.0",
Expand All @@ -39,7 +36,20 @@ public ConfigService(LiteDatabase globalDatabase, LiteDatabase userDatabase)
Id = "v0.18.0"
};

GlobalAppConfiguration = GlobalCollection.FindById("v0.18.0") ?? defaultGlobalSettings;
// If the global database is null, the assumption has to be that we are running as a non-administrator
// user, as such, we should proceed with default settings
if (globalDatabase == null)
{
GlobalCollection = null;
GlobalAppConfiguration = defaultGlobalSettings;
}
else
{
GlobalCollection = globalDatabase.GetCollection<AppConfiguration>(nameof(AppConfiguration));
GlobalAppConfiguration = GlobalCollection.FindById("v0.18.0") ?? defaultGlobalSettings;
}

UserCollection = userDatabase.GetCollection<AppConfiguration>(nameof(AppConfiguration));
UserAppConfiguration = UserCollection.FindById("v0.18.0") ?? defaultUserSettings;
}

Expand Down Expand Up @@ -149,6 +159,14 @@ public AppConfiguration GetGlobalConfiguration()

public void UpdateSettings(AppConfiguration settings, bool global)
{
if (global && GlobalCollection == null)
{
// This is very much an edge case, and we shouldn't ever get to here, but it does need to be handled
Logger.Warning("An attempt has been made to save a configuration change globally, when the global configuration database hasn't been created.");
Logger.Warning("No action will be taken, please check with your System Administrator.");
return;
}

var settingsCollection = global ? GlobalCollection : UserCollection;

if (settingsCollection.Exists(Query.EQ("_id", "v0.18.0")))
Expand All @@ -160,7 +178,7 @@ public void UpdateSettings(AppConfiguration settings, bool global)
settingsCollection.Insert(settings);
}

SettingsChanged?.Invoke(settings, EventArgs.Empty);
SettingsChanged?.Invoke(GetEffectiveConfiguration(), EventArgs.Empty);
}

public IEnumerable<ChocolateyGuiFeature> GetFeatures(bool global)
Expand Down
114 changes: 72 additions & 42 deletions Source/ChocolateyGuiCli/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
using ChocolateyGui.Common.Commands;
using ChocolateyGui.Common.Models;
using ChocolateyGui.Common.Services;
using LiteDB;
using Serilog;
using Assembly = chocolatey.infrastructure.adapters.Assembly;
using Console = System.Console;
using GenericRunner = ChocolateyGui.Common.Commands.GenericRunner;
Expand All @@ -37,62 +39,90 @@ public static OptionSet OptionSet

public static void Main(string[] args)
{
AddAssemblyResolver();
try
{
AddAssemblyResolver();

Bootstrapper.Configure();
Bootstrapper.Configure();

var commandName = string.Empty;
IList<string> commandArgs = new List<string>();
var commandName = string.Empty;
IList<string> commandArgs = new List<string>();

// shift the first arg off
int count = 0;
foreach (var arg in args)
{
if (count == 0)
// shift the first arg off
int count = 0;
foreach (var arg in args)
{
count += 1;
continue;
if (count == 0)
{
count += 1;
continue;
}

commandArgs.Add(arg);
}

commandArgs.Add(arg);
}
var configuration = new ChocolateyGuiConfiguration();
SetUpGlobalOptions(args, configuration, Bootstrapper.Container);
SetEnvironmentOptions(configuration);

var configuration = new ChocolateyGuiConfiguration();
SetUpGlobalOptions(args, configuration, Bootstrapper.Container);
SetEnvironmentOptions(configuration);
if (configuration.RegularOutput)
{
#if DEBUG
Bootstrapper.Logger.Warning(" (DEBUG BUILD)".format_with("Chocolatey GUI", configuration.Information.DisplayVersion));
#else
Bootstrapper.Logger.Warning("{0}".format_with(configuration.Information.DisplayVersion));
#endif

if (configuration.RegularOutput)
{
#if DEBUG
Bootstrapper.Logger.Warning(" (DEBUG BUILD)".format_with("Chocolatey GUI", configuration.Information.DisplayVersion));
#else
Bootstrapper.Logger.Warning("{0}".format_with(configuration.Information.DisplayVersion));
#endif
if (args.Length == 0)
{
Bootstrapper.Logger.Information(ChocolateyGui.Common.Properties.Resources.Command_CommandsText.format_with("chocolateyguicli"));
}
}

if (args.Length == 0)
var runner = new GenericRunner();
runner.Run(configuration, Bootstrapper.Container, command =>
{
Bootstrapper.Logger.Information(ChocolateyGui.Common.Properties.Resources.Command_CommandsText.format_with("chocolateyguicli"));
}
ParseArgumentsAndUpdateConfiguration(
commandArgs,
configuration,
(optionSet) => command.ConfigureArgumentParser(optionSet, configuration),
(unparsedArgs) =>
{
command.HandleAdditionalArgumentParsing(unparsedArgs, configuration);
},
() =>
{
Bootstrapper.Logger.Debug("Performing validation checks...");
command.HandleValidation(configuration);
},
() => command.HelpMessage(configuration));
});
}

var runner = new GenericRunner();
runner.Run(configuration, Bootstrapper.Container, command =>
catch (Exception ex)
{
Bootstrapper.Logger.Error(ex.Message);
}
finally
{
ParseArgumentsAndUpdateConfiguration(
commandArgs,
configuration,
(optionSet) => command.ConfigureArgumentParser(optionSet, configuration),
(unparsedArgs) =>
Log.CloseAndFlush();

if (Bootstrapper.Container != null)
{
if (Bootstrapper.Container.IsRegisteredWithName<LiteDatabase>(Bootstrapper.GlobalConfigurationDatabaseName))
{
command.HandleAdditionalArgumentParsing(unparsedArgs, configuration);
},
() =>
var globalDatabase = Bootstrapper.Container.ResolveNamed<LiteDatabase>(Bootstrapper.GlobalConfigurationDatabaseName);
globalDatabase.Dispose();
}

if (Bootstrapper.Container.IsRegisteredWithName<LiteDatabase>(Bootstrapper.UserConfigurationDatabaseName))
{
Bootstrapper.Logger.Debug("Performing validation checks...");
command.HandleValidation(configuration);
},
() => command.HelpMessage(configuration));
});
var userDatabase = Bootstrapper.Container.ResolveNamed<LiteDatabase>(Bootstrapper.UserConfigurationDatabaseName);
userDatabase.Dispose();
}

Bootstrapper.Container.Dispose();
}
}
}

#region DupFinder Exclusion
Expand Down
28 changes: 24 additions & 4 deletions Source/ChocolateyGuiCli/Startup/ChocolateyGuiCliModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,30 @@ protected override void Load(ContainerBuilder builder)
{
var userDatabase = new LiteDatabase($"filename={Path.Combine(Bootstrapper.LocalAppDataPath, "data.db")};upgrade=true");

var globalDatabase = Hacks.IsElevated
? new LiteDatabase($"filename={Path.Combine(Bootstrapper.AppDataPath, "Config", "data.db")};upgrade=true")
: new LiteDatabase($"filename={Path.Combine(Bootstrapper.AppDataPath, "Config", "data.db")};upgrade=true;readonly=true");
LiteDatabase globalDatabase;
if (Hacks.IsElevated)
{
globalDatabase = new LiteDatabase($"filename={Path.Combine(Bootstrapper.AppDataPath, "Config", "data.db")};upgrade=true");
}
else
{
if (!File.Exists(Path.Combine(Bootstrapper.AppDataPath, "Config", "data.db")))
{
// Since the global configuration database file doesn't exist, we must be running in a state where an administrator user
// has never run Chocolatey GUI. In this case, use null, which will mean attempts to use the global database will be ignored.
globalDatabase = null;
}
else
{
// Since this is a non-administrator user, they should only have read permissions to this database
globalDatabase = new LiteDatabase($"filename={Path.Combine(Bootstrapper.AppDataPath, "Config", "data.db")};readonly=true");
}
}

if (globalDatabase != null)
{
builder.RegisterInstance(globalDatabase).As<LiteDatabase>().SingleInstance().Named<LiteDatabase>(Bootstrapper.GlobalConfigurationDatabaseName);
}

var configService = new ConfigService(globalDatabase, userDatabase);
configService.SetEffectiveConfiguration();
Expand All @@ -58,7 +79,6 @@ protected override void Load(ContainerBuilder builder)

// Since there are two instances of LiteDB, they are added as named instances, so that they can be retrieved when required
builder.RegisterInstance(userDatabase).As<LiteDatabase>().SingleInstance().Named<LiteDatabase>(Bootstrapper.UserConfigurationDatabaseName);
builder.RegisterInstance(globalDatabase).As<LiteDatabase>().SingleInstance().Named<LiteDatabase>(Bootstrapper.GlobalConfigurationDatabaseName);
}
catch (IOException ex)
{
Expand Down
2 changes: 1 addition & 1 deletion nuspec/chocolatey/ChocolateyGUI.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Chocolatey GUI is a delicious GUI on top of the Chocolatey command line tool.
- `/DefaultToTileViewForRemoteSource` - Enables/disables whether or not Chocolatey GUI defaults to tile instead of list view for all remote source views.
- `/UseDelayedSearch` - Enables/disables whether or not Chocolatey GUI uses a live search, which returns results after a short delay without clicking the search button.
- `/PreventPreload` - Prevents preloading results with a blank search when opening the remote source view.
- `/PreventAutomatedOutdatedPackagesCheck - Prevents automated check for outdated packages on startup.
- `/PreventAutomatedOutdatedPackagesCheck` - Prevents automated check for outdated packages on startup.
- `/ExcludeInstalledPackages` - Enables/disables whether or not Chocolatey GUI shows packages that are already installed when viewing sources.
- `/ShowAggregatedSourceView` - Enables/disables whether or not Chocolatey GUI shows an additional source combining all sources into one location.
- `/ShowAdditionalPackageInformation` - Show additional package information on Local and Remote views.
Expand Down

0 comments on commit f2615ab

Please sign in to comment.