diff --git a/README.md b/README.md index e7d83e9..0791996 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,12 @@ contributoor update # Update to latest version contributoor logs # Show logs ``` +If you chose to install contributoor under a custom directory, you will need to specify the directory when running the commands, for example: + +```bash +contributoor --config-path /path/to/contributoor start +``` + ## 🔨 Development
diff --git a/install.bats b/install.bats index bf6ef6f..76bc7ea 100644 --- a/install.bats +++ b/install.bats @@ -1026,7 +1026,11 @@ EOF *) return 0 ;; esac } - export -f detect_platform sudo docker + function contributoor() { + echo "Config Path : $TEST_DIR/.contributoor/config.yaml" + return 0 + } + export -f detect_platform sudo docker contributoor export HOME="$TEST_DIR" # Test 'no' response @@ -1064,9 +1068,14 @@ EOF case "$2" in "systemctl") return 0 ;; "docker") return 0 ;; + "contributoor") return 0 ;; *) command "$@" ;; esac } + contributoor() { + echo "Config Path : $TEST_DIR/.contributoor/config.yaml" + return 0 + } sudo() { case "$1" in "systemctl") @@ -1098,7 +1107,7 @@ EOF *) return 0 ;; esac } - export -f detect_platform command sudo docker + export -f detect_platform command sudo docker contributoor printf "y\n" | uninstall ' @@ -1134,6 +1143,16 @@ EOF # Setup mock functions detect_platform() { echo "darwin"; } + command() { + case "$2" in + "contributoor") return 0 ;; + *) return 1 ;; + esac + } + contributoor() { + echo "Config Path : $TEST_DIR/.contributoor/config.yaml" + return 0 + } sudo() { case "$1" in "launchctl") @@ -1153,7 +1172,7 @@ EOF ;; esac } - export -f detect_platform sudo + export -f detect_platform command sudo contributoor printf "y\n" | uninstall ' @@ -1165,32 +1184,95 @@ EOF } @test "uninstall handles missing components gracefully" { - # Create minimal test environment. - mkdir -p "$TEST_DIR" + # Create minimal test environment with config path + mkdir -p "$TEST_DIR/.contributoor" + touch "$TEST_DIR/.contributoor/config.yaml" - # Setup mock functions. + # Setup mock functions function detect_platform() { echo "linux"; } function command() { case "$2" in "systemctl") return 1 ;; # systemd not available "docker") return 1 ;; # docker not available + "contributoor") return 0 ;; *) command "$@" ;; esac } + function contributoor() { + echo "Config Path : $TEST_DIR/.contributoor/config.yaml" + return 0 + } function sudo() { "${@:2}" return 0 } - export -f detect_platform command sudo + export -f detect_platform command sudo contributoor export HOME="$TEST_DIR" - # Run uninstall with 'yes' response. + # Run uninstall with 'yes' response run bash -c ' source ./install.sh printf "y\n" | uninstall ' - # Should complete successfully even with nothing to clean. + # Should complete successfully even with nothing to clean [ "$status" -eq 0 ] echo "$output" | grep -q "Contributoor has been uninstalled successfully" +} + +@test "installation path expands tilde correctly" { + # Setup test environment + export HOME="$TEST_DIR" + CUSTOM_PATH="~/custom/contributoor" + EXPECTED_PATH="$TEST_DIR/custom/contributoor" + + run bash -c " + source ./install.sh + CUSTOM_PATH='$CUSTOM_PATH' + # Expand ~ to \$HOME in a portable way + CUSTOM_PATH=\$(echo \"\$CUSTOM_PATH\" | sed \"s|^~|\$HOME|\") + echo \$CUSTOM_PATH + " + + [ "$status" -eq 0 ] + [ "$output" = "$EXPECTED_PATH" ] +} + +@test "uninstall handles tilde expansion in config path" { + # Create test environment with config in custom path + CUSTOM_DIR="$TEST_DIR/custom/contributoor" + mkdir -p "$CUSTOM_DIR" + touch "$CUSTOM_DIR/config.yaml" + export HOME="$TEST_DIR" + + # Run uninstall with config path using tilde + run bash -c ' + source ./install.sh + CONFIG_PATH="~/custom/contributoor/config.yaml" + detect_platform() { echo "linux"; } + command() { return 1; } + export -f detect_platform command + printf "y\n" | CONFIG_PATH="$CONFIG_PATH" uninstall + ' + + # Should expand ~ and find the config + [ "$status" -eq 0 ] + echo "$output" | grep -q "custom/contributoor" + [ ! -d "$CUSTOM_DIR" ] +} + +@test "uninstall fails with non-existent config path after tilde expansion" { + export HOME="$TEST_DIR" + + run bash -c ' + source ./install.sh + CONFIG_PATH="~/nonexistent/config.yaml" + detect_platform() { echo "linux"; } + command() { return 1; } + export -f detect_platform command + printf "y\n" | CONFIG_PATH="$CONFIG_PATH" uninstall + ' + + [ "$status" -eq 1 ] + echo "$output" | grep -q "Config file not found at: $TEST_DIR/nonexistent/config.yaml" } \ No newline at end of file diff --git a/install.sh b/install.sh index 19dbce6..bad4712 100755 --- a/install.sh +++ b/install.sh @@ -89,10 +89,11 @@ warn() { } usage() { - echo "Usage: $0 [-p path] [-v version] [-u]" + echo "Usage: $0 [-p path] [-v version] [-u] [-c config_path]" echo " -p: Path to install contributoor (default: $HOME/.contributoor)" echo " -v: Version of contributoor to install without 'v' prefix (default: latest, example: 0.0.6)" echo " -u: Uninstall Contributoor" + echo " -c: Path to config.yaml (only used with -u for uninstall)" exit 1 } @@ -599,11 +600,37 @@ EOF } uninstall() { + # Try to determine the installation directory + local install_dir="" + + # If config path was provided via -c, use it + if [ -n "${CONFIG_PATH:-}" ]; then + # Expand ~ to $HOME in a portable way + CONFIG_PATH=$(echo "$CONFIG_PATH" | sed "s|^~|$HOME|") + if [ ! -f "$CONFIG_PATH" ]; then + fail "Config file not found at: $CONFIG_PATH" + fi + install_dir=$(dirname "$CONFIG_PATH") + else + # Try using contributoor status + if command -v contributoor >/dev/null 2>&1; then + local config_path=$(contributoor status 2>/dev/null | grep "Config Path" | cut -d':' -f2 | tr -d ' ') + if [ -n "$config_path" ]; then + install_dir=$(dirname "$config_path") + fi + fi + + # If we couldn't determine the install directory, ask user to specify. + if [ -z "$install_dir" ]; then + fail "Could not determine installation directory.\nIt's likely you installed contributoor under a custom directory.\n\nPlease specify the directory when running the uninstaller:\n./install.sh -u -c /path/to/custom/config.yaml" + fi + fi + printf "\n${COLOR_RED}Warning, this will:${COLOR_RESET}\n" printf " • Stop and remove any contributoor services (systemd/launchd)\n" printf " • Stop and remove any contributoor Docker containers and images\n" printf " • Remove contributoor from your PATH\n" - printf " • Delete all contributoor data from ${HOME}/.contributoor\n\n" + printf " • Delete all contributoor data from ${install_dir}\n\n" printf "Are you sure you want to uninstall? [y/N]: " read -r confirm case "$(echo "$confirm" | tr '[:upper:]' '[:lower:]')" in @@ -663,19 +690,20 @@ uninstall() { fi # Remove PATH entry from shell config + local bin_path="$install_dir/bin" for rc in "$HOME/.bashrc" "$HOME/.zshrc" "$HOME/.bash_profile" "$HOME/.profile"; do if [ -f "$rc" ]; then temp_file=$(mktemp) - grep -v "export PATH=.*contributoor.*bin" "$rc" > "$temp_file" + grep -v "export PATH=.*$bin_path" "$rc" > "$temp_file" mv "$temp_file" "$rc" success "Cleaned PATH from $rc" fi done - # Remove contributoor directory - if [ -d "$HOME/.contributoor" ]; then - rm -rf "$HOME/.contributoor" - success "Removed contributoor directory" + # Remove contributoor directory using detected path + if [ -d "$install_dir" ]; then + rm -rf "$install_dir" + success "Removed contributoor directory: $install_dir" fi printf "\n\n${COLOR_GREEN}Contributoor has been uninstalled successfully${COLOR_RESET}\n\n" @@ -684,16 +712,24 @@ uninstall() { main() { # Parse arguments - while getopts "p:v:hu" FLAG; do + SHOULD_UNINSTALL=false + while getopts "p:v:c:hu" FLAG; do case "$FLAG" in p) CONTRIBUTOOR_PATH="$OPTARG" ;; v) CONTRIBUTOOR_VERSION="$OPTARG" ;; - u) uninstall ;; + c) CONFIG_PATH="$OPTARG" ;; + u) SHOULD_UNINSTALL=true ;; h) usage ;; *) usage ;; esac done + # Handle uninstall if requested + if [ "$SHOULD_UNINSTALL" = true ]; then + uninstall + exit 0 + fi + # Setup environment CONTRIBUTOOR_BIN="$CONTRIBUTOOR_PATH/bin" ARCH=$(detect_architecture) @@ -726,6 +762,8 @@ main() { read -r CUSTOM_PATH fi if [ -n "$CUSTOM_PATH" ]; then + # Expand ~ to $HOME in a portable way + CUSTOM_PATH=$(echo "$CUSTOM_PATH" | sed "s|^~|$HOME|") CONTRIBUTOOR_PATH="$CUSTOM_PATH" CONTRIBUTOOR_BIN="$CONTRIBUTOOR_PATH/bin" fi