protected override async Task OnExecuteAsync() { await PrintAsync("Purging packages..."); var packagesDirectory = m_PackageManager.PackagesDirectory; var options = new GlobOptions { Evaluation = { CaseInsensitive = false } }; var restore = !Context.Parameters.Contains("--no-restore"); var filters = Context.Parameters .Where(d => d != "--no-restore") .Select(d => Glob.Parse(d, options)) .ToList(); var i = 0; foreach (var packageDir in Directory.GetDirectories(packagesDirectory)) { var nupkg = Directory.GetFiles(packageDir, "*.nupkg", SearchOption.AllDirectories) .FirstOrDefault(); if (nupkg == null) { // Ignore directories that do not have a nupkg file continue; } try { using var reader = new PackageArchiveReader(nupkg); var identity = await reader.GetIdentityAsync(CancellationToken.None); if (filters.Count > 0 && !filters.Any(f => f.IsMatch(identity.Id))) { continue; } Directory.Delete(packageDir, recursive: true); i++; } catch (Exception ex) { var dirName = Path.GetFileName(packageDir); await PrintAsync($"Failed to delete {dirName}: {ex.Message}"); } } await PrintAsync($"Purged {i} package(s)."); if (restore) { await PrintAsync("Restoring packages..."); i = await m_PackageManager.InstallMissingPackagesAsync(); await PrintAsync($"Restored {i} package(s) from packages.yaml."); } }
public async Task <IHost> InitAsync( List <Assembly> openModHostAssemblies, RuntimeInitParameters parameters, Func <IHostBuilder>?hostBuilderFunc = null) { if (parameters == null) { throw new ArgumentNullException(nameof(parameters)); } HostAssemblies = openModHostAssemblies ?? throw new ArgumentNullException(nameof(openModHostAssemblies)); try { IsDisposing = false; var openModCoreAssembly = typeof(AsyncHelper).Assembly; if (!openModHostAssemblies.Contains(openModCoreAssembly)) { openModHostAssemblies.Insert(0, openModCoreAssembly); } var hostInformationType = openModHostAssemblies .Select(asm => AssemblyExtensions.GetLoadableTypes(asm) .FirstOrDefault(t => typeof(IHostInformation).IsAssignableFrom(t))) .LastOrDefault(d => d != null); if (hostInformationType == null) { throw new Exception("Failed to find IHostInformation in host assemblies."); } HostInformation = (IHostInformation)Activator.CreateInstance(hostInformationType); m_OpenModHostAssemblies = openModHostAssemblies; m_HostBuilderFunc = hostBuilderFunc; m_RuntimeInitParameters = parameters; var hostBuilder = hostBuilderFunc == null ? new HostBuilder() : hostBuilderFunc(); if (!Directory.Exists(parameters.WorkingDirectory)) { Directory.CreateDirectory(parameters.WorkingDirectory); } Status = RuntimeStatus.Initializing; WorkingDirectory = parameters.WorkingDirectory; CommandlineArgs = parameters.CommandlineArgs; SetupSerilog(false); m_Logger.LogInformation("OpenMod v{Version} is starting...", Version); if (parameters.PackageManager is not NuGetPackageManager nugetPackageManager) { var packagesDirectory = Path.Combine(WorkingDirectory, "packages"); nugetPackageManager = new NuGetPackageManager(packagesDirectory); } nugetPackageManager.Logger = new OpenModNuGetLogger(m_LoggerFactory !.CreateLogger("NuGet")); await nugetPackageManager.RemoveOutdatedPackagesAsync(); nugetPackageManager.InstallAssemblyResolver(); nugetPackageManager.SetAssemblyLoader((NuGetPackageManager.AssemblyLoader)Hotloader.LoadAssembly); var startupContext = new OpenModStartupContext { Runtime = this, LoggerFactory = m_LoggerFactory !, NuGetPackageManager = nugetPackageManager, DataStore = new Dictionary <string, object>() }; var startup = new OpenModStartup(startupContext); startupContext.OpenModStartup = startup; foreach (var assembly in openModHostAssemblies) { startup.RegisterIocAssemblyAndCopyResources(assembly, string.Empty); } var configFile = Path.Combine(WorkingDirectory, "openmod.yaml"); if (File.Exists(configFile)) { var yaml = File.ReadAllText(configFile); var deserializer = new DeserializerBuilder() .WithTypeConverter(new YamlNullableEnumTypeConverter()) .WithNamingConvention(CamelCaseNamingConvention.Instance) .Build(); var config = deserializer.Deserialize <Dictionary <string, object> >(yaml); var hotReloadingEnabled = true; if (config.TryGetValue("hotreloading", out var unparsed)) { switch (unparsed) { case bool value: hotReloadingEnabled = value; break; case string strValue when bool.TryParse(strValue, out var parsed): hotReloadingEnabled = parsed; break; default: m_Logger.LogWarning( "Unknown config for 'hotreloading' in OpenMod configuration: {UnparsedConfig}", unparsed); break; } } Hotloader.Enabled = hotReloadingEnabled; var tryInstallMissingDependencies = false; if (config.TryGetValue("nuget", out unparsed) && unparsed is Dictionary <object, object> nugetConfig) { if (nugetConfig.TryGetValue("tryAutoInstallMissingDependencies", out unparsed)) { switch (unparsed) { case bool value: tryInstallMissingDependencies = value; break; case string strValue when bool.TryParse(strValue, out var parsed): tryInstallMissingDependencies = parsed; break; default: m_Logger.LogWarning( "Unknown config for 'tryAutoInstallMissingDependencies' in OpenMod configuration: {UnparsedConfig}", unparsed); break; } } } PluginAssemblyStore.TryInstallMissingDependencies = tryInstallMissingDependencies; } await nugetPackageManager.InstallMissingPackagesAsync(updateExisting : true); await startup.LoadPluginAssembliesAsync(); SetupSerilog(true); hostBuilder .UseContentRoot(parameters.WorkingDirectory) .UseServiceProviderFactory(new AutofacServiceProviderFactory()) .ConfigureHostConfiguration(builder => { ConfigureConfiguration(builder, startup); ((OpenModStartupContext)startup.Context).Configuration = builder.Build(); }) .ConfigureAppConfiguration(builder => ConfigureConfiguration(builder, startup)) .ConfigureContainer <ContainerBuilder>(builder => SetupContainer(builder, startup)) .ConfigureServices(services => SetupServices(services, startup)) .UseSerilog(); Host = hostBuilder.Build(); m_AppLifeTime = Host.Services.GetRequiredService <IHostApplicationLifetime>(); m_AppLifeTime.ApplicationStopping.Register(() => { AsyncHelper.RunSync(ShutdownAsync); }); Status = RuntimeStatus.Initialized; LifetimeScope = Host.Services.GetRequiredService <ILifetimeScope>().BeginLifetimeScopeEx( containerBuilder => { containerBuilder.Register(_ => this) .As <IOpenModComponent>() .SingleInstance() .ExternallyOwned(); containerBuilder.RegisterType <ScopedPermissionChecker>() .As <IPermissionChecker>() .InstancePerLifetimeScope() .OwnedByLifetimeScope(); }); DataStore = Host.Services.GetRequiredService <IDataStoreFactory>().CreateDataStore( new DataStoreCreationParameters { Component = this, Prefix = "openmod", Suffix = null, WorkingDirectory = WorkingDirectory }); try { await Host.StartAsync(); } catch (Exception ex) { Status = RuntimeStatus.Crashed; m_Logger.LogCritical(ex, "OpenMod has crashed"); Log.CloseAndFlush(); } PerformFileSystemWatcherPatch(); return(Host); } catch (Exception ex) { Console.WriteLine(ex); throw; } }