Skip to content

Instantly share code, notes, and snippets.

@trevorrjohn
Last active August 14, 2024 21:54
Show Gist options
  • Save trevorrjohn/406f2129dce79fdc6fbfccbbe0723c89 to your computer and use it in GitHub Desktop.
Save trevorrjohn/406f2129dce79fdc6fbfccbbe0723c89 to your computer and use it in GitHub Desktop.
The goal of these function are to automatically add and remove your Rails ./bin/ directory to your and remove it when it doesn't exist. I am sure there are edge cases I missed or maybe there is a better way to do this. :shurg:
# NOTE:
# Make sure you add this function to your zshrc file or link to the file.
# it could look like this line in your `~/.zshrc`
# . PATH_TO_FILE/add_to_path.sh
#!/bin/sh
# Function to add a directory to PATH
#
# Usage:
# add_to_path "/path/to/add"
#
# Arguments:
# $1 - The directory path to add to PATH
#
# Description:
# Adds the specified directory to the beginning of PATH if it's not already present.
#
# Edge cases handled:
# - Checks if the directory exists and is readable
# - Avoids adding duplicate entries
# - Handles directories with spaces in the name
# - Maintains : at the start/end of PATH if originally present
add_to_path() {
if [ -z "$1" ]; then
echo "Usage: add_to_path <directory>" >&2
return 1
fi
if [ ! -d "$1" ]; then
echo "Error: '$1' is not a directory" >&2
return 1
fi
if [ ! -r "$1" ]; then
echo "Error: '$1' is not readable" >&2
return 1
fi
case ":$PATH:" in
*":$1:"*) :;; # Already in PATH
*)
if [ "${PATH#:}" != "$PATH" ]; then
PATH=":$1$PATH" # Maintain leading :
elif [ "${PATH%:}" != "$PATH" ]; then
PATH="$1:$PATH:" # Maintain trailing :
else
PATH="$1:$PATH"
fi
;;
esac
}
# NOTE:
# Make sure you add this function to your zshrc file or link to the file.
# it could look like this line in your `~/.zshrc`
# . PATH_TO_FILE/rails-cd.sh
#!/bin/sh
# Function to override the cd command
#
# Usage:
# cd [directory]
#
# Arguments:
# [directory] - The directory to change to. If omitted, changes to the home directory.
#
# Description:
# This function overrides the built-in cd command. It changes the current
# directory and manages the PATH based on the presence of a ./bin/rails file.
#
# Edge cases handled:
# - Fails gracefully if the target directory doesn't exist
# - Checks if the old directory still exists before modifying PATH
# - Verifies both existence and readability of bin/rails files
# - Works with relative and absolute paths
# - Handles 'cd' with no arguments (change to home directory)
# - Handles spaces in directory names
cd() {
old_dir="$PWD"
# Check if another cd function is defined
if (( $+functions[cd_func] )); then
cd_func "$@"
else
# Use builtin cd for zsh, fallback to command cd for other shells
if [ -n "$ZSH_VERSION" ]; then
builtin cd "$@"
else
command cd "$@"
fi
fi
if [ $? -ne 0 ]; then
echo "cd: no such file or directory: $*" >&2
return 1
fi
if [ "$PWD" != "$old_dir" ]; then
# Check if old directory still exists and had bin/rails
if [ -d "$old_dir" ] && [ -f "$old_dir/bin/rails" ]; then
remove_from_path "$old_dir/bin"
echo "Removed $old_dir/bin from PATH"
fi
# Check if new directory has bin/rails
if [ -f "./bin/rails" ] && [ -r "./bin/rails" ]; then
add_to_path "$PWD/bin"
echo "Added $PWD/bin to PATH"
fi
fi
}
# NOTE:
# Make sure you add this function to your zshrc file or link to the file.
# it could look like this line in your `~/.zshrc`
# . PATH_TO_FILE/remove_from_path.sh
#!/bin/sh
# Function to remove a directory from PATH
#
# Usage:
# remove_from_path "/path/to/remove"
#
# Arguments:
# $1 - The directory path to remove from PATH
#
# Description:
# Removes all occurrences of the specified directory from PATH.
#
# Edge cases handled:
# - Handles directories with spaces in the name
# - Maintains : at the start/end of PATH if originally present
# - Handles cases where the directory appears multiple times in PATH
# - Avoids creating empty entries or consecutive colons
remove_from_path() {
if [ -z "$1" ]; then
echo "Usage: remove_from_path <directory>" >&2
return 1
fi
# Store the original first and last characters of PATH
first_char="${PATH%"${PATH#?}"}"
last_char="${PATH#"${PATH%?}"}"
# Remove all occurrences of the directory, handle spaces in path names
new_path=$(echo "$PATH" | sed -e "s#^$1:##" -e "s#:$1:##g" -e "s#:$1\$##")
# If PATH was changed, remove any resulting empty entries and duplicate colons
if [ "$new_path" != "$PATH" ]; then
new_path=$(echo "$new_path" | sed -e 's#^:##' -e 's#:$##' -e 's#::+#:#g')
# Restore leading/trailing colon if they were present originally
[ "$first_char" = ":" ] && new_path=":$new_path"
[ "$last_char" = ":" ] && new_path="$new_path:"
PATH="$new_path"
fi
}
@trevorrjohn
Copy link
Author

Update for POISX and fixed some edge cases.

@trevorrjohn
Copy link
Author

handle when a cd function already exists

@trevorrjohn
Copy link
Author

Split it up into a few files to make it easier to understand.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment