From 98637404d18a06a6b6376e359a083c1bbbf58631 Mon Sep 17 00:00:00 2001 From: Chris Montgomery Date: Wed, 6 Aug 2025 15:41:51 -0400 Subject: [PATCH 1/6] refactor(direnv): rename `find_prj_config` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rename `find_prj_config` to `find_prj_root_with_config_dir`. This function is not trying to find `$PRJ_CONFIG_HOME` as its name might imply. It looks for a directory named “.config” in order to find `$PRJ_ROOT`, the successful result of which is later used as a fallback method to set the initial value of `$PRJ_ROOT` if `find_prj_root_with_git` yields no result (i.e. this is not a Git repository). --- contrib/direnv | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) mode change 100644 => 100755 contrib/direnv diff --git a/contrib/direnv b/contrib/direnv old mode 100644 new mode 100755 index 25b1a65..825babb --- a/contrib/direnv +++ b/contrib/direnv @@ -2,7 +2,7 @@ # Discover PRJ_ROOT if not found via git (i.e. not in a git repository). # Look for the .config folder in the current directory and up -find_prj_config() ( +find_prj_root_with_config_dir() ( local old_pwd while [[ $old_pwd != "$PWD" ]]; do if [[ -d .config && "$HOME" != "$PWD" ]]; then @@ -29,7 +29,7 @@ find_prj_root_with_git() ( # PRJ_ROOT _prj_root="$(find_prj_root_with_git)" - : "${PRJ_ROOT:=${_prj_root:=$(find_prj_config)}}" + : "${PRJ_ROOT:=${_prj_root:=$(find_prj_root_with_config_dir)}}" # PRJ_CONFIG_HOME - always local to the project : "${PRJ_CONFIG_HOME:=${PRJ_ROOT}/.config}" @@ -74,7 +74,7 @@ find_prj_root_with_git() ( mkdir -p "${PRJ_PATH}" } -unset -f find_prj_config +unset -f find_prj_root_with_config_dir PATH_add "${PRJ_PATH}" export PRJ_ROOT From 25d2a8a83c5a727a810b0c6b7b9d57622e6050e2 Mon Sep 17 00:00:00 2001 From: Chris Montgomery Date: Wed, 6 Aug 2025 15:32:54 -0400 Subject: [PATCH 2/6] fix(direnv): unset `find_prj_root_with_git` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The custom `find_prj_root_with_config_dir()` function is unset towards the end of the script. However, the other custom function `find_prj_root_with_git()` is not unset. I assume this is because the latter was added a couple months after the former, and that the author understandably forgot to unset the newly-added function. I’m not entirely sure about the utility of unsetting either of these functions, but I suppose it does keep the resulting environment cleaner. --- contrib/direnv | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/direnv b/contrib/direnv index 825babb..ebf27e0 100755 --- a/contrib/direnv +++ b/contrib/direnv @@ -75,6 +75,7 @@ find_prj_root_with_git() ( } unset -f find_prj_root_with_config_dir +unset -f find_prj_root_with_git PATH_add "${PRJ_PATH}" export PRJ_ROOT From 10d03030c46cc576e6baa8f04519d61948d2523f Mon Sep 17 00:00:00 2001 From: Chris Montgomery Date: Wed, 6 Aug 2025 15:53:30 -0400 Subject: [PATCH 3/6] refactor(direnv): prefix private functions --- contrib/direnv | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/contrib/direnv b/contrib/direnv index ebf27e0..f7e1f65 100755 --- a/contrib/direnv +++ b/contrib/direnv @@ -2,7 +2,7 @@ # Discover PRJ_ROOT if not found via git (i.e. not in a git repository). # Look for the .config folder in the current directory and up -find_prj_root_with_config_dir() ( +__find_prj_root_with_config_dir() ( local old_pwd while [[ $old_pwd != "$PWD" ]]; do if [[ -d .config && "$HOME" != "$PWD" ]]; then @@ -18,7 +18,7 @@ find_prj_root_with_config_dir() ( ) # Discover PRJ_ROOT if in a git repository. -find_prj_root_with_git() ( +__find_prj_root_with_git() ( git rev-parse --show-toplevel 2>/dev/null ) @@ -28,8 +28,8 @@ find_prj_root_with_git() ( : "${XDG_DATA_HOME:=${HOME}/.local/share}" # PRJ_ROOT - _prj_root="$(find_prj_root_with_git)" - : "${PRJ_ROOT:=${_prj_root:=$(find_prj_root_with_config_dir)}}" + _prj_root="$(__find_prj_root_with_git)" + : "${PRJ_ROOT:=${_prj_root:=$(__find_prj_root_with_config_dir)}}" # PRJ_CONFIG_HOME - always local to the project : "${PRJ_CONFIG_HOME:=${PRJ_ROOT}/.config}" @@ -74,8 +74,8 @@ find_prj_root_with_git() ( mkdir -p "${PRJ_PATH}" } -unset -f find_prj_root_with_config_dir -unset -f find_prj_root_with_git +unset -f __find_prj_root_with_config_dir +unset -f __find_prj_root_with_git PATH_add "${PRJ_PATH}" export PRJ_ROOT From 8235e182b90c07a940b28cc58f03e4f586eb5d42 Mon Sep 17 00:00:00 2001 From: Chris Montgomery Date: Wed, 6 Aug 2025 15:16:41 -0400 Subject: [PATCH 4/6] feat(shell): add a generalized shell hook based on direnv hook --- contrib/direnv | 85 +---------------------------------------- contrib/shell-hook.sh | 88 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 84 deletions(-) create mode 100755 contrib/shell-hook.sh diff --git a/contrib/direnv b/contrib/direnv index f7e1f65..2373116 100755 --- a/contrib/direnv +++ b/contrib/direnv @@ -1,90 +1,7 @@ #!/usr/bin/env bash -# Discover PRJ_ROOT if not found via git (i.e. not in a git repository). -# Look for the .config folder in the current directory and up -__find_prj_root_with_config_dir() ( - local old_pwd - while [[ $old_pwd != "$PWD" ]]; do - if [[ -d .config && "$HOME" != "$PWD" ]]; then - echo "$PWD" - return 0 - fi - old_pwd=$PWD - cd .. - done - # We're at the top and didn't find anything - log_error "ERROR: could not find project root" >&2 - return 1 -) +source ./shell-hook.sh -# Discover PRJ_ROOT if in a git repository. -__find_prj_root_with_git() ( - git rev-parse --show-toplevel 2>/dev/null -) - -{ - : "${XDG_CONFIG_HOME:=${HOME}/.config}" - : "${XDG_CACHE_HOME:=${HOME}/.cache}" - : "${XDG_DATA_HOME:=${HOME}/.local/share}" - - # PRJ_ROOT - _prj_root="$(__find_prj_root_with_git)" - : "${PRJ_ROOT:=${_prj_root:=$(__find_prj_root_with_config_dir)}}" - - # PRJ_CONFIG_HOME - always local to the project - : "${PRJ_CONFIG_HOME:=${PRJ_ROOT}/.config}" - mkdir -p "${PRJ_CONFIG_HOME}" - - if [[ -z "${PRJ_ID:-}" && -f "${PRJ_CONFIG_HOME}/prj_id" ]]; then - PRJ_ID=$(<"${PRJ_CONFIG_HOME}/prj_id") - fi - - # PRJ_RUNTIME_DIR - always local to the project - : "${PRJ_RUNTIME_DIR:=${PRJ_ROOT}/.run}" - mkdir -p "${PRJ_RUNTIME_DIR}" - - # PRJ_CACHE_HOME - shared if PRJ_ID is set - if [[ -z "${PRJ_CACHE_HOME:-}" ]]; then - if [[ -n "${PRJ_ID:-}" ]]; then - PRJ_CACHE_HOME="${XDG_CACHE_HOME}/prj/${PRJ_ID}" - else - PRJ_CACHE_HOME="${PRJ_ROOT}/.cache" - fi - fi - mkdir -p "${PRJ_CACHE_HOME}" - - # PRJ_DATA_HOME - shared if PRJ_ID is set - if [[ -z "${PRJ_DATA_HOME:-}" ]]; then - if [[ -n "${PRJ_ID:-}" ]]; then - PRJ_DATA_HOME="${XDG_DATA_HOME}/prj/${PRJ_ID}" - else - PRJ_DATA_HOME="${PRJ_ROOT}/.data" - fi - fi - mkdir -p "${PRJ_DATA_HOME}" - - # PRJ_PATH - shared if PRJ_ID is set - if [[ -z "${PRJ_PATH:-}" ]]; then - if [[ -n "${PRJ_ID:-}" ]]; then - PRJ_PATH="${HOME}/.local/bin/prj/${PRJ_ID}" - else - PRJ_PATH="${PRJ_ROOT}/.bin" - fi - fi - mkdir -p "${PRJ_PATH}" -} - -unset -f __find_prj_root_with_config_dir -unset -f __find_prj_root_with_git - -PATH_add "${PRJ_PATH}" -export PRJ_ROOT -export PRJ_ID -export PRJ_PATH -export PRJ_CONFIG_HOME -export PRJ_CACHE_HOME -export PRJ_DATA_HOME -export PRJ_RUNTIME_DIR [ -z ${DIRENV_PRJ_SILENCE+x} ] && log_status "PRJ_ROOT: ${PRJ_ROOT}" [ -z ${DIRENV_PRJ_SILENCE+x} ] && log_status "PRJ_ID: ${PRJ_ID-none}" [ -z ${DIRENV_PRJ_SILENCE+x} ] && log_status "PRJ_CONFIG_HOME: ${PRJ_CONFIG_HOME#"${PRJ_ROOT}"/}" diff --git a/contrib/shell-hook.sh b/contrib/shell-hook.sh new file mode 100755 index 0000000..779a3b5 --- /dev/null +++ b/contrib/shell-hook.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash + +# Discover PRJ_ROOT if not found via git (i.e. not in a git repository). +# Look for the .config folder in the current directory and up +__find_prj_root_with_config_dir() ( + local old_pwd + while [[ $old_pwd != "$PWD" ]]; do + if [[ -d .config && "$HOME" != "$PWD" ]]; then + echo "$PWD" + return 0 + fi + old_pwd=$PWD + cd .. + done + # We're at the top and didn't find anything + log_error "ERROR: could not find project root" >&2 + return 1 +) + +# Discover PRJ_ROOT if in a git repository. +__find_prj_root_with_git() ( + git rev-parse --show-toplevel 2>/dev/null +) + +{ + : "${XDG_CONFIG_HOME:=${HOME}/.config}" + : "${XDG_CACHE_HOME:=${HOME}/.cache}" + : "${XDG_DATA_HOME:=${HOME}/.local/share}" + + # PRJ_ROOT + _prj_root="$(__find_prj_root_with_git)" + : "${PRJ_ROOT:=${_prj_root:=$(__find_prj_root_with_config_dir)}}" + + # PRJ_CONFIG_HOME - always local to the project + : "${PRJ_CONFIG_HOME:=${PRJ_ROOT}/.config}" + mkdir -p "${PRJ_CONFIG_HOME}" + + if [[ -z "${PRJ_ID:-}" && -f "${PRJ_CONFIG_HOME}/prj_id" ]]; then + PRJ_ID=$(<"${PRJ_CONFIG_HOME}/prj_id") + fi + + # PRJ_RUNTIME_DIR - always local to the project + : "${PRJ_RUNTIME_DIR:=${PRJ_ROOT}/.run}" + mkdir -p "${PRJ_RUNTIME_DIR}" + + # PRJ_CACHE_HOME - shared if PRJ_ID is set + if [[ -z "${PRJ_CACHE_HOME:-}" ]]; then + if [[ -n "${PRJ_ID:-}" ]]; then + PRJ_CACHE_HOME="${XDG_CACHE_HOME}/prj/${PRJ_ID}" + else + PRJ_CACHE_HOME="${PRJ_ROOT}/.cache" + fi + fi + mkdir -p "${PRJ_CACHE_HOME}" + + # PRJ_DATA_HOME - shared if PRJ_ID is set + if [[ -z "${PRJ_DATA_HOME:-}" ]]; then + if [[ -n "${PRJ_ID:-}" ]]; then + PRJ_DATA_HOME="${XDG_DATA_HOME}/prj/${PRJ_ID}" + else + PRJ_DATA_HOME="${PRJ_ROOT}/.data" + fi + fi + mkdir -p "${PRJ_DATA_HOME}" + + # PRJ_PATH - shared if PRJ_ID is set + if [[ -z "${PRJ_PATH:-}" ]]; then + if [[ -n "${PRJ_ID:-}" ]]; then + PRJ_PATH="${HOME}/.local/bin/prj/${PRJ_ID}" + else + PRJ_PATH="${PRJ_ROOT}/.bin" + fi + fi + mkdir -p "${PRJ_PATH}" +} + +unset -f __find_prj_root_with_config_dir +unset -f __find_prj_root_with_git + +export PATH="${PRJ_PATH}:${PATH}" + +export PRJ_ROOT +export PRJ_ID +export PRJ_PATH +export PRJ_CONFIG_HOME +export PRJ_CACHE_HOME +export PRJ_DATA_HOME +export PRJ_RUNTIME_DIR From 0c53ebd83a18f76147edb550c3cd883338f62e64 Mon Sep 17 00:00:00 2001 From: Chris Montgomery Date: Fri, 29 Aug 2025 14:38:00 -0400 Subject: [PATCH 5/6] refactor(direnv): rename file to `direnv-hook.sh` --- contrib/{direnv => direnv-hook.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename contrib/{direnv => direnv-hook.sh} (100%) diff --git a/contrib/direnv b/contrib/direnv-hook.sh similarity index 100% rename from contrib/direnv rename to contrib/direnv-hook.sh From 4727ff5b89020912ead606c9ebbbe3e94d4a9f50 Mon Sep 17 00:00:00 2001 From: Chris Montgomery Date: Fri, 29 Aug 2025 14:40:52 -0400 Subject: [PATCH 6/6] fix: make contrib hooks non-executable They are intended to be sourced in the appropriate context, not executed directly. --- contrib/direnv-hook.sh | 0 contrib/shell-hook.sh | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 contrib/direnv-hook.sh mode change 100755 => 100644 contrib/shell-hook.sh diff --git a/contrib/direnv-hook.sh b/contrib/direnv-hook.sh old mode 100755 new mode 100644 diff --git a/contrib/shell-hook.sh b/contrib/shell-hook.sh old mode 100755 new mode 100644