Compare commits

...

No commits in common. "v0.1.0" and "main" have entirely different histories.
v0.1.0 ... main

2 changed files with 131 additions and 36 deletions

View file

@ -1,18 +1,24 @@
# Rensu Direnv Integration # Rensa Direnv Integration
## Usage ## Usage
```console 1. Use latest release/tag: [![Latest Release](https://gitlab.com/rensa-nix/direnv/-/badges/release.svg)](https://gitlab.com/rensa-nix/direnv/-/releases)
direnv fetchurl https://gitlab.com/rensa-nix/direnv/-/raw/main/direnvrc 1. Get hash for release:
``` ```bash
direnv fetchurl https://gitlab.com/rensa-nix/direnv/-/raw/<version>/direnvrc
```
1. Add this to your `.envrc`:
```bash
# configure rensa here if needed, like:
# REN_DO_WATCH=false
# etc.
source $(fetchurl https://gitlab.com/rensa-nix/direnv/-/raw/<version>/direnvrc <hash>)
use ren //repo/shells/default
```
`.envrc`: ## Configuration
```bash See [direnvrc](./direnvrc) at the top.
source $(fetchurl https://gitlab.com/rensa-nix/direnv/-/raw/main/direnvrc <hash>)
use envreload //repo/shells/default
```
## Formatting & Linting ## Formatting & Linting

141
direnvrc
View file

@ -14,6 +14,19 @@ readonly RENSA_DIRENV_VERSION="0.1.0"
readonly DIRENV_MIN_VERSION="2.21.3" readonly DIRENV_MIN_VERSION="2.21.3"
readonly BASH_MIN_VERSION="4.4" readonly BASH_MIN_VERSION="4.4"
#
# CONFIGURATION ENV VARS
#
REN_FLAKE_ATTR=${REN_FLAKE_ATTR-"__ren"}
# whether to enable watching the files for changes
REN_DO_WATCH=${REN_DO_WATCH-true}
# whether to add the shell profile or flake inputs to gcroots
REN_DO_GCROOTS=${REN_DO_GCROOTS-true}
# whether to archive the flake inputs and gcroot them (only works if REN_DO_GCROOT is true)
REN_DO_ARCHIVE=${REN_DO_ARCHIVE-true}
# whether to enable compat mode which sets PRJ env variables
REN_DO_PRJ_COMPAT=${REN_DO_PRJ_COMAT-true}
# #
# LOGGING # LOGGING
# #
@ -76,9 +89,9 @@ __ren_get_cell_path() {
if [[ -z "$__cell_path_cache" ]]; then if [[ -z "$__cell_path_cache" ]]; then
local cell="$1" local cell="$1"
local cellsFrom local cellsFrom
cellsFrom=$(__ren_nix eval --raw ".#__std.cellsFrom" 2>/dev/null || true) cellsFrom=$(__ren_nix eval --raw ".#${REN_FLAKE_ATTR}.cellsFrom" 2>/dev/null || true)
if [[ -z "$cellsFrom" ]]; then if [[ -z "$cellsFrom" ]]; then
__ren_log TRACE "Could not determine 'cellsFrom' path from flake." __ren_log ERROR "Could not determine 'cellsFrom' path from flake."
return 1 return 1
fi fi
__cell_path_cache=$cellsFrom __cell_path_cache=$cellsFrom
@ -108,12 +121,73 @@ __ren_init_project() {
export REN_ROOT="$git_repo" export REN_ROOT="$git_repo"
export REN_STATE="${REN_ROOT}/.ren" export REN_STATE="${REN_ROOT}/.ren"
mkdir -p "${REN_STATE}/direnv" mkdir -p "${REN_STATE}"
# shellcheck disable=SC2034 # shellcheck disable=SC2034
direnv_layout_dir="${REN_STATE}/direnv" direnv_layout_dir="${REN_STATE}/direnv"
mkdir -p "${REN_STATE}/direnv"
# add nested gitignore which ignores the whole state dir # add nested gitignore which ignores the whole state dir
echo "**/*" >"$REN_STATE/.gitignore" echo "**/*" >"$REN_STATE/.gitignore"
if [ "$REN_DO_PRJ_COMPAT" = true ]; then
__ren_log INFO "Setting PRJ env variables for compat"
__ren_init_prj_spec
else
__ren_log TRACE "Not setting PRJ env variables"
fi
}
# compat with other stuff that uses PRJ_...
# we explicitly don't want any dirs to be in the project dir, put them all
# in .ren, so they don't clutter everything up
__ren_init_prj_spec() {
export PRJ_ROOT=${PRJ_ROOT:="${REN_ROOT}"}
export PRJ_CONFIG_HOME=${PRJ_CONFIG_HOME:="${REN_STATE}/config"}
mkdir -p "${PRJ_CONFIG_HOME}"
export PRJ_RUNTIME_DIR=${PRJ_RUNTIME_DIR:="${REN_STATE}/runtime"}
mkdir -p "${PRJ_RUNTIME_DIR}"
# load project id if exists
if [[ -z "${PRJ_ID:-}" && -f "${PRJ_CONFIG_HOME}/prj_id" ]]; then
export PRJ_ID=$(<"${PRJ_CONFIG_HOME}/prj_id")
fi
# PRJ_CACHE_HOME - shared if PRJ_ID is set
if [[ -z "${PRJ_CACHE_HOME:-}" ]]; then
if [[ -n "${PRJ_ID:-}" ]]; then
export PRJ_CACHE_HOME="${XDG_CACHE_HOME}/prj/${PRJ_ID}"
else
export PRJ_CACHE_HOME="${REN_STATE}/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
export PRJ_DATA_HOME="${XDG_DATA_HOME}/prj/${PRJ_ID}"
else
export PRJ_DATA_HOME="${REN_STATE}/data"
fi
fi
# NOTE: stuff like devshell uses PRJ_DATA_DIR instead, even though numtide
# wrote the spec? :D
# technically not supported so we just overwrite it, use PRJ_DATA_HOME instead
export PRJ_DATA_DIR=$PRJ_DATA_HOME
mkdir -p "${PRJ_DATA_HOME}"
# PRJ_PATH - shared if PRJ_ID is set
if [[ -z "${PRJ_PATH:-}" ]]; then
if [[ -n "${PRJ_ID:-}" ]]; then
export PRJ_PATH="${HOME}/.local/bin/prj/${PRJ_ID}"
else
export PRJ_PATH="${REN_STATE}/bin"
fi
fi
mkdir -p "${PRJ_PATH}"
} }
# #
@ -208,16 +282,18 @@ __ren_update_gcroots() {
local __layout_dir="$1" tmp_profile="$2" profile="$3" cell="$4" local __layout_dir="$1" tmp_profile="$2" profile="$3" cell="$4"
__ren_add_gcroot "$tmp_profile" "$profile" __ren_add_gcroot "$tmp_profile" "$profile"
rm -f "$tmp_profile"* rm -f "$tmp_profile"*
# add gcroots for the main flake if [ "$REN_DO_ARCHIVE" = true ]; then
__ren_add_flake_input_gcroots "$REN_ROOT" "$__layout_dir" # add gcroots for the main flake
__ren_add_flake_input_gcroots "$REN_ROOT" "$__layout_dir"
# if a cell is specified, also gcroot it's flake inputs, if it has a flake # if a cell is specified, also gcroot it's flake inputs, if it has a flake
if [[ -n "$cell" ]]; then if [[ -n "$cell" ]]; then
local cell_path local cell_path
if cell_path=$(__ren_get_cell_path "$cell"); then if cell_path=$(__ren_get_cell_path "$cell"); then
if [[ -f "${cell_path}/flake.nix" ]]; then if [[ -f "${cell_path}/flake.nix" ]]; then
__ren_log TRACE "Found cell flake. Adding GC roots for inputs from '${cell_path}'." __ren_log TRACE "Found cell flake. Adding GC roots for inputs from '${cell_path}'."
__ren_add_flake_input_gcroots "$cell_path" "$__layout_dir" __ren_add_flake_input_gcroots "$cell_path" "$__layout_dir"
fi
fi fi
fi fi
fi fi
@ -298,15 +374,18 @@ __ren_is_rebuild_needed() {
echo 1 echo 1
return return
fi fi
local watches=()
__ren_get_direnv_watches watches if [ "$REN_DO_WATCH" = true ]; then
for file in "${watches[@]}"; do local watches=()
if [[ "$file" -nt "$profile_rc" ]]; then __ren_get_direnv_watches watches
__ren_log INFO "Cache invalidated by: $file" for file in "${watches[@]}"; do
echo 1 if [[ "$file" -nt "$profile_rc" ]]; then
return __ren_log INFO "Cache invalidated by: $file"
fi echo 1
done return
fi
done
fi
echo 0 echo 0
} }
@ -330,7 +409,11 @@ __ren_build_and_cache() {
if build_output=$(__ren_nix print-dev-env --profile "$tmp_profile" "$flake_attr"); then if build_output=$(__ren_nix print-dev-env --profile "$tmp_profile" "$flake_attr"); then
__ren_clean_old_gcroots "$__layout_dir" __ren_clean_old_gcroots "$__layout_dir"
echo "$build_output" >"$profile_rc" echo "$build_output" >"$profile_rc"
__ren_update_gcroots "$__layout_dir" "$tmp_profile" "$profile" "$cell"
# only add new gcroots if enabled, cleaning old is always fine
if [ "$REN_DO_GCROOTS" = true ]; then
__ren_update_gcroots "$__layout_dir" "$tmp_profile" "$profile" "$cell"
fi
__ren_log TRACE "Cache for '$target_spec' renewed successfully." __ren_log TRACE "Cache for '$target_spec' renewed successfully."
return 0 return 0
@ -344,9 +427,9 @@ __ren_build_and_cache() {
# ENTRYPOINTS # ENTRYPOINTS
# #
# usage in .envrc: use_envreload <target> # usage in .envrc: use ren <target>
# <target> can be `//cell/block/target` or a direct flake attr like `.#myShell` # <target> can be `//cell/block/target` or a direct flake attr like `.#myShell`
use_envreload() { use_ren() {
if [[ -z ${REN_SKIP_VERSION_CHECK:-} ]]; then if [[ -z ${REN_SKIP_VERSION_CHECK:-} ]]; then
__ren_require_version "bash" "$BASH_VERSION" "$BASH_MIN_VERSION" __ren_require_version "bash" "$BASH_VERSION" "$BASH_MIN_VERSION"
__ren_require_cmd_version "direnv" "$DIRENV_MIN_VERSION" __ren_require_cmd_version "direnv" "$DIRENV_MIN_VERSION"
@ -363,11 +446,13 @@ use_envreload() {
local target_spec="${1-}" local target_spec="${1-}"
if [[ -z "$target_spec" ]]; then if [[ -z "$target_spec" ]]; then
__ren_log ERROR "use_envreload requires a target argument, e.g., //repo/devShells/default or .#myShell" __ren_log ERROR "use ren requires a target argument, e.g., //repo/devShells/default or .#myShell"
return 1 return 1
fi fi
__ren_setup_watches "$@" if [ "$REN_DO_WATCH" = true ]; then
__ren_setup_watches "$@"
fi
local __layout_dir profile profile_rc local __layout_dir profile profile_rc
__layout_dir=$(direnv_layout_dir) __layout_dir=$(direnv_layout_dir)
@ -391,6 +476,10 @@ use_envreload() {
__ren_import_env "$profile_rc" __ren_import_env "$profile_rc"
} }
use_rensa() {
use_ren "$@"
}
# initialize project environment variables immediately upon sourcing the script, # initialize project environment variables immediately upon sourcing the script,
# allows the user to use $REN_STATE etc. in .envrc # allows the user to use $REN_STATE etc. in .envrc
__ren_init_project __ren_init_project