diff --git a/scripts/install.sh b/scripts/install.sh index afecfb16bb0..6a69398bbc4 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -131,15 +131,15 @@ checkConflictingInstallation() { fi } -# Install the binary and ask for elevated permissions if needed +# Install the binary, using sudo if the directory is not directly writable installBinary() { - if [ "$INSTALL_DIR" = "/usr/local/bin" ]; then + if { [ -d "$INSTALL_DIR" ] && [ -w "$INSTALL_DIR" ]; } || { [ ! -d "$INSTALL_DIR" ] && [ -w "$(dirname "$INSTALL_DIR")" ]; }; then + install -d "$INSTALL_DIR" + install rill "$INSTALL_DIR" + else printf "\nElevated permissions required to install the Rill binary to: %s/rill\n" "$INSTALL_DIR" sudo install -d "$INSTALL_DIR" sudo install rill "$INSTALL_DIR" - else - install -d "$INSTALL_DIR" - install rill "$INSTALL_DIR" fi cd - > /dev/null } @@ -225,13 +225,18 @@ removePathConfigEntries() { done } -# Check if the install directory (or its parent, if it doesn't exist yet) is writable +# Check if we can install to INSTALL_DIR installDirIsWritable() { - if [ -d "$INSTALL_DIR" ]; then - [ -w "$INSTALL_DIR" ] - else - [ -w "$(dirname "$INSTALL_DIR")" ] + # Check if it is directly writable + if [ -d "$INSTALL_DIR" ] && [ -w "$INSTALL_DIR" ]; then + return 0 + # If it doesn't exist yet, check if the parent directory is writable + elif [ ! -d "$INSTALL_DIR" ] && [ -w "$(dirname "$INSTALL_DIR")" ]; then + return 0 fi + + # Lastly, we also consider it writable if we have passwordless sudo (since then we don't need to prompt/error due to lack of permissions) + sudo -n true 2>/dev/null } # Resolve the install directory @@ -248,18 +253,20 @@ resolveInstallDir() { # Handle non-interactive scenarios where prompt or sudo are not possible if [ "$NON_INTERACTIVE" = "true" ]; then - # If the install directory was explicitly set and requires sudo, we error - if [ -n "$INSTALL_DIR" ] && [ "$INSTALL_DIR_EXPLICIT" = "true" ] && ! installDirIsWritable; then - printf "Install directory '%s' requires elevated permissions, which are not available in non-interactive mode.\n" "$INSTALL_DIR" - exit 1 + # Default to /usr/local/bin if not set. + if [ -z "$INSTALL_DIR" ]; then + INSTALL_DIR="/usr/local/bin" fi - # If the install directory is not set, or the previous installation path requires sudo, we default to installing in the current directory - if [ -z "$INSTALL_DIR" ]; then - printf "Non-interactive shell detected; defaulting to install in current directory.\n" - INSTALL_DIR=$(pwd) - elif ! installDirIsWritable; then - printf "Non-interactive shell detected; previous installation at '%s' requires elevated permissions; defaulting to install in current directory.\n" "$INSTALL_DIR" + # Handle if the install directory is not writable and we can't prompt due to non-interactive mode. + if ! installDirIsWritable; then + # Error if the install directory was set explicitly. + if [ "$INSTALL_DIR_EXPLICIT" = "true" ]; then + printf "Install directory '%s' requires elevated permissions, which are not available in non-interactive mode.\n" "$INSTALL_DIR" + exit 1 + fi + + # Fall back to the current directory otherwise (which we assume is writable). INSTALL_DIR=$(pwd) fi