feat: add netssh uninstall
Remove everything netssh and install.sh set up, also leftovers of older versions: - netssh blocks and unmarked legacy lines in bash, zsh, and fish profiles - completion files for bash, zsh (incl. the oh-my-zsh cache), fish, and the command alias; files not generated by netssh are kept - the cache directory with hosts, aliases, and per-instance caches - the config file and local notes; the config is first copied to a private netssh.yaml.backup-<timestamp> because it holds API tokens - the netssh binary; for protected paths the sudo command is printed --keep-config keeps config and notes, --dry-run only lists the plan, and --yes skips the confirmation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
786768ec53
commit
c2e590bf52
6 files changed
+445
-1
No files matched your search
@@ -114,3 +114,46 @@ complete --command %s --wraps netssh
|
||||
`, completionMarker, alias)
|
||||
}
|
||||
}
|
||||
|
||||
// CompletionFiles lists the completion and alias files netssh may have
|
||||
// installed for itself and for the given command aliases.
|
||||
func CompletionFiles(aliases ...string) []string {
|
||||
files := []string{
|
||||
filepath.Join(os.Getenv("HOME"), ".local", "share", "bash-completion", "completions", "netssh"),
|
||||
filepath.Join(ZshFuncDir(), "_netssh"),
|
||||
filepath.Join(FishConfigDir(), "completions", "netssh.fish"),
|
||||
FishAliasesPath(),
|
||||
}
|
||||
// oh-my-zsh caches generated completions separately.
|
||||
for _, dir := range []string{os.Getenv("ZSH_CACHE_DIR"), filepath.Join(os.Getenv("ZSH"), "cache"), filepath.Join(os.Getenv("HOME"), ".oh-my-zsh", "cache")} {
|
||||
if dir != "" && dir != "cache" {
|
||||
files = append(files, filepath.Join(dir, "completions", "_netssh"))
|
||||
}
|
||||
}
|
||||
for _, alias := range aliases {
|
||||
if config.ValidateCommandAlias(alias) != nil || alias == "" {
|
||||
continue
|
||||
}
|
||||
for _, shell := range []string{"bash", "zsh", "fish"} {
|
||||
files = append(files, commandCompletionPath(shell, alias))
|
||||
}
|
||||
}
|
||||
return files
|
||||
}
|
||||
|
||||
// CompletionAliasState returns the command alias whose completion files were
|
||||
// last generated, or "" when there is none.
|
||||
func CompletionAliasState() string {
|
||||
data, err := os.ReadFile(filepath.Join(filepath.Dir(AliasesPath()), "completion_alias"))
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return strings.TrimSpace(string(data))
|
||||
}
|
||||
|
||||
// IsGenerated reports whether a completion file was written by netssh,
|
||||
// so uninstall never removes a user's own file of the same name.
|
||||
func IsGenerated(path string) bool {
|
||||
data, err := os.ReadFile(path)
|
||||
return err == nil && strings.Contains(string(data), "netssh")
|
||||
}
|
||||
@@ -166,6 +166,16 @@ func isLegacyLine(line string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// HasEntries reports whether the profile contains a managed block or legacy lines.
|
||||
func HasEntries(profilePath string) bool {
|
||||
data, err := os.ReadFile(profilePath)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
_, removed, err := clean(string(data), profilePath)
|
||||
return removed || err != nil
|
||||
}
|
||||
|
||||
// Uninstall removes legacy hook lines and complete installer-managed blocks.
|
||||
// Missing profiles are a no-op; malformed blocks leave the file unchanged.
|
||||
func Uninstall(profilePath string) (removed bool, err error) {
|
||||
@@ -248,3 +258,23 @@ func writeProfile(profilePath, content string) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ProfileCandidates lists every shell profile netssh or install.sh may have
|
||||
// written to, in the same order as the installer.
|
||||
func ProfileCandidates() []string {
|
||||
home := os.Getenv("HOME")
|
||||
zdot := zshDir()
|
||||
paths := []string{
|
||||
filepath.Join(home, ".bashrc"),
|
||||
filepath.Join(home, ".bash_profile"),
|
||||
filepath.Join(home, ".bash_login"),
|
||||
filepath.Join(home, ".profile"),
|
||||
filepath.Join(zdot, ".zshrc"),
|
||||
filepath.Join(zdot, ".zprofile"),
|
||||
filepath.Join(zdot, ".zshenv"),
|
||||
}
|
||||
if zdot != home {
|
||||
paths = append(paths, filepath.Join(home, ".zshrc"), filepath.Join(home, ".zprofile"), filepath.Join(home, ".zshenv"))
|
||||
}
|
||||
return append(paths, filepath.Join(FishConfigDir(), "config.fish"))
|
||||
}
|
||||
Reference in new issue
Block a user