diff --git a/app/Pog/lib_compiled/Pog/src/Commands/EnablePogCommand.cs b/app/Pog/lib_compiled/Pog/src/Commands/EnablePogCommand.cs index 4e00612..53e0820 100644 --- a/app/Pog/lib_compiled/Pog/src/Commands/EnablePogCommand.cs +++ b/app/Pog/lib_compiled/Pog/src/Commands/EnablePogCommand.cs @@ -170,6 +170,7 @@ protected override void ProcessPackage(ImportedPackage package) { RemoveStaleExports(package, ctx); } + // FIXME: in "NormalView" error view, the error looks slightly confusing, as it's designed for "ConciseView" private EnableScriptFailedException WrapContainerError(ImportedPackage package, RuntimeException e) { var ii = e.ErrorRecord.InvocationInfo; // replace the position info with a custom listing, since the script path is missing @@ -187,7 +188,7 @@ private EnableScriptFailedException WrapContainerError(ImportedPackage package, private void RemoveStaleExports(ImportedPackage package, EnableContainerContext ctx) { if (ctx.StaleShortcuts.Count > 0) RemoveStaleShortcuts(ctx.StaleShortcuts, package); if (ctx.StaleShortcutShims.Count > 0) RemoveStaleShortcutShims(ctx.StaleShortcutShims); - if (ctx.StaleCommands.Count > 0) RemoveStaleCommands(ctx.StaleCommands); + if (ctx.StaleCommands.Count > 0) RemoveStaleCommands(ctx.StaleCommands, package); } private void RemoveStaleShortcuts(IEnumerable staleShortcutPaths, ImportedPackage package) { @@ -222,7 +223,7 @@ private void RemoveStaleShortcutShims(IEnumerable staleShortcutShimPaths } } - private void RemoveStaleCommands(IEnumerable staleCommandPaths) { + private void RemoveStaleCommands(IEnumerable staleCommandPaths, ImportedPackage package) { WriteDebug("Removing stale commands..."); foreach (var path in staleCommandPaths) { if (FsUtils.FileExistsCaseSensitive(path)) { @@ -231,9 +232,9 @@ private void RemoveStaleCommands(IEnumerable staleCommandPaths) { } // delete the globally exported command, if there's any - var globalCmd = GlobalExportUtils.GetCommandExportPath(path); - if (FsUtils.GetSymbolicLinkTarget(globalCmd) == path) { - File.Delete(globalCmd); + var globalCommand = GloballyExportedCommand.FromLocal(path); + if (globalCommand.IsFromPackage(package)) { + globalCommand.Delete(); WriteDebug("Removed globally exported command."); } diff --git a/app/Pog/lib_compiled/Pog/src/Commands/ExportPogCommand.cs b/app/Pog/lib_compiled/Pog/src/Commands/ExportPogCommand.cs index 35822d7..63cd904 100644 --- a/app/Pog/lib_compiled/Pog/src/Commands/ExportPogCommand.cs +++ b/app/Pog/lib_compiled/Pog/src/Commands/ExportPogCommand.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.IO; using System.Linq; using System.Management.Automation; @@ -32,8 +31,10 @@ private void ExportShortcuts(ImportedPackage p) { continue; } } else { + var ownerPath = target.SourcePackagePath; if (target.OverwriteWith(shortcut)) { - WriteWarning($"Overwritten an existing shortcut '{shortcutName}'."); + WriteWarning($"Overwritten an existing shortcut '{shortcutName}' from package " + + $"'{Path.GetFileName(ownerPath)}'."); } else { // created new shortcut } @@ -43,49 +44,45 @@ private void ExportShortcuts(ImportedPackage p) { } } - private static IEnumerable EnumerateMatchingCommands(string dirPath, string cmdName) { - // filter out files with a dot before the extension (e.g. `arm-none-eabi-ld.bfd.exe`) - return Directory.EnumerateFiles(dirPath, $"{cmdName}.*").Where(cmdPath => { - return string.Equals(Path.GetFileNameWithoutExtension(cmdPath), cmdName, StringComparison.OrdinalIgnoreCase); - }); - } - private void ExportCommands(ImportedPackage p) { // ensure the export dir exists Directory.CreateDirectory(InternalState.PathConfig.ExportedCommandDir); foreach (var command in p.EnumerateExportedCommands()) { var cmdName = command.GetBaseName(); - var targetPath = GlobalExportUtils.GetCommandExportPath(command); + var target = GloballyExportedCommand.FromLocal(command.FullName); - if (command.FullName == FsUtils.GetSymbolicLinkTarget(targetPath)) { - WriteVerbose($"Command '{cmdName}' is already exported from this package."); + if (command.FullName == target.Target) { + WriteVerbose($"Command '{cmdName}' is already globally exported from this package."); continue; } - var matchingCommands = EnumerateMatchingCommands(InternalState.PathConfig.ExportedCommandDir, cmdName).ToArray(); + var matchingCommands = target.EnumerateConflictingCommands().ToArray(); if (matchingCommands.Length != 0) { WriteDebug($"Found {matchingCommands.Length} conflicting commands: {matchingCommands}"); if (matchingCommands.Length > 1) { - WriteWarning("Pog developers fucked something up, and there are multiple colliding commands. " + - "Plz send bug report."); + WriteWarning($"Pog developers fucked something up, and there are multiple colliding commands for " + + $"'{cmdName}', please send a bug report."); } + + var ownerPath = matchingCommands[0].SourcePackagePath; foreach (var collidingCmdPath in matchingCommands) { - File.Delete(collidingCmdPath); + collidingCmdPath.Delete(); } - WriteWarning($"Overwritten an existing command '{cmdName}'."); + + WriteWarning($"Overwritten an existing command '{cmdName}' from package '{Path.GetFileName(ownerPath)}'."); } try { - FsUtils.CreateSymbolicLink(targetPath, command.FullName, false); + target.UpdateFrom(command); } catch (Exception e) { var category = e is UnauthorizedAccessException ? ErrorCategory.PermissionDenied : ErrorCategory.NotSpecified; ThrowTerminatingError(new CommandExportException( - $"Could not export command '{cmdName}' from '{p.PackageName}', " + - $"symbolic link creation failed: {e.Message}", e), + $"Could not export command '{cmdName}' from '{p.PackageName}', symbolic link creation " + + $"failed: {e.Message}", e), "CommandExportFailed", category, cmdName); } WriteInformation($"Exported command '{cmdName}' from '{p.PackageName}'.", null); diff --git a/app/Pog/lib_compiled/Pog/src/ImportedPackage/GloballyExportedCommand.cs b/app/Pog/lib_compiled/Pog/src/ImportedPackage/GloballyExportedCommand.cs new file mode 100644 index 0000000..7792244 --- /dev/null +++ b/app/Pog/lib_compiled/Pog/src/ImportedPackage/GloballyExportedCommand.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Pog.Utils; +using IOPath = System.IO.Path; + +namespace Pog; + +internal class GloballyExportedCommand(string path) { + public readonly string Path = path; + + public bool Exists => FsUtils.FileExistsCaseSensitive(Path); + // take the target path and go ../.. (from `/.commands/name.exe`) + public string? SourcePackagePath => !Exists ? null : IOPath.GetDirectoryName(IOPath.GetDirectoryName(Target)); + public string? Target => FsUtils.GetSymbolicLinkTarget(Path); + + public static GloballyExportedCommand FromLocal(string localExportPath) { + var path = $"{InternalState.PathConfig.ExportedCommandDir}\\{IOPath.GetFileName(localExportPath)}"; + return new(path); + } + + public bool IsFromPackage(ImportedPackage p) => SourcePackagePath == p.Path; + + public void Delete() => File.Delete(Path); + + public void UpdateFrom(FileInfo localCmd) { + FsUtils.CreateSymbolicLink(Path, localCmd.FullName, false); + } + + public IEnumerable EnumerateConflictingCommands() { + var name = IOPath.GetFileNameWithoutExtension(Path); + // filter out files with a dot before the extension (e.g. `arm-none-eabi-ld.bfd.exe`) + return Directory.EnumerateFiles(InternalState.PathConfig.ExportedCommandDir, $"{name}.*") + .Where(cmdPath => string.Equals( + IOPath.GetFileNameWithoutExtension(cmdPath), name, StringComparison.OrdinalIgnoreCase)) + .Select(p => new GloballyExportedCommand(p)); + } +} diff --git a/app/Pog/lib_compiled/Pog/src/ImportedPackage/GloballyExportedShortcut.cs b/app/Pog/lib_compiled/Pog/src/ImportedPackage/GloballyExportedShortcut.cs index f342053..e6e4716 100644 --- a/app/Pog/lib_compiled/Pog/src/ImportedPackage/GloballyExportedShortcut.cs +++ b/app/Pog/lib_compiled/Pog/src/ImportedPackage/GloballyExportedShortcut.cs @@ -13,11 +13,15 @@ public static GloballyExportedShortcut FromLocal(string localExportPath) { return new(path); } - public bool IsFromPackage(ImportedPackage p) { - // we consider the shortcut matching if it exists and its source package matches instead of matching exact content; - // this ensures that if something caused the two shortcuts to desync previously, we can recover - return FsUtils.FileExistsCaseSensitive(Path) && ExportedShortcut.GetShortcutSource(new(Path)) == p.Path; - } + public bool Exists => FsUtils.FileExistsCaseSensitive(Path); + // somewhat expensive + public string? SourcePackagePath => !Exists ? null : ExportedShortcut.GetShortcutSource(new(Path)); + + // we consider the shortcut matching if it exists and its source package matches instead of matching exact content; + // this ensures that if something caused the two shortcuts to desync previously, we can recover + public bool IsFromPackage(ImportedPackage p) => SourcePackagePath == p.Path; + + public void Delete() => File.Delete(Path); public bool UpdateFrom(FileInfo localShortcut) { if (FsUtils.FileContentEqual(localShortcut, new(Path))) { @@ -43,8 +47,4 @@ public bool OverwriteWith(FileInfo localShortcut) { localShortcut.CopyTo(Path); return exists; } - - public void Delete() { - File.Delete(Path); - } } diff --git a/app/Pog/lib_compiled/Pog/src/InnerCommands/DisablePog.cs b/app/Pog/lib_compiled/Pog/src/InnerCommands/DisablePog.cs index 8446700..0944cb6 100644 --- a/app/Pog/lib_compiled/Pog/src/InnerCommands/DisablePog.cs +++ b/app/Pog/lib_compiled/Pog/src/InnerCommands/DisablePog.cs @@ -1,6 +1,5 @@ using System; using System.Diagnostics; -using System.IO; using System.Management.Automation; using Pog.InnerCommands.Common; using Pog.Utils; @@ -86,7 +85,7 @@ private void RemoveGloballyExportedShortcuts(ImportedPackage p) { var globalShortcut = GloballyExportedShortcut.FromLocal(shortcut.FullName); if (globalShortcut.IsFromPackage(p)) { globalShortcut.Delete(); - WriteInformation($"Removed an exported shortcut '{shortcut.GetBaseName()}'."); + WriteInformation($"Removed an exported shortcut '{shortcut.GetBaseName()}' from the Start menu."); } else { WriteVerbose($"Shortcut '{shortcut.GetBaseName()}' is not exported to the Start menu."); } @@ -95,13 +94,12 @@ private void RemoveGloballyExportedShortcuts(ImportedPackage p) { private void RemoveGloballyExportedCommands(ImportedPackage p) { foreach (var command in p.EnumerateExportedCommands()) { - var targetPath = GlobalExportUtils.GetCommandExportPath(command); - if (command.FullName == FsUtils.GetSymbolicLinkTarget(targetPath)) { - // found a matching command, delete it - File.Delete(targetPath); - WriteInformation($"Removed an exported command '{command.GetBaseName()}'."); + var globalCommand = GloballyExportedCommand.FromLocal(command.FullName); + if (globalCommand.IsFromPackage(p)) { + globalCommand.Delete(); + WriteInformation($"Removed an exported command '{command.GetBaseName()}' from PATH."); } else { - WriteVerbose($"Command '{command.GetBaseName()}' is not exported."); + WriteVerbose($"Command '{command.GetBaseName()}' is not exported to PATH."); } } } diff --git a/app/Pog/lib_compiled/Pog/src/Pog.GlobalExportUtils.cs b/app/Pog/lib_compiled/Pog/src/Pog.GlobalExportUtils.cs deleted file mode 100644 index d8a9ee1..0000000 --- a/app/Pog/lib_compiled/Pog/src/Pog.GlobalExportUtils.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.IO; - -namespace Pog; - -/// Class with utility functions for working with global exports (i.e. commands visible in PATH and Start menu shortcuts). -/// In this future, this will probably turn into a non-static class instantiated per export location (e.g. `ShortcutExportManager`). -internal static class GlobalExportUtils { - public static string GetCommandExportPath(string exportedCommandPath) { - return $"{InternalState.PathConfig.ExportedCommandDir}\\{Path.GetFileName(exportedCommandPath)}"; - } - - public static string GetCommandExportPath(FileInfo exportedCommand) { - return $"{InternalState.PathConfig.ExportedCommandDir}\\{exportedCommand.Name}"; - } -} diff --git a/app/Pog/lib_compiled/Pog/src/Pog.InternalError.cs b/app/Pog/lib_compiled/Pog/src/Pog.InternalError.cs index 3b29e79..1b9df7b 100644 --- a/app/Pog/lib_compiled/Pog/src/Pog.InternalError.cs +++ b/app/Pog/lib_compiled/Pog/src/Pog.InternalError.cs @@ -3,4 +3,4 @@ namespace Pog; public class InternalError(string message) - : Exception($"INTERNAL ERROR: {message} Seems like Pog developers fucked something up, plz send a bug report."); + : Exception($"INTERNAL ERROR: {message} Seems like Pog developers fucked something up, please send a bug report.");