feat: iris uninstall command (#21)
New uninstall command option ```bash IRIS uninstall ``` Fix install and uninstall script
This commit is contained in:
@@ -0,0 +1,147 @@
|
|||||||
|
package root
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/versenilvis/iris/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(uninstallCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
var uninstallCmd = &cobra.Command{
|
||||||
|
Use: "uninstall",
|
||||||
|
Short: "Uninstall Iris and remove shell integrations",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
fmt.Println("Uninstalling Iris...")
|
||||||
|
home, err := os.UserHomeDir()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("! could not determine home directory: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
configFiles := []string{
|
||||||
|
filepath.Join(home, ".zshrc"),
|
||||||
|
filepath.Join(home, ".bashrc"),
|
||||||
|
filepath.Join(home, ".config", "fish", "config.fish"),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, file := range configFiles {
|
||||||
|
if cleanShellConfig(file) {
|
||||||
|
fmt.Printf("✓ Removed integration from %s\n", file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove config, state, and cache directories
|
||||||
|
if cfgPath, err := config.ConfigPath(); err == nil {
|
||||||
|
if cfgDir := filepath.Dir(cfgPath); os.RemoveAll(cfgDir) == nil {
|
||||||
|
fmt.Printf("✓ Removed config directory: %s\n", cfgDir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if statePath, err := config.StatePath(); err == nil {
|
||||||
|
if stateDir := filepath.Dir(statePath); os.RemoveAll(stateDir) == nil {
|
||||||
|
fmt.Printf("✓ Removed state directory: %s\n", stateDir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if cachePath, err := config.CachePath(); err == nil {
|
||||||
|
if os.RemoveAll(cachePath) == nil {
|
||||||
|
fmt.Printf("✓ Removed cache directory: %s\n", cachePath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binLocations := []string{
|
||||||
|
filepath.Join(home, ".local", "bin", "iris"),
|
||||||
|
"/usr/local/bin/iris",
|
||||||
|
}
|
||||||
|
if exe, err := os.Executable(); err == nil && exe != "" {
|
||||||
|
binLocations = append(binLocations, exe)
|
||||||
|
}
|
||||||
|
|
||||||
|
anyFound := false
|
||||||
|
for _, loc := range binLocations {
|
||||||
|
if _, err := os.Stat(loc); err == nil {
|
||||||
|
anyFound = true
|
||||||
|
if errRemove := os.Remove(loc); errRemove == nil {
|
||||||
|
fmt.Printf("✓ Removed binary: %s\n", loc)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("! Could not remove binary at %s (try with sudo): %v\n", loc, errRemove)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !anyFound {
|
||||||
|
fmt.Println("✓ No leftover binary files found")
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = os.Remove("iris.log")
|
||||||
|
|
||||||
|
fmt.Println("\n✓ Iris has been successfully uninstalled")
|
||||||
|
if os.Getenv("IRIS_PID") != "" {
|
||||||
|
fmt.Println("\n⚠️ You are currently inside an active Iris session.")
|
||||||
|
fmt.Println("Iris runs as the parent process of this terminal - do NOT run 'pkill iris'")
|
||||||
|
fmt.Println("as it will immediately close this terminal window.")
|
||||||
|
fmt.Println("\nTo fully exit, simply close this terminal window and open a new one.")
|
||||||
|
fmt.Println("Iris will not start again since the shell config has been cleaned up.")
|
||||||
|
} else {
|
||||||
|
fmt.Println("Please close and reopen your terminal to complete the uninstall.")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func cleanShellConfig(filePath string) bool {
|
||||||
|
content, err := os.ReadFile(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var lines []string
|
||||||
|
scanner := bufio.NewScanner(strings.NewReader(string(content)))
|
||||||
|
modified := false
|
||||||
|
skipNext := false
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
if skipNext {
|
||||||
|
skipNext = false
|
||||||
|
modified = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
lowerLine := strings.ToLower(line)
|
||||||
|
if strings.Contains(lowerLine, "# iris autocomplete") || strings.Contains(lowerLine, "# iris autostart") {
|
||||||
|
modified = true
|
||||||
|
skipNext = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.Contains(lowerLine, "iris init") {
|
||||||
|
modified = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
lines = append(lines, line)
|
||||||
|
}
|
||||||
|
|
||||||
|
if scanErr := scanner.Err(); scanErr != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if !modified {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for len(lines) > 0 && strings.TrimSpace(lines[len(lines)-1]) == "" {
|
||||||
|
lines = lines[:len(lines)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
output := strings.Join(lines, "\n")
|
||||||
|
if len(lines) > 0 {
|
||||||
|
output += "\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.WriteFile(filePath, []byte(output), 0644)
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
+9
-5
@@ -1,9 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Iris installer
|
|
||||||
# Usage: curl -sS https://raw.githubusercontent.com/versenilvis/iris/main/scripts/install.sh | sudo sh
|
|
||||||
|
|
||||||
REPO="versenilvis/iris"
|
REPO="versenilvis/iris"
|
||||||
BIN_DIR="${BIN_DIR:-/usr/local/bin}"
|
BIN_DIR="${BIN_DIR:-/usr/local/bin}"
|
||||||
# allow overriding the GitHub API base URL for local testing
|
# allow overriding the GitHub API base URL for local testing
|
||||||
@@ -62,8 +59,15 @@ main() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if "${BIN_DIR}/iris" version >/dev/null 2>&1; then
|
if [ "${has_write_permission}" -eq 1 ]; then
|
||||||
echo "Installation verified."
|
mkdir -p "${BIN_DIR}"
|
||||||
|
cp "$bin" "${BIN_DIR}/iris"
|
||||||
|
chmod +x "${BIN_DIR}/iris"
|
||||||
|
if "${BIN_DIR}/iris" version >/dev/null 2>&1; then
|
||||||
|
echo "Installation verified."
|
||||||
|
else
|
||||||
|
echo "Warning: could not verify installed binary at ${BIN_DIR}/iris"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
chmod +x "$bin"
|
chmod +x "$bin"
|
||||||
if "$bin" version >/dev/null 2>&1; then
|
if "$bin" version >/dev/null 2>&1; then
|
||||||
|
|||||||
+39
-29
@@ -1,43 +1,53 @@
|
|||||||
#!/bin/bash
|
#!/bin/sh
|
||||||
|
|
||||||
echo "Uninstalling Iris..."
|
echo "Uninstalling Iris..."
|
||||||
|
|
||||||
|
if command -v iris >/dev/null 2>&1; then
|
||||||
|
if iris uninstall --help >/dev/null 2>&1; then
|
||||||
|
iris uninstall
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
BIN_LOCATIONS=(
|
for loc in "${HOME}/.local/bin/iris" "/usr/local/bin/iris"; do
|
||||||
"$HOME/.local/bin/iris"
|
if [ -f "${loc}" ]; then
|
||||||
"/usr/local/bin/iris"
|
echo "Removing binary: ${loc}"
|
||||||
)
|
if [ -w "$(dirname "${loc}")" ]; then
|
||||||
|
/bin/rm -f "${loc}" 2>/dev/null || rm -f "${loc}"
|
||||||
for loc in "${BIN_LOCATIONS[@]}"; do
|
|
||||||
if [ -f "$loc" ]; then
|
|
||||||
echo "Removing binary: $loc"
|
|
||||||
if [ -w "$(dirname "$loc")" ]; then
|
|
||||||
rm -f "$loc"
|
|
||||||
else
|
else
|
||||||
sudo rm -f "$loc"
|
sudo /bin/rm -f "${loc}" 2>/dev/null || sudo rm -f "${loc}"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
for file in "${HOME}/.zshrc" "${HOME}/.bashrc" "${HOME}/.config/fish/config.fish"; do
|
||||||
CONFIG_FILES=(
|
if [ -f "${file}" ]; then
|
||||||
"$HOME/.zshrc"
|
echo "Removing integration from ${file}..."
|
||||||
"$HOME/.bashrc"
|
tmp_file=$(mktemp)
|
||||||
"$HOME/.config/fish/config.fish"
|
grep -v -i -E "(# iris autocomplete|# iris autostart|iris init)" "${file}" > "${tmp_file}" 2>/dev/null
|
||||||
)
|
status=$?
|
||||||
|
if [ "${status}" -eq 0 ] || [ "${status}" -eq 1 ]; then
|
||||||
for file in "${CONFIG_FILES[@]}"; do
|
mv "${tmp_file}" "${file}"
|
||||||
if [ -f "$file" ]; then
|
else
|
||||||
echo "Removing integration from $file..."
|
/bin/rm -f "${tmp_file}" 2>/dev/null || rm -f "${tmp_file}"
|
||||||
sed -i '/# Iris Autocomplete/d' "$file"
|
fi
|
||||||
sed -i '/iris init/d' "$file"
|
|
||||||
sed -i '/^$/N;/^\n$/D' "$file"
|
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ -f "iris.log" ]; then
|
/bin/rm -rf "${HOME}/.config/iris" 2>/dev/null || rm -rf "${HOME}/.config/iris"
|
||||||
rm -f "iris.log"
|
/bin/rm -rf "${HOME}/.local/share/iris" 2>/dev/null || rm -rf "${HOME}/.local/share/iris"
|
||||||
fi
|
/bin/rm -rf "${HOME}/.cache/iris" 2>/dev/null || rm -rf "${HOME}/.cache/iris"
|
||||||
|
/bin/rm -f "iris.log" 2>/dev/null || rm -f "iris.log"
|
||||||
|
|
||||||
echo "✓ Iris has been successfully uninstalled"
|
echo "✓ Iris has been successfully uninstalled"
|
||||||
echo "Please restart your terminal or source your config file to clear the environment"
|
if [ -n "${IRIS_PID}" ]; then
|
||||||
|
echo ""
|
||||||
|
echo "⚠️ You are currently inside an active Iris session."
|
||||||
|
echo "Iris runs as the parent process of this terminal - do NOT run 'pkill iris'"
|
||||||
|
echo "as it will immediately close this terminal window."
|
||||||
|
echo ""
|
||||||
|
echo "To fully exit, simply close this terminal window and open a new one."
|
||||||
|
echo "Iris will not start again since the shell config has been cleaned up."
|
||||||
|
else
|
||||||
|
echo "Please close and reopen your terminal to complete the uninstall."
|
||||||
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user