Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,30 @@ Inside the `.env` file, two _environment variables_ can be accessed:
- `AUTOENV_CUR_FILE` - The file being sourced
- `AUTOENV_CUR_DIR` - Equivalent to `dirname "$AUTOENV_CUR_FILE"`

#### Programmatic Authorization

You can programmatically authorize, deny, or remove authorization for enter and leave scripts using the following functions:

- `autoenv_authorize [directory] [enter|leave|both]` - Authorize `.env` and/or `.env.leave` files in a directory to be automatically sourced. The directory defaults to the current directory, and the second argument defaults to `both`.
- `autoenv_unauthorize [directory] [enter|leave|both]` - Deny (mark as not authorized) `.env` and/or `.env.leave` files in a directory. They will not be sourced and you won't be prompted for authorization.
- `autoenv_deauthorize [directory] [enter|leave|both]` - Remove authorization for `.env` and/or `.env.leave` files in a directory. You will be prompted for authorization again when entering the directory.

Example usage:

```bash
# Authorize both .env and .env.leave in the current directory.
autoenv_authorize

# Authorize only the .env file in a specific directory.
autoenv_authorize /path/to/project enter

# Deny the .env.leave file in a specific directory.
autoenv_unauthorize /path/to/project leave

# Remove authorization for both files in the current directory.
autoenv_deauthorize
```

## Shells

autoenv is tested on:
Expand Down
138 changes: 138 additions & 0 deletions activate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,18 @@ _autoenv_draw_line() {
fi
}

# @description Convert a directory path to absolute path
# @args $1: directory path
# @internal
_autoenv_get_abs_dir() {
local _dir="${1}"
if \command -v chdir >/dev/null 2>&1; then
( \chdir "${_dir}" && \pwd -P )
else
( \builtin cd "${_dir}" && \pwd -P )
fi
}

# @description Main initialization function
# @internal
autoenv_init() {
Expand Down Expand Up @@ -241,6 +253,132 @@ autoenv_authorize_env() {
autoenv_hashline "${_envfile}" >> "${AUTOENV_AUTH_FILE}"
}

# @description Authorize enter and/or leave scripts in a directory
# @usage autoenv_authorize [directory] [enter|leave|both]
# @args $1: directory path (defaults to current directory)
# @args $2: which files to authorize - "enter", "leave", or "both" (defaults to "both")
# @exitcode 0 on success
# @public
autoenv_authorize() {
local _dir="${1:-.}" _which="${2:-both}" _abs_dir

if [ ! -d "${_dir}" ]; then
\printf '%s\n' "autoenv: error: '${_dir}' is not a directory" >&2
\return 1
fi

case "${_which}" in
enter|leave|both)
;;
*)
\printf '%s\n' "autoenv: error: invalid argument '${_which}' (expected 'enter', 'leave', or 'both')" >&2
\return 1
;;
esac

_abs_dir=$(_autoenv_get_abs_dir "${_dir}")

if [ "${_which}" = "enter" ] || [ "${_which}" = "both" ]; then
if [ -f "${_abs_dir}/${AUTOENV_ENV_FILENAME}" ]; then
autoenv_authorize_env "${_abs_dir}/${AUTOENV_ENV_FILENAME}"
\printf '%s\n' "Authorized: ${_abs_dir}/${AUTOENV_ENV_FILENAME}"
fi
fi

if [ "${_which}" = "leave" ] || [ "${_which}" = "both" ]; then
if [ -f "${_abs_dir}/${AUTOENV_ENV_LEAVE_FILENAME}" ]; then
autoenv_authorize_env "${_abs_dir}/${AUTOENV_ENV_LEAVE_FILENAME}"
\printf '%s\n' "Authorized: ${_abs_dir}/${AUTOENV_ENV_LEAVE_FILENAME}"
fi
fi

\return 0
}

# @description Deny (unauthorize) enter and/or leave scripts in a directory
# @usage autoenv_unauthorize [directory] [enter|leave|both]
# @args $1: directory path (defaults to current directory)
# @args $2: which files to deny - "enter", "leave", or "both" (defaults to "both")
# @exitcode 0 on success
# @public
autoenv_unauthorize() {
local _dir="${1:-.}" _which="${2:-both}" _abs_dir

if [ ! -d "${_dir}" ]; then
\printf '%s\n' "autoenv: error: '${_dir}' is not a directory" >&2
\return 1
fi

case "${_which}" in
enter|leave|both)
;;
*)
\printf '%s\n' "autoenv: error: invalid argument '${_which}' (expected 'enter', 'leave', or 'both')" >&2
\return 1
;;
esac

_abs_dir=$(_autoenv_get_abs_dir "${_dir}")

if [ "${_which}" = "enter" ] || [ "${_which}" = "both" ]; then
if [ -f "${_abs_dir}/${AUTOENV_ENV_FILENAME}" ]; then
autoenv_unauthorize_env "${_abs_dir}/${AUTOENV_ENV_FILENAME}"
\printf '%s\n' "Denied: ${_abs_dir}/${AUTOENV_ENV_FILENAME}"
fi
fi

if [ "${_which}" = "leave" ] || [ "${_which}" = "both" ]; then
if [ -f "${_abs_dir}/${AUTOENV_ENV_LEAVE_FILENAME}" ]; then
autoenv_unauthorize_env "${_abs_dir}/${AUTOENV_ENV_LEAVE_FILENAME}"
\printf '%s\n' "Denied: ${_abs_dir}/${AUTOENV_ENV_LEAVE_FILENAME}"
fi
fi

\return 0
}

# @description Remove authorization for enter and/or leave scripts in a directory
# @usage autoenv_deauthorize [directory] [enter|leave|both]
# @args $1: directory path (defaults to current directory)
# @args $2: which files to deauthorize - "enter", "leave", or "both" (defaults to "both")
# @exitcode 0 on success
# @public
autoenv_deauthorize() {
local _dir="${1:-.}" _which="${2:-both}" _abs_dir

if [ ! -d "${_dir}" ]; then
\printf '%s\n' "autoenv: error: '${_dir}' is not a directory" >&2
\return 1
fi

case "${_which}" in
enter|leave|both)
;;
*)
\printf '%s\n' "autoenv: error: invalid argument '${_which}' (expected 'enter', 'leave', or 'both')" >&2
\return 1
;;
esac

_abs_dir=$(_autoenv_get_abs_dir "${_dir}")

if [ "${_which}" = "enter" ] || [ "${_which}" = "both" ]; then
if [ -f "${_abs_dir}/${AUTOENV_ENV_FILENAME}" ]; then
autoenv_deauthorize_env "${_abs_dir}/${AUTOENV_ENV_FILENAME}"
\printf '%s\n' "Deauthorized: ${_abs_dir}/${AUTOENV_ENV_FILENAME}"
fi
fi

if [ "${_which}" = "leave" ] || [ "${_which}" = "both" ]; then
if [ -f "${_abs_dir}/${AUTOENV_ENV_LEAVE_FILENAME}" ]; then
autoenv_deauthorize_env "${_abs_dir}/${AUTOENV_ENV_LEAVE_FILENAME}"
\printf '%s\n' "Deauthorized: ${_abs_dir}/${AUTOENV_ENV_LEAVE_FILENAME}"
fi
fi

\return 0
}

# @description Actually source a file
# @internal
autoenv_source() {
Expand Down
138 changes: 138 additions & 0 deletions tests/test_authorize_api.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# shellcheck shell=sh

. "${FUNCTIONS}"
. "${ACTIVATE_SH}"

# Prepare test directories and files.
mkdir -pv 'dir1' 'dir2' 'dir3'
echo 'echo enter1' > "dir1/.env"
echo 'echo leave1' > "dir1/.env.leave"
echo 'echo enter2' > "dir2/.env"
echo 'echo leave2' > "dir2/.env.leave"
echo 'echo enter3' > "dir3/.env"

abs_dir1=$(
if \command -v chdir >/dev/null 2>&1; then
( \chdir dir1 && \pwd -P )
else
( \builtin cd dir1 && \pwd -P )
fi
)
abs_dir2=$(
if \command -v chdir >/dev/null 2>&1; then
( \chdir dir2 && \pwd -P )
else
( \builtin cd dir2 && \pwd -P )
fi
)
abs_dir3=$(
if \command -v chdir >/dev/null 2>&1; then
( \chdir dir3 && \pwd -P )
else
( \builtin cd dir3 && \pwd -P )
fi
)

# Test autoenv_authorize with both enter and leave files.
out=$(autoenv_authorize dir1)
ret="$?"
if [ ${ret} -ne 0 ]; then
echo "autoenv_authorize failed with exit code ${ret}."
exit 1
fi
if ! printf '%s\n' "${out}" | grep -q "Authorized: ${abs_dir1}/.env" ; then
echo "autoenv_authorize did not authorize .env file."
exit 1
fi
if ! printf '%s\n' "${out}" | grep -q "Authorized: ${abs_dir1}/.env.leave" ; then
echo "autoenv_authorize did not authorize .env.leave file."
exit 1
fi

# Verify the files are authorized by checking if they're in the auth file.
# Use absolute paths for hash calculation.
hash1=$(autoenv_hashline "${abs_dir1}/.env")
hash2=$(autoenv_hashline "${abs_dir1}/.env.leave")
if ! grep -q "${hash1}" "${AUTOENV_AUTH_FILE}"; then
echo ".env file was not added to auth file."
exit 1
fi
if ! grep -q "${hash2}" "${AUTOENV_AUTH_FILE}"; then
echo ".env.leave file was not added to auth file."
exit 1
fi

# Test autoenv_authorize with only "enter" option.
out=$(autoenv_authorize dir2 enter)
if ! printf '%s\n' "${out}" | grep -q "Authorized: ${abs_dir2}/.env" ; then
echo "autoenv_authorize with 'enter' did not authorize .env file."
exit 1
fi
if printf '%s\n' "${out}" | grep -q "Authorized: ${abs_dir2}/.env.leave" ; then
echo "autoenv_authorize with 'enter' incorrectly authorized .env.leave file."
exit 1
fi

# Test autoenv_authorize with only "leave" option.
out=$(autoenv_authorize dir2 leave)
if ! printf '%s\n' "${out}" | grep -q "Authorized: ${abs_dir2}/.env.leave" ; then
echo "autoenv_authorize with 'leave' did not authorize .env.leave file."
exit 1
fi

# Test autoenv_deauthorize.
out=$(autoenv_deauthorize dir1)
if ! printf '%s\n' "${out}" | grep -q "Deauthorized: ${abs_dir1}/.env" ; then
echo "autoenv_deauthorize did not deauthorize .env file."
exit 1
fi
if ! printf '%s\n' "${out}" | grep -q "Deauthorized: ${abs_dir1}/.env.leave" ; then
echo "autoenv_deauthorize did not deauthorize .env.leave file."
exit 1
fi

# Verify the files are deauthorized by checking they're not in the auth file.
if grep -q "${hash1}" "${AUTOENV_AUTH_FILE}"; then
echo ".env file was not removed from auth file."
exit 1
fi
if grep -q "${hash2}" "${AUTOENV_AUTH_FILE}"; then
echo ".env.leave file was not removed from auth file."
exit 1
fi

# Test autoenv_unauthorize (deny).
out=$(autoenv_unauthorize dir3)
if ! printf '%s\n' "${out}" | grep -q "Denied: ${abs_dir3}/.env" ; then
echo "autoenv_unauthorize did not deny .env file."
exit 1
fi
hash3=$(autoenv_hashline "${abs_dir3}/.env")
if ! grep -q "${hash3}" "${AUTOENV_NOTAUTH_FILE}"; then
echo ".env file was not added to not-authorized file."
exit 1
fi

# Test error handling with non-existent directory.
out=$(autoenv_authorize nonexistent 2>&1)
ret="$?"
if [ ${ret} -eq 0 ]; then
echo "autoenv_authorize should have failed with non-existent directory."
exit 1
fi
if ! printf '%s\n' "${out}" | grep -q "is not a directory" ; then
echo "autoenv_authorize did not report proper error for non-existent directory."
exit 1
fi

# Test error handling with invalid option.
out=$(autoenv_authorize dir1 invalid 2>&1)
ret="$?"
if [ ${ret} -eq 0 ]; then
echo "autoenv_authorize should have failed with invalid option."
exit 1
fi
if ! printf '%s\n' "${out}" | grep -q "invalid argument" ; then
echo "autoenv_authorize did not report proper error for invalid option."
exit 1
fi
Loading