diff --git a/.github/workflows/announce.yml b/.github/workflows/announce.yml index 23ba14b9..de6d6aaf 100644 --- a/.github/workflows/announce.yml +++ b/.github/workflows/announce.yml @@ -18,7 +18,7 @@ jobs: -d '{ "username": "mattpannella", "avatar_url": "https://avatars.githubusercontent.com/u/4806679", - "content": "Pupdate Release", + "content": "Bark bark, motherfuckers. A new version of Pupdate is available.", "embeds": [{ "color": 4819409, "title": "${{ github.event.release.name }}", diff --git a/README.md b/README.md index 69a6f424..e2e97e7a 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,12 @@ Checks for missing required assets for each core you have selected (mainly arcad -p, --path Absolute path to install location -c, --core The core you want to update. Runs for all otherwise -f, --platformsfolder Preserve the Platforms folder, so customizations aren't overwritten by updates. + -r, --clean Clean install. Remove all existing core files, and force a fresh re-install + + uninstall Delete a core + -p, --path Absolute path to install location + -c, --core The core you want to uninstall. Required + -a, --assets Delete the core specific Assets folder. ex: Assets/{platform}/{corename} assets Run the asset downloader -p, --path Absolute path to install location diff --git a/pupdate.csproj b/pupdate.csproj index a6f59a85..cd865444 100644 --- a/pupdate.csproj +++ b/pupdate.csproj @@ -6,7 +6,7 @@ net6.0 enable enable - 3.0.0 + 3.1.0 Keep your Analogue Pocket up to date 2023 Matt Pannella Matt Pannella diff --git a/src/Program.cs b/src/Program.cs index 533808a7..3b45fa72 100644 --- a/src/Program.cs +++ b/src/Program.cs @@ -33,13 +33,15 @@ private static async Task Main(string[] args) string? imagePackVariant = null; bool downloadFirmware = false; bool selfUpdate = false; + bool nuke = false; + bool cleanInstall = false; ConsoleKey response; string verb = "menu"; Dictionary data = new Dictionary(); Parser.Default.ParseArguments(args) + AssetsOptions, FirmwareOptions, ImagesOptions, InstancegeneratorOptions, UpdateSelfOptions, UninstallOptions>(args) .WithParsed(o => { selfUpdate = true; }) @@ -63,11 +65,27 @@ private static async Task Main(string[] args) if(o.PreservePlatformsFolder) { preservePlatformsFolder = true; } + if(o.CleanInstall) { + cleanInstall = true; + } if(o.CoreName != null && o.CoreName != "") { coreName = o.CoreName; } } ) + .WithParsed(async o => + { + verb = "uninstall"; + cliMode = true; + coreName = o.CoreName; + if(o.InstallPath != null && o.InstallPath != "") { + path = o.InstallPath; + } + if(o.DeleteAssets) { + nuke = true; + } + } + ) .WithParsed(async o => { verb = "assets"; @@ -238,7 +256,7 @@ private static async Task Main(string[] args) } if(forceUpdate) { Console.WriteLine("Starting update process..."); - await updater.RunUpdates(coreName); + await updater.RunUpdates(coreName, cleanInstall); Pause(); } else if(downloadFirmware) { await updater.UpdateFirmware(); @@ -257,6 +275,12 @@ private static async Task Main(string[] args) variant = imagePackVariant }; await InstallImagePack(path, pack); + } else if (verb == "uninstall") { + if (GlobalHelper.Instance.GetCore(coreName) == null) { + Console.WriteLine("Unknown core"); + } else { + await updater.DeleteCore(GlobalHelper.Instance.GetCore(coreName), true, nuke); + } } else { bool flag = true; while(flag) { @@ -1011,6 +1035,23 @@ public class UpdateOptions [Option('f', "platformsfolder", Required = false, HelpText = "Preserve the Platforms folder, so customizations aren't overwritten by updates.")] public bool PreservePlatformsFolder { get; set; } + + [Option('r', "clean", Required = false, HelpText = "Clean install. Remove all existing core files, before updating")] + public bool CleanInstall { get; set; } + +} + +[Verb("uninstall", HelpText = "Delete a core")] +public class UninstallOptions +{ + [Option('p', "path", HelpText = "Absolute path to install location", Required = false)] + public string? InstallPath { get; set; } + + [Option ('c', "core", Required = true, HelpText = "The core you want to delete.")] + public string CoreName { get; set; } + + [Option('a', "assets", Required = false, HelpText = "Delete the core specific Assets folder")] + public bool DeleteAssets { get; set; } } [Verb("assets", HelpText = "Run the asset downloader")] diff --git a/src/Updater.cs b/src/Updater.cs index 69507a04..53be43a6 100644 --- a/src/Updater.cs +++ b/src/Updater.cs @@ -199,7 +199,7 @@ public async Task BuildInstanceJSON(bool overwrite = false, string? corename = n /// /// Run the full openFPGA core download and update process /// - public async Task RunUpdates(string? id = null) + public async Task RunUpdates(string? id = null, bool clean = false) { List> installed = new List>(); List installedAssets = new List(); @@ -228,7 +228,7 @@ public async Task RunUpdates(string? id = null) core.buildInstances = (Factory.GetGlobals().SettingsManager.GetConfig().build_instance_jsons && (id==null)); try { if(Factory.GetGlobals().SettingsManager.GetCoreSettings(core.identifier).skip) { - _DeleteCore(core); + await DeleteCore(core); continue; } @@ -270,7 +270,7 @@ public async Task RunUpdates(string? id = null) _writeMessage("local core found: " + localVersion); } - if (mostRecentRelease != localVersion){ + if (mostRecentRelease != localVersion || clean){ _writeMessage("Updating core"); } else { await CopyBetaKey(core); @@ -289,7 +289,7 @@ public async Task RunUpdates(string? id = null) _writeMessage("Downloading core"); } - if(await core.Install(_githubApiKey)) { + if(await core.Install(clean)) { Dictionary summary = new Dictionary(); summary.Add("version", mostRecentRelease); summary.Add("core", core.identifier); @@ -545,13 +545,13 @@ public void DeleteSkippedCores(bool value) _deleteSkippedCores = value; } - private void _DeleteCore(Core core) + public async Task DeleteCore(Core core, bool force = false, bool nuke = false) { - if(!_deleteSkippedCores) { + if(!_deleteSkippedCores || !force) { return; } - core.Uninstall(); + core.Uninstall(nuke); } private void updater_StatusUpdated(object sender, StatusUpdatedEventArgs e) diff --git a/src/models/Core.cs b/src/models/Core.cs index 4db0b1b0..294f70dc 100644 --- a/src/models/Core.cs +++ b/src/models/Core.cs @@ -40,12 +40,15 @@ public override string ToString() return platform.name; } - public async Task Install(string githubApiKey = "") + public async Task Install(bool clean = false) { if(this.repository == null) { _writeMessage("Core installed manually. Skipping."); return false; } + if (clean && this.isInstalled()) { + Delete(); + } //iterate through assets to find the zip release return await _installGithubAsset(); } @@ -95,19 +98,38 @@ private bool checkUpdateDirectory() return true; } - public void Uninstall() + public void Delete(bool nuke = false) { - List folders = new List{"Cores", "Presets"}; + List folders = new List{"Cores", "Presets", "Settings"}; foreach(string folder in folders) { string path = Path.Combine(Factory.GetGlobals().UpdateDirectory, folder, this.identifier); if(Directory.Exists(path)) { - _writeMessage("Uninstalling " + path); + _writeMessage("Deleting " + path); + Directory.Delete(path, true); + } + } + if(nuke) { + string path = Path.Combine(Factory.GetGlobals().UpdateDirectory, "Assets", this.platform_id, this.identifier); + if (Directory.Exists(path)) { + _writeMessage("Deleting " + path); Directory.Delete(path, true); - Divide(); } } } + public void Uninstall(bool nuke = false) + { + _writeMessage("Uninstalling " + this.identifier); + + Delete(nuke); + + Factory.GetGlobals().SettingsManager.DisableCore(this.identifier); + Factory.GetGlobals().SettingsManager.SaveSettings(); + + _writeMessage("Finished"); + Divide(); + } + public Platform? ReadPlatformFile() { var info = this.getConfig();