diff --git a/.idea/.idea.UpTool2/.idea/projectSettingsUpdater.xml b/.idea/.idea.UpTool2/.idea/projectSettingsUpdater.xml index 7515e76..4bb9f4d 100644 --- a/.idea/.idea.UpTool2/.idea/projectSettingsUpdater.xml +++ b/.idea/.idea.UpTool2/.idea/projectSettingsUpdater.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/CLI.md b/CLI.md index 4981838..2fddfe8 100644 --- a/CLI.md +++ b/CLI.md @@ -1,5 +1,6 @@ # CLI -Updating the cache: uptool update + +### Package Management Installing a package (set \ to a file for local): uptool install \ @@ -11,17 +12,28 @@ Removing a package: uptool remove \ Removing a package and all its configuration and data files: uptool purge \ +Upgrade all packages: uptool dist-upgrade +### Cache Management List installed packages: uptool list -Upgrade all packages: uptool dist-upgrade - Search for a package: uptool search \ Show package info: uptool show \ -Start an app: uptool start \ +Updating the cache: uptool update +### Repos Management -Upgrading UpToolCLI: uptool upgrade-self \ No newline at end of file +Add a repository: uptool add-repo \ \ + +Remove a repository: uptool remove-repo \ + +List repositories: uptool list-repo + +### Other + +Upgrading UpToolCLI: uptool upgrade-self + +Start an app: uptool start \ \ No newline at end of file diff --git a/InstallerCLI/InstallerCLI.csproj b/InstallerCLI/InstallerCLI.csproj index a8fb99c..092ebc8 100644 --- a/InstallerCLI/InstallerCLI.csproj +++ b/InstallerCLI/InstallerCLI.csproj @@ -13,7 +13,7 @@ - + diff --git a/UpTool build tool/UpTool build tool.csproj b/UpTool build tool/UpTool build tool.csproj index 9c2bf60..5387aa0 100644 --- a/UpTool build tool/UpTool build tool.csproj +++ b/UpTool build tool/UpTool build tool.csproj @@ -16,6 +16,6 @@ - + \ No newline at end of file diff --git a/UpTool2/MainForm.cs b/UpTool2/MainForm.cs index 2ce3a90..0a62515 100644 --- a/UpTool2/MainForm.cs +++ b/UpTool2/MainForm.cs @@ -210,7 +210,9 @@ namespace UpTool2 File.WriteAllText(tmpFile, string.Join("\r\n\r\n", GlobalVariables.Apps.Values.Select(app => app.ToString()).Concat(new[] - {"Assembly version: " + Assembly.GetExecutingAssembly().GetName().Version}).ToArray())); + { + $"Assembly version: {Assembly.GetExecutingAssembly().GetName().Version}" + }).ToArray())); new Thread(() => { Process.Start("notepad", tmpFile).WaitForExit(); diff --git a/UpTool2/SourcesForm.Designer.cs b/UpTool2/SourcesForm.Designer.cs index b253ebb..3a9c270 100644 --- a/UpTool2/SourcesForm.Designer.cs +++ b/UpTool2/SourcesForm.Designer.cs @@ -21,20 +21,16 @@ } #region Windows Form Designer generated code - /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SettingsForms)); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(UpTool2.SettingsForms)); this.sourceGrid = new System.Windows.Forms.DataGridView(); - ((System.ComponentModel.ISupportInitialize)(this.sourceGrid)).BeginInit(); + ((System.ComponentModel.ISupportInitialize) (this.sourceGrid)).BeginInit(); this.SuspendLayout(); - // - // sourceGrid - // this.sourceGrid.BackgroundColor = System.Drawing.Color.White; this.sourceGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; this.sourceGrid.Dock = System.Windows.Forms.DockStyle.Fill; @@ -44,28 +40,24 @@ this.sourceGrid.Name = "sourceGrid"; this.sourceGrid.Size = new System.Drawing.Size(933, 519); this.sourceGrid.TabIndex = 0; - // - // SettingsForms - // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(933, 519); this.Controls.Add(this.sourceGrid); - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Icon = ((System.Drawing.Icon) (resources.GetObject("$this.Icon"))); this.Name = "SettingsForms"; this.ShowIcon = false; this.ShowInTaskbar = false; this.Text = "Sources"; this.TopMost = true; this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.SettingsForms_FormClosing); - ((System.ComponentModel.ISupportInitialize)(this.sourceGrid)).EndInit(); + ((System.ComponentModel.ISupportInitialize) (this.sourceGrid)).EndInit(); this.ResumeLayout(false); - } - #endregion - private System.Windows.Forms.DataGridView sourceGrid; +#endregion + private System.Windows.Forms.DataGridViewTextBoxColumn sbName; private System.Windows.Forms.DataGridViewTextBoxColumn sbLink; } diff --git a/UpTool2/SourcesForm.cs b/UpTool2/SourcesForm.cs index 322060a..bcc7dcc 100644 --- a/UpTool2/SourcesForm.cs +++ b/UpTool2/SourcesForm.cs @@ -15,6 +15,9 @@ namespace UpTool2 Program.FixXml(); _doc = XDocument.Load(PathTool.InfoXml); _repos = _doc.Element("meta").Element("Repos"); + sourceGrid.Columns.Clear(); + sourceGrid.Columns.Add("name", "Name"); + sourceGrid.Columns.Add("link", "Link"); foreach (XElement repo in _repos.Elements("Repo")) sourceGrid.Rows.Add(repo.Element("Name").Value, repo.Element("Link").Value); } diff --git a/UpToolCLI/CacheManagement.cs b/UpToolCLI/CacheManagement.cs new file mode 100644 index 0000000..bf096c2 --- /dev/null +++ b/UpToolCLI/CacheManagement.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.CommandLine; +using System.CommandLine.Invocation; +using System.Linq; +using UpToolLib; +using UpToolLib.DataStructures; +using UpToolLib.Tool; + +namespace UpToolCLI +{ + public static class CacheManagement + { + public static void RegisterCommands(RootCommand rootCommand) + { + rootCommand.AddCommand(new Command("list", "Lists installed packages") + { + Handler = CommandHandler.Create(List) + }); + + Command search = new Command("search", "Search for packages") + { + new Option(new[] {"--identifier", "-i"}, "Something to identify the app") + { + Required = true + } + }; + search.Handler = CommandHandler.Create(Search); + rootCommand.AddCommand(search); + + Command show = new Command("show", "Shows package info") + { + new Option(new[] {"--identifier", "-i"}, "Something to identify the app") + { + Required = true + } + }; + show.Handler = CommandHandler.Create(Show); + rootCommand.AddCommand(show); + + rootCommand.AddCommand(new Command("update", "Updates the cache") + { + Handler = CommandHandler.Create(Update) + }); + } + + private static void List() + { + RepoManagement.GetReposFromDisk(); + Console.WriteLine(GlobalVariables.Apps.Where(s => (s.Value.Status & Status.Installed) == Status.Installed).ToStringTable(new[] + { + "Name", "State", "Guid" + }, + u => u.Value.Name, + u => u.Value.Local ? "Local" : (u.Value.Status & Status.Updatable) == Status.Updatable ? "Updatable" : "None", + u => u.Key)); + } + + private static void Search(string identifier) + { + RepoManagement.GetReposFromDisk(); + App[] apps = AppExtras.FindApps(identifier); + Console.WriteLine($"Found {apps.Length} app(s)"); + if (apps.Length > 0) + Console.WriteLine(apps.ToStringTable(new[] + { + "Name", "Guid" + }, + u => u.Name, + u => u.Id)); + } + + private static void Show(string identifier) + { + RepoManagement.GetReposFromDisk(); + App[] apps = AppExtras.FindApps(identifier); + if (apps.Length == 0) + Console.WriteLine("Package not found."); + else + Console.WriteLine(apps.First()); + } + + private static void Update() + { + Console.WriteLine("Fetching Repos..."); + RepoManagement.FetchRepos(); + RepoManagement.GetReposFromDisk(); + Console.WriteLine(); + IEnumerable tmp = GlobalVariables.Apps.Where(s => + (s.Value.Status & Status.Updatable) == Status.Updatable).Select(s => s.Value); + IEnumerable apps = tmp as App[] ?? tmp.ToArray(); + int updatableCount = apps.Count(); + Console.WriteLine(updatableCount == 0 + ? "All up-to-date" + : $@"Found {updatableCount} Updates: +{string.Join(Environment.NewLine, apps.Select(s => $"- {s.Name} ({s.Version})"))}"); +#if !DEBUG + Version vLocal = Assembly.GetExecutingAssembly().GetName().Version; + Version vOnline = UpdateCheck.OnlineVersion; + if (vLocal < vOnline) + Console.WriteLine($"uptool is outdated ({vLocal} vs {vOnline}), update using \"uptool upgrade-self\""); +#endif + } + } +} \ No newline at end of file diff --git a/UpToolCLI/Other.cs b/UpToolCLI/Other.cs new file mode 100644 index 0000000..4fd3c7a --- /dev/null +++ b/UpToolCLI/Other.cs @@ -0,0 +1,100 @@ +using System; +using System.CommandLine; +using System.CommandLine.Invocation; +using System.Linq; +using UpToolLib.DataStructures; +using UpToolLib.Tool; +using Process = System.Diagnostics.Process; + +namespace UpToolCLI +{ + public class Other + { + public static void RegisterCommands(RootCommand rootCommand) + { + Command command = new Command("upgrade-self", "Upgrades UpToolCLI") + { + new Option(new[] {"--force", "-f"}, "Overwrites older files") + }; + command.Handler = CommandHandler.Create(UpgradeSelf); + rootCommand.AddCommand(command); + + Command start = new Command("start", "Starts an app") + { + new Option(new[] {"--identifier", "-i"}, "Something to identify the app") + { + Required = true + }, + new Option(new[] {"--waitForExit", "-wait"}, "Waits until the program quits") + }; + start.Handler = CommandHandler.Create(Start); + rootCommand.AddCommand(start); + } + + private static void UpgradeSelf(bool force) + { +#if DEBUG + Console.WriteLine("Not enabled in debug builds"); +#else + if (!force && Assembly.GetExecutingAssembly().GetName().Version >= UpdateCheck.OnlineVersion) + Console.WriteLine("Already up-to-date"); + else + { + Console.WriteLine("Downloading latest"); + (bool success, byte[] dl) = Functions.Download(UpdateCheck.Installer); + if (!success) + throw new Exception("Failed to update"); + Console.WriteLine("Verifying"); + using (SHA256CryptoServiceProvider sha256 = new SHA256CryptoServiceProvider()) + { + string pkgHash = BitConverter.ToString(sha256.ComputeHash(dl)).Replace("-", string.Empty).ToUpper(); + if (pkgHash != UpdateCheck.InstallerHash) + throw new Exception($@"The hash is not equal to the one stored in the repo: +Package: {pkgHash} +Online: {UpdateCheck.InstallerHash}"); + } + Console.WriteLine("Installing"); + if (Directory.Exists(PathTool.GetRelative("Install", "tmp"))) + Directory.Delete(PathTool.GetRelative("Install", "tmp"), true); + Directory.CreateDirectory(PathTool.GetRelative("Install", "tmp")); + using (MemoryStream ms = new MemoryStream(dl)) + { + using ZipArchive ar = new ZipArchive(ms); + ar.ExtractToDirectory(PathTool.GetRelative("Install", "tmp"), true); + } + string file = PathTool.GetRelative("Install", "tmp", "Installer.exe"); + Console.WriteLine($"Starting {file}"); + Process.Start(new ProcessStartInfo + { + FileName = file, + Arguments = "i", + WorkingDirectory = PathTool.GetRelative("Install"), + UseShellExecute = false + }); + } +#endif + } + + private static void Start(string identifier, bool waitForExit) + { + RepoManagement.GetReposFromDisk(); + App[] apps = AppExtras.FindApps(identifier); + if (apps.Length == 0) + Console.WriteLine("Package not found."); + else + { + App tmp = apps.First(); + if (tmp.Runnable) + { + Console.WriteLine($"Starting {tmp.Name}"); + Process tmp1 = AppExtras.RunApp(tmp); + if (waitForExit) + tmp1.WaitForExit(); + } + else + Console.WriteLine($"{tmp.Name} is not runnable"); + } + Console.WriteLine("Done!"); + } + } +} \ No newline at end of file diff --git a/UpToolCLI/PackageManagement.cs b/UpToolCLI/PackageManagement.cs new file mode 100644 index 0000000..e567030 --- /dev/null +++ b/UpToolCLI/PackageManagement.cs @@ -0,0 +1,206 @@ +using System; +using System.Collections.Generic; +using System.CommandLine; +using System.CommandLine.Invocation; +using System.Drawing; +using System.IO; +using System.Linq; +using UpToolLib; +using UpToolLib.DataStructures; +using UpToolLib.Tool; + +namespace UpToolCLI +{ + public static class PackageManagement + { + public static void RegisterCommands(RootCommand rootCommand) + { + Command install = new Command("install", "Install a package") + { + new Option(new[] {"--identifier", "-i"}, "Something to identify the app or the file name") + { + Required = true + }, + new Option(new[] {"--force", "-f"}, "Overwrites older files") + }; + install.Handler = CommandHandler.Create(Install); + rootCommand.AddCommand(install); + + Command upgrade = new Command("upgrade", "Upgrade a package") + { + new Option(new[] {"--identifier", "-i"}, "Something to identify the app") + { + Required = true + }, + new Option(new[] {"--force", "-f"}, "Overwrites older files") + }; + upgrade.Handler = CommandHandler.Create(Upgrade); + rootCommand.AddCommand(upgrade); + + Command reinstall = new Command("reinstall", "Reinstall a package") + { + new Option(new[] {"--identifier", "-i"}, "Something to identify the app") + { + Required = true + }, + new Option(new[] {"--force", "-f"}, "Overwrites older files") + }; + reinstall.Handler = CommandHandler.Create(Reinstall); + rootCommand.AddCommand(reinstall); + + Command remove = new Command("remove", "Remove a package") + { + new Option(new[] {"--identifier", "-i"}, "Something to identify the app") + { + Required = true + } + }; + remove.Handler = CommandHandler.Create(Remove); + rootCommand.AddCommand(remove); + + Command purge = new Command("purge", "Completely remove a package") + { + new Option(new[] {"--identifier", "-i"}, "Something to identify the app") + { + Required = true + } + }; + purge.Handler = CommandHandler.Create(Purge); + rootCommand.AddCommand(purge); + + rootCommand.AddCommand(new Command("dist-upgrade", "Upgrades all packages") + { + Handler = CommandHandler.Create(DistUpgrade) + }); + } + + private static void Install(string identifier, bool force) + { + RepoManagement.GetReposFromDisk(); + App[] apps = AppExtras.FindApps(identifier); + if (apps.Length == 0) + { + if (File.Exists(identifier)) + { + Console.WriteLine("Name:"); + string name = Console.ReadLine(); + AppInstall.InstallZip(identifier, new App(name, "Locally installed package, removal only", + GlobalVariables.MinimumVer, "", true, "", + Guid.NewGuid(), Color.Red, "", false, ""), force); + Console.WriteLine($"Successfully installed \"{name}\""); + } + else + { + Console.WriteLine("Package not found."); + Console.WriteLine(identifier); + } + } + else + { + App tmp = apps.First(); + if ((tmp.Status & Status.Installed) == Status.Installed) + Console.WriteLine("Package is already installed"); + else + { + Console.WriteLine($"Installing {tmp.Name}"); + AppInstall.Install(tmp, true); + } + } + Console.WriteLine("Done!"); + } + + private static void Upgrade(string identifier, bool force) + { + RepoManagement.GetReposFromDisk(); + App[] apps = AppExtras.FindApps(identifier); + if (apps.Length == 0) + Console.WriteLine("Package not found."); + else + { + App tmp = apps.First(); + if ((tmp.Status & Status.Updatable) == Status.Updatable) + { + Console.WriteLine($"Upgrading {tmp.Name}"); + AppExtras.Update(tmp, force); + } + else + Console.WriteLine("Package is up-to-date"); + } + Console.WriteLine("Done!"); + } + + private static void Reinstall(string identifier, bool force) + { + RepoManagement.GetReposFromDisk(); + App[] apps = AppExtras.FindApps(identifier); + if (apps.Length == 0) + Console.WriteLine("Package not found."); + else + { + App tmp = apps.First(); + Console.WriteLine($"Reinstalling {tmp.Name}"); + AppExtras.Update(tmp, force); + } + Console.WriteLine("Done!"); + } + + private static void Remove(string identifier) + { + RepoManagement.GetReposFromDisk(); + App[] apps = AppExtras.FindApps(identifier); + if (apps.Length == 0) + Console.WriteLine("Package not found."); + else + { + App tmp = apps.First(); + if ((tmp.Status & Status.Installed) == Status.Installed) + { + Console.WriteLine($"Removing {tmp.Name}"); + AppExtras.Remove(tmp, false); + } + else + Console.WriteLine("Package is not installed"); + } + Console.WriteLine("Done!"); + } + + private static void Purge(string identifier) + { + RepoManagement.GetReposFromDisk(); + App[] apps = AppExtras.FindApps(identifier); + if (apps.Length == 0) + Console.WriteLine("Package not found."); + else + { + App tmp = apps.First(); + if ((tmp.Status & Status.Installed) == Status.Installed) + { + Console.WriteLine($"Purgeing {tmp.Name}"); + AppExtras.Remove(tmp, true); + } + else + Console.WriteLine("Package is not installed"); + } + Console.WriteLine("Done!"); + } + + private static void DistUpgrade() + { + RepoManagement.GetReposFromDisk(); + foreach (KeyValuePair app in GlobalVariables.Apps.Where(s => + (s.Value.Status & Status.Updatable) == Status.Updatable)) + { + Console.WriteLine($"Updating {app.Value.Name}"); + AppExtras.Update(app.Value, false); + } +#if !DEBUG + if (Assembly.GetExecutingAssembly().GetName().Version < UpdateCheck.OnlineVersion) + { + Console.WriteLine("Updating self"); + UpgradeSelf(false); + } +#endif + Console.WriteLine("Done!"); + } + } +} \ No newline at end of file diff --git a/UpToolCLI/Program.cs b/UpToolCLI/Program.cs index 483d211..7b13f62 100644 --- a/UpToolCLI/Program.cs +++ b/UpToolCLI/Program.cs @@ -1,18 +1,7 @@ using System; -using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.Invocation; -using System.Diagnostics; -using System.Drawing; -using System.IO; -using System.IO.Compression; -using System.Linq; -using System.Reflection; -using System.Security.Cryptography; using UpToolLib; -using UpToolLib.DataStructures; using UpToolLib.Tool; -using Process = System.Diagnostics.Process; namespace UpToolCLI { @@ -28,87 +17,12 @@ namespace UpToolCLI XmlTool.FixXml(); ExternalFunctionalityManager.Init(Functions); RootCommand rootCommand = new RootCommand(); - rootCommand.AddCommand(new Command("update", "Updates the cache") - { - Handler = CommandHandler.Create(Update) - }); - - Command install = new Command("install", "Install a package") - { - new Option(new[] {"--identifier", "-i"}, "Something to identify the app or the file name"), - new Option(new[] {"--force", "-f"}, "Overwrites older files") - }; - install.Handler = CommandHandler.Create(Install); - rootCommand.AddCommand(install); - - Command upgrade = new Command("upgrade", "Upgrade a package") - { - new Option(new[] {"--identifier", "-i"}, "Something to identify the app"), - new Option(new[] {"--force", "-f"}, "Overwrites older files") - }; - upgrade.Handler = CommandHandler.Create(Upgrade); - rootCommand.AddCommand(upgrade); - - Command command = new Command("upgrade-self", "Upgrades UpToolCLI") - { - new Option(new[] {"--force", "-f"}, "Overwrites older files") - }; - command.Handler = CommandHandler.Create(UpgradeSelf); - rootCommand.AddCommand(command); - - Command reinstall = new Command("reinstall", "Reinstall a package") - { - new Option(new[] {"--identifier", "-i"}, "Something to identify the app"), - new Option(new[] {"--force", "-f"}, "Overwrites older files") - }; - reinstall.Handler = CommandHandler.Create(Reinstall); - rootCommand.AddCommand(reinstall); - - Command remove = new Command("remove", "Remove a package") - { - new Option(new[] {"--identifier", "-i"}, "Something to identify the app") - }; - remove.Handler = CommandHandler.Create(Remove); - rootCommand.AddCommand(remove); - - Command purge = new Command("purge", "Completely remove a package") - { - new Option(new[] {"--identifier", "-i"}, "Something to identify the app") - }; - purge.Handler = CommandHandler.Create(Purge); - rootCommand.AddCommand(purge); - - rootCommand.AddCommand(new Command("list", "Lists installed packages") - { - Handler = CommandHandler.Create(List) - }); - - rootCommand.AddCommand(new Command("dist-upgrade", "Upgrades all packages") - { - Handler = CommandHandler.Create(DistUpgrade) - }); - - Command search = new Command("search", "Search for packages") - { - new Option(new[] {"--identifier", "-i"}, "Something to identify the app") - }; - search.Handler = CommandHandler.Create(Search); - rootCommand.AddCommand(search); - - Command show = new Command("show", "Shows package info") - { - new Option(new[] {"--identifier", "-i"}, "Something to identify the app") - }; - show.Handler = CommandHandler.Create(Show); - rootCommand.AddCommand(show); - - Command start = new Command("start", "Starts an app") - { - new Option(new[] {"--identifier", "-i"}, "Something to identify the app"), - new Option(new[] {"--waitForExit", "-wait"}, "Waits until the program quits") - }; - start.Handler = CommandHandler.Create(Start); - rootCommand.AddCommand(start); + + PackageManagement.RegisterCommands(rootCommand); + CacheManagement.RegisterCommands(rootCommand); + ReposManagement.RegisterCommands(rootCommand); + Other.RegisterCommands(rootCommand); + return rootCommand.InvokeAsync(args).Result; } catch (Exception e) @@ -121,256 +35,5 @@ namespace UpToolCLI MutexLock.Unlock(); } } - - private static void UpgradeSelf(bool force) - { -#if DEBUG - Console.WriteLine("Not enabled in debug builds"); -#else - if (!force && Assembly.GetExecutingAssembly().GetName().Version >= UpdateCheck.OnlineVersion) - Console.WriteLine("Already up-to-date"); - else - { - Console.WriteLine("Downloading latest"); - (bool success, byte[] dl) = Functions.Download(UpdateCheck.Installer); - if (!success) - throw new Exception("Failed to update"); - Console.WriteLine("Verifying"); - using (SHA256CryptoServiceProvider sha256 = new SHA256CryptoServiceProvider()) - { - string pkgHash = BitConverter.ToString(sha256.ComputeHash(dl)).Replace("-", string.Empty).ToUpper(); - if (pkgHash != UpdateCheck.InstallerHash) - throw new Exception($@"The hash is not equal to the one stored in the repo: -Package: {pkgHash} -Online: {UpdateCheck.InstallerHash}"); - } - Console.WriteLine("Installing"); - if (Directory.Exists(PathTool.GetRelative("Install", "tmp"))) - Directory.Delete(PathTool.GetRelative("Install", "tmp"), true); - Directory.CreateDirectory(PathTool.GetRelative("Install", "tmp")); - using (MemoryStream ms = new MemoryStream(dl)) - { - using ZipArchive ar = new ZipArchive(ms); - ar.ExtractToDirectory(PathTool.GetRelative("Install", "tmp"), true); - } - string file = PathTool.GetRelative("Install", "tmp", "Installer.exe"); - Console.WriteLine($"Starting {file}"); - Process.Start(new ProcessStartInfo - { - FileName = file, - Arguments = "i", - WorkingDirectory = PathTool.GetRelative("Install"), - UseShellExecute = false - }); - } -#endif - } - - private static void Update() - { - Console.WriteLine("Fetching Repos..."); - RepoManagement.FetchRepos(); - RepoManagement.GetReposFromDisk(); - Console.WriteLine(); - IEnumerable tmp = GlobalVariables.Apps.Where(s => - (s.Value.Status & Status.Updatable) == Status.Updatable).Select(s => s.Value); - IEnumerable apps = tmp as App[] ?? tmp.ToArray(); - int updatableCount = apps.Count(); - Console.WriteLine(updatableCount == 0 - ? "All up-to-date" - : $@"Found {updatableCount} Updates: -{string.Join(Environment.NewLine, apps.Select(s => $"- {s.Name} ({s.Version})"))}"); -#if !DEBUG - Version vLocal = Assembly.GetExecutingAssembly().GetName().Version; - Version vOnline = UpdateCheck.OnlineVersion; - if (vLocal < vOnline) - Console.WriteLine($"uptool is outdated ({vLocal} vs {vOnline}), update using \"uptool upgrade-self\""); -#endif - } - - private static void List() - { - RepoManagement.GetReposFromDisk(); - foreach (KeyValuePair app in GlobalVariables.Apps.Where(s => - (s.Value.Status & Status.Installed) == Status.Installed)) - { - Console.BackgroundColor = (app.Value.Status & Status.Local) == Status.Local ? ConsoleColor.DarkRed : - (app.Value.Status & Status.Updatable) == Status.Updatable ? ConsoleColor.DarkGreen : - ConsoleColor.Black; - Console.ForegroundColor = ConsoleColor.White; - Console.WriteLine($"{app.Value.Name} ({app.Key})"); - } - Console.ResetColor(); - } - - private static void DistUpgrade() - { - RepoManagement.GetReposFromDisk(); - foreach (KeyValuePair app in GlobalVariables.Apps.Where(s => - (s.Value.Status & Status.Updatable) == Status.Updatable)) - { - Console.WriteLine($"Updating {app.Value.Name}"); - AppExtras.Update(app.Value, false); - } -#if !DEBUG - if (Assembly.GetExecutingAssembly().GetName().Version < UpdateCheck.OnlineVersion) - { - Console.WriteLine("Updating self"); - UpgradeSelf(false); - } -#endif - Console.WriteLine("Done!"); - } - - private static void Show(string identifier) - { - RepoManagement.GetReposFromDisk(); - App[] apps = AppExtras.FindApps(identifier); - if (apps.Length == 0) - Console.WriteLine("Package not found."); - else - Console.WriteLine(apps.First()); - } - - private static void Search(string identifier) - { - RepoManagement.GetReposFromDisk(); - App[] apps = AppExtras.FindApps(identifier); - Console.WriteLine($"Found {apps.Length} app(s)"); - for (int i = 0; i < apps.Length; i++) - Console.WriteLine($"{apps[i].Name} ({apps[i].Id})"); - } - - private static void Upgrade(string identifier, bool force) - { - RepoManagement.GetReposFromDisk(); - App[] apps = AppExtras.FindApps(identifier); - if (apps.Length == 0) - Console.WriteLine("Package not found."); - else - { - App tmp = apps.First(); - if ((tmp.Status & Status.Updatable) == Status.Updatable) - { - Console.WriteLine($"Upgrading {tmp.Name}"); - AppExtras.Update(tmp, force); - } - else - Console.WriteLine("Package is up-to-date"); - } - Console.WriteLine("Done!"); - } - - private static void Reinstall(string identifier, bool force) - { - RepoManagement.GetReposFromDisk(); - App[] apps = AppExtras.FindApps(identifier); - if (apps.Length == 0) - Console.WriteLine("Package not found."); - else - { - App tmp = apps.First(); - Console.WriteLine($"Reinstalling {tmp.Name}"); - AppExtras.Update(tmp, force); - } - Console.WriteLine("Done!"); - } - - private static void Remove(string identifier) - { - RepoManagement.GetReposFromDisk(); - App[] apps = AppExtras.FindApps(identifier); - if (apps.Length == 0) - Console.WriteLine("Package not found."); - else - { - App tmp = apps.First(); - if ((tmp.Status & Status.Installed) == Status.Installed) - { - Console.WriteLine($"Removing {tmp.Name}"); - AppExtras.Remove(tmp, false); - } - else - Console.WriteLine("Package is not installed"); - } - Console.WriteLine("Done!"); - } - - private static void Purge(string identifier) - { - RepoManagement.GetReposFromDisk(); - App[] apps = AppExtras.FindApps(identifier); - if (apps.Length == 0) - Console.WriteLine("Package not found."); - else - { - App tmp = apps.First(); - if ((tmp.Status & Status.Installed) == Status.Installed) - { - Console.WriteLine($"Purgeing {tmp.Name}"); - AppExtras.Remove(tmp, true); - } - else - Console.WriteLine("Package is not installed"); - } - Console.WriteLine("Done!"); - } - - private static void Install(string identifier, bool force) - { - RepoManagement.GetReposFromDisk(); - App[] apps = AppExtras.FindApps(identifier); - if (apps.Length == 0) - { - if (File.Exists(identifier)) - { - Console.WriteLine("Name:"); - string name = Console.ReadLine(); - AppInstall.InstallZip(identifier, new App(name, "Locally installed package, removal only", - GlobalVariables.MinimumVer, "", true, "", - Guid.NewGuid(), Color.Red, "", false, ""), force); - Console.WriteLine($"Successfully installed \"{name}\""); - } - else - { - Console.WriteLine("Package not found."); - Console.WriteLine(identifier); - } - } - else - { - App tmp = apps.First(); - if ((tmp.Status & Status.Installed) == Status.Installed) - Console.WriteLine("Package is already installed"); - else - { - Console.WriteLine($"Installing {tmp.Name}"); - AppInstall.Install(tmp, true); - } - } - Console.WriteLine("Done!"); - } - - private static void Start(string identifier, bool waitForExit) - { - RepoManagement.GetReposFromDisk(); - App[] apps = AppExtras.FindApps(identifier); - if (apps.Length == 0) - Console.WriteLine("Package not found."); - else - { - App tmp = apps.First(); - if (tmp.Runnable) - { - Console.WriteLine($"Starting {tmp.Name}"); - Process tmp1 = AppExtras.RunApp(tmp); - if (waitForExit) - tmp1.WaitForExit(); - } - else - Console.WriteLine($"{tmp.Name} is not runnable"); - } - Console.WriteLine("Done!"); - } } } \ No newline at end of file diff --git a/UpToolCLI/ReposManagement.cs b/UpToolCLI/ReposManagement.cs new file mode 100644 index 0000000..9e3319b --- /dev/null +++ b/UpToolCLI/ReposManagement.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Generic; +using System.CommandLine; +using System.CommandLine.Invocation; +using System.Linq; +using System.Xml.Linq; +using UpToolLib.Tool; + +namespace UpToolCLI +{ + public class ReposManagement + { + public static void RegisterCommands(RootCommand rootCommand) + { + rootCommand.AddCommand(new Command("list-repo", "Lists current repositories") + { + Handler = CommandHandler.Create(ListRepo) + }); + + Command addRepo = new Command("add-repo", "Adds a repository") + { + new Option(new[] {"--name", "-n"}, "The new repositories name") + { + Required = true + }, + new Option(new[]{"--link", "-l"}, "A link to the repositories XML") + { + Required = true + } + }; + addRepo.Handler = CommandHandler.Create(AddRepo); + rootCommand.AddCommand(addRepo); + + Command removeRepo = new Command("remove-repo", "Removes a repository") + { + new Option(new[] {"--name", "-n"}, "The repositories name") + { + Required = true + } + }; + removeRepo.Handler = CommandHandler.Create(RemoveRepo); + rootCommand.AddCommand(removeRepo); + } + + private static void ListRepo() + { + XDocument doc = XDocument.Load(PathTool.InfoXml); + XElement repos = doc.Element("meta").Element("Repos"); + Console.WriteLine("Current repos:"); + Console.WriteLine(repos.Elements("Repo").ToStringTable(new[] + { + "Name", "Link" + }, + u => u.Element("Name").Value, + u => u.Element("Link").Value)); + } + + private static void AddRepo(string name, string link) + { + XDocument doc = XDocument.Load(PathTool.InfoXml); + XElement repos = doc.Element("meta").Element("Repos"); + repos.Add(new XElement("Repo", new XElement("Name", name), + new XElement("Link", link))); + doc.Save(PathTool.InfoXml); + Console.WriteLine("Added repo. Remember to update the cache using \"uptool update\""); + } + + private static void RemoveRepo(string name) + { + XDocument doc = XDocument.Load(PathTool.InfoXml); + XElement repos = doc.Element("meta").Element("Repos"); + XElement[] sRepos = repos.Elements("Repo") + .Where(s => s.Element("Name").Value.ToLower().StartsWith(name.ToLower())).ToArray(); + switch (sRepos.Length) + { + case 0: + Console.WriteLine("No repo was found that matches your input!"); + return; + case 1: + break; + default: + Console.WriteLine("Found multiple repos that match your input:"); + Console.WriteLine(sRepos.ToStringTable(new[] + { + "Name", "Link" + }, + u => u.Element("Name").Value, + u => u.Element("Link").Value)); + Console.WriteLine("Are you sure you want to delete them all? (y/n)"); + ConsoleKey k; + do + k = Console.ReadKey().Key; + while (k != ConsoleKey.Y && k != ConsoleKey.N); + if (k == ConsoleKey.N || k != ConsoleKey.Y) + return; + break; + } + for (int i = 0; i < sRepos.Length; i++) + { + Console.WriteLine($"Removing {sRepos[i].Element("Name").Value}"); + sRepos[i].Remove(); + } + doc.Save(PathTool.InfoXml); + Console.WriteLine("Removed repo. Remember to update the cache using \"uptool update\""); + } + } +} \ No newline at end of file diff --git a/UpToolCLI/TableParser.cs b/UpToolCLI/TableParser.cs new file mode 100644 index 0000000..333baea --- /dev/null +++ b/UpToolCLI/TableParser.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; + +namespace UpToolCLI +{ + public static class TableParser + { + public static string ToStringTable(this IEnumerable values, string[] columnHeaders, params Func[] valueSelectors) => ToStringTable(values.ToArray(), columnHeaders, valueSelectors); + + public static string ToStringTable(this T[] values, string[] columnHeaders, params Func[] valueSelectors) + { + Debug.Assert(columnHeaders.Length == valueSelectors.Length); + + string[,] arrValues = new string[values.Length + 1, valueSelectors.Length]; + + // Fill headers + for (int colIndex = 0; colIndex < arrValues.GetLength(1); colIndex++) arrValues[0, colIndex] = columnHeaders[colIndex]; + + // Fill table rows + for (int rowIndex = 1; rowIndex < arrValues.GetLength(0); rowIndex++) + for (int colIndex = 0; colIndex < arrValues.GetLength(1); colIndex++) + { + object value = valueSelectors[colIndex].Invoke(values[rowIndex - 1]); + + arrValues[rowIndex, colIndex] = value != null ? value.ToString() : "null"; + } + + return ToStringTable(arrValues); + } + + public static string ToStringTable(this string[,] arrValues) + { + int[] maxColumnsWidth = GetMaxColumnsWidth(arrValues); + string headerSpliter = new string('-', maxColumnsWidth.Sum(i => i + 3) - 1); + + StringBuilder sb = new StringBuilder(); + for (int rowIndex = 0; rowIndex < arrValues.GetLength(0); rowIndex++) + { + for (int colIndex = 0; colIndex < arrValues.GetLength(1); colIndex++) + { + // Print cell + string cell = arrValues[rowIndex, colIndex]; + cell = cell.PadRight(maxColumnsWidth[colIndex]); + sb.Append(" | "); + sb.Append(cell); + } + + // Print end of line + sb.Append(" | "); + sb.AppendLine(); + + // Print splitter + if (rowIndex == 0) + { + sb.AppendFormat(" |{0}| ", headerSpliter); + sb.AppendLine(); + } + } + + return sb.ToString(); + } + + private static int[] GetMaxColumnsWidth(string[,] arrValues) + { + int[] maxColumnsWidth = new int[arrValues.GetLength(1)]; + for (int colIndex = 0; colIndex < arrValues.GetLength(1); colIndex++) + for (int rowIndex = 0; rowIndex < arrValues.GetLength(0); rowIndex++) + { + int newLength = arrValues[rowIndex, colIndex].Length; + int oldLength = maxColumnsWidth[colIndex]; + + if (newLength > oldLength) maxColumnsWidth[colIndex] = newLength; + } + + return maxColumnsWidth; + } + + public static string ToStringTable(this IEnumerable values, params Expression>[] valueSelectors) + { + string[] headers = valueSelectors.Select(func => GetProperty(func).Name).ToArray(); + Func[] selectors = valueSelectors.Select(exp => exp.Compile()).ToArray(); + return ToStringTable(values, headers, selectors); + } + + private static PropertyInfo GetProperty(Expression> expresstion) + { + if (expresstion.Body is UnaryExpression expression) + if (expression.Operand is MemberExpression memberExpression) + return memberExpression.Member as PropertyInfo; + + if (expresstion.Body is MemberExpression body) return body.Member as PropertyInfo; + return null; + } + } +} \ No newline at end of file diff --git a/UpToolCLI/UpToolCLI.csproj b/UpToolCLI/UpToolCLI.csproj index 070953f..abb6db1 100644 --- a/UpToolCLI/UpToolCLI.csproj +++ b/UpToolCLI/UpToolCLI.csproj @@ -14,7 +14,7 @@ - +