Unverified Commit 6fbfc4c7 authored by Jędrzej Lewandowski's avatar Jędrzej Lewandowski Committed by GitHub
Browse files

dotenv: add agree-once improvement to confirmation prompt (#8729)



* dotenv: add possibility to agree once for a given .env file

* refactor: fix code style

* Use :A modifier instead of readlink. Thanks Aloxaf

* Use grep and clean up allowed list check logic

* Simplify and reorder file; change default allowed list path

* Add new feature to README

* Make sure ZSH_CACHE_DIR is defined

* Resolve symlinks in $PWD before storing in allowed list
Co-authored-by: default avatarAloxaf <bailong104@gmail.com>
Co-authored-by: default avatarMarc Cornellà <marc.cornella@live.com>
parent fe97382b
...@@ -4,9 +4,7 @@ Automatically load your project ENV variables from `.env` file when you `cd` int ...@@ -4,9 +4,7 @@ Automatically load your project ENV variables from `.env` file when you `cd` int
Storing configuration in the environment is one of the tenets of a [twelve-factor app](https://www.12factor.net). Anything that is likely to change between deployment environments, such as resource handles for databases or credentials for external services, should be extracted from the code into environment variables. Storing configuration in the environment is one of the tenets of a [twelve-factor app](https://www.12factor.net). Anything that is likely to change between deployment environments, such as resource handles for databases or credentials for external services, should be extracted from the code into environment variables.
## Installation To use it, add `dotenv` to the plugins array in your zshrc file:
Just add the plugin to your `.zshrc`:
```sh ```sh
plugins=(... dotenv) plugins=(... dotenv)
...@@ -17,22 +15,26 @@ plugins=(... dotenv) ...@@ -17,22 +15,26 @@ plugins=(... dotenv)
Create `.env` file inside your project root directory and put your ENV variables there. Create `.env` file inside your project root directory and put your ENV variables there.
For example: For example:
```sh ```sh
export AWS_S3_TOKEN=d84a83539134f28f412c652b09f9f98eff96c9a export AWS_S3_TOKEN=d84a83539134f28f412c652b09f9f98eff96c9a
export SECRET_KEY=7c6c72d959416d5aa368a409362ec6e2ac90d7f export SECRET_KEY=7c6c72d959416d5aa368a409362ec6e2ac90d7f
export MONGO_URI=mongodb://127.0.0.1:27017 export MONGO_URI=mongodb://127.0.0.1:27017
export PORT=3001 export PORT=3001
``` ```
`export` is optional. This format works as well: `export` is optional. This format works as well:
```sh ```sh
AWS_S3_TOKEN=d84a83539134f28f412c652b09f9f98eff96c9a AWS_S3_TOKEN=d84a83539134f28f412c652b09f9f98eff96c9a
SECRET_KEY=7c6c72d959416d5aa368a409362ec6e2ac90d7f SECRET_KEY=7c6c72d959416d5aa368a409362ec6e2ac90d7f
MONGO_URI=mongodb://127.0.0.1:27017 MONGO_URI=mongodb://127.0.0.1:27017
PORT=3001 PORT=3001
``` ```
You can even mix both formats, although it's probably a bad idea. You can even mix both formats, although it's probably a bad idea.
## Plugin options ## Settings
### ZSH_DOTENV_FILE ### ZSH_DOTENV_FILE
...@@ -40,7 +42,7 @@ You can also modify the name of the file to be loaded with the variable `ZSH_DOT ...@@ -40,7 +42,7 @@ You can also modify the name of the file to be loaded with the variable `ZSH_DOT
If the variable isn't set, the plugin will default to use `.env`. If the variable isn't set, the plugin will default to use `.env`.
For example, this will make the plugin look for files named `.dotenv` and load them: For example, this will make the plugin look for files named `.dotenv` and load them:
``` ```zsh
# in ~/.zshrc, before Oh My Zsh is sourced: # in ~/.zshrc, before Oh My Zsh is sourced:
ZSH_DOTENV_FILE=.dotenv ZSH_DOTENV_FILE=.dotenv
``` ```
...@@ -48,6 +50,27 @@ ZSH_DOTENV_FILE=.dotenv ...@@ -48,6 +50,27 @@ ZSH_DOTENV_FILE=.dotenv
### ZSH_DOTENV_PROMPT ### ZSH_DOTENV_PROMPT
Set `ZSH_DOTENV_PROMPT=false` in your zshrc file if you don't want the confirmation message. Set `ZSH_DOTENV_PROMPT=false` in your zshrc file if you don't want the confirmation message.
You can also choose the `Always` option when prompted to always allow sourcing the .env file
in that directory. See the next section for more details.
### ZSH_DOTENV_ALLOWED_LIST
The default behavior of the plugin is to always ask whether to source a dotenv file. There's
a **Y**es, **N**o, and **A**lways option. If you choose Always, the directory of the .env file
will be added to an allowed list. If a directory is found in this list, the plugin won't ask
for confirmation and will instead source the .env file directly.
This allowed list is saved by default in `$ZSH_CACHE_DIR/dotenv-allowed.list`. If you want
to change that location, change the `$ZSH_DOTENV_ALLOWED_LIST` variable, like so:
```zsh
# in ~/.zshrc, before Oh My Zsh is sourced:
ZSH_DOTENV_ALLOWED_LIST=/path/to/dotenv/allowed/list
```
This file is just a list of directories allowed, separated by a newline character. If you want
to disallow a directory, just edit this file and remove the line for the directory you want to
disallow.
## Version Control ## Version Control
...@@ -58,5 +81,6 @@ Set `ZSH_DOTENV_PROMPT=false` in your zshrc file if you don't want the confirmat ...@@ -58,5 +81,6 @@ Set `ZSH_DOTENV_PROMPT=false` in your zshrc file if you don't want the confirmat
This plugin only sources the `.env` file. Nothing less, nothing more. It doesn't do any checks. It's designed to be the fastest and simplest option. You're responsible for the `.env` file content. You can put some code (or weird symbols) there, but do it on your own risk. `dotenv` is the basic tool, yet it does the job. This plugin only sources the `.env` file. Nothing less, nothing more. It doesn't do any checks. It's designed to be the fastest and simplest option. You're responsible for the `.env` file content. You can put some code (or weird symbols) there, but do it on your own risk. `dotenv` is the basic tool, yet it does the job.
If you need more advanced and feature-rich ENV management, check out these awesome projects: If you need more advanced and feature-rich ENV management, check out these awesome projects:
* [direnv](https://github.com/direnv/direnv) * [direnv](https://github.com/direnv/direnv)
* [zsh-autoenv](https://github.com/Tarrasch/zsh-autoenv) * [zsh-autoenv](https://github.com/Tarrasch/zsh-autoenv)
## Settings
# Filename of the dotenv file to look for
: ${ZSH_DOTENV_FILE:=.env}
# Path to the file containing allowed paths
: ${ZSH_DOTENV_ALLOWED_LIST:="${ZSH_CACHE_DIR:-$ZSH/cache}/dotenv-allowed.list"}
## Functions
source_env() { source_env() {
if [[ -f $ZSH_DOTENV_FILE ]]; then if [[ -f $ZSH_DOTENV_FILE ]]; then
if [ "$ZSH_DOTENV_PROMPT" != "false" ]; then if [[ "$ZSH_DOTENV_PROMPT" != false ]]; then
# confirm before sourcing file local confirmation dirpath="${PWD:A}"
local confirmation
# print same-line prompt and output newline character if necessary # make sure there is an allowed file
echo -n "dotenv: source '$ZSH_DOTENV_FILE' file in the directory? (Y/n) " touch "$ZSH_DOTENV_ALLOWED_LIST"
read -k 1 confirmation; [[ "$confirmation" != $'\n' ]] && echo
# only bail out if confirmation character is n # check if current directory's .env file is allowed or ask for confirmation
if [[ "$confirmation" = [nN] ]]; then if ! grep -q "$dirpath" "$ZSH_DOTENV_ALLOWED_LIST" &>/dev/null; then
return # print same-line prompt and output newline character if necessary
echo -n "dotenv: found '$ZSH_DOTENV_FILE' file. Source it? ([Y]es/[n]o/[a]lways) "
read -k 1 confirmation; [[ "$confirmation" != $'\n' ]] && echo
# check input
case "$confirmation" in
[nN]) return ;;
[aA]) echo "$dirpath" >> "$ZSH_DOTENV_ALLOWED_LIST" ;;
*) ;; # interpret anything else as a yes
esac
fi fi
fi fi
# test .env syntax # test .env syntax
zsh -fn $ZSH_DOTENV_FILE || echo "dotenv: error when sourcing '$ZSH_DOTENV_FILE' file" >&2 zsh -fn $ZSH_DOTENV_FILE || echo "dotenv: error when sourcing '$ZSH_DOTENV_FILE' file" >&2
if [[ -o a ]]; then setopt localoptions allexport
source $ZSH_DOTENV_FILE source $ZSH_DOTENV_FILE
else
set -a
source $ZSH_DOTENV_FILE
set +a
fi
fi fi
} }
autoload -U add-zsh-hook autoload -U add-zsh-hook
add-zsh-hook chpwd source_env add-zsh-hook chpwd source_env
if [[ -z $ZSH_DOTENV_FILE ]]; then
ZSH_DOTENV_FILE=.env
fi
source_env source_env
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment