magicant / yash

Yet another shell
http://magicant.github.io/yash/
GNU General Public License v2.0
300 stars 28 forks source link

Yash Throws: yash: parameter `DIRENV_DIR' is not set When Accounted For #55

Open FOSSilizedDaemon opened 3 weeks ago

FOSSilizedDaemon commented 3 weeks ago

Describe the bug I am currently implementing direnv support into my configuration. I started by adding the direnv shell script offered in the example rc file.

_update_direnv_info() {
    eval "$(
    direnv export json |
        jq -r 'to_entries | .[] |
        if .value == null then
            @sh "unset \(.key)"
        else
            @sh "export \(.key)=\(.value)"
        end'
        )"
}
YASH_AFTER_CD=('_update_direnv_info')

I then wiped up a quick prompt to show either direnv or python status.

_update_direnv_status() {
    direnv_info=$(basename "$(printf "%s" "${DIRENV_DIR}" | tr -d '-')")
    environment_info="\fmt.-(\fd.\fct.${direnv_info}\fd.\fmt.)\fd."
    printf "%s" "${environment_info}"
}

_update_python_status() {
    python_info=$(basename "${VIRTUAL_ENV}")
    environment_info="\fmt.-(\fd.\fct.${python_info}\fd.\fmt.)\fd."
    printf "%s" "${environment_info}"
}

_update_environment_info() {
    if [ -n "${DIRENV_DIR}" ]; then
        _update_direnv_status
    elif [ -n "${VIRTUAL_ENV}" ]; then
        _update_python_status
    fi
}
export PS1='.$(_update_environment_info) \fmt>\fd\fyt>\fd\fct>\fd '

However, every time I run a shell I get the following line yash: parameter DIRENV_DIR' is not set after every command and when I am not in a direnv allowed directory. I did some digging and it is coming from my prompt function _update_direnv_status. From my understanding within POSIX and many other shells, though I may be wrong, this shouldn't be happening because if "${DIRENV_DIR}" is empty the shell will simply move on. Am I missing something? To Reproduce Steps to reproduce the behavior:

  1. Create new .yashrc
  2. Copy the above code into it
  3. Launch a new shell
  4. See error

Expected behavior I expect the shell to show nothing related to direnv when not in a direnv allowed directory.

Screenshots If applicable, add screenshots to help explain your problem.

Environment (please complete the following information):

Additional context I do not have any additional context other than my current dotfiles located here.

As an update, I found a workaround. If you set

DIRENV_DIR="${DIRENV_DIR:-""}"
VIRTUAL_ENV="${VIRTUAL_ENV:-""}"

you won't get the message. I have not experienced this in other shells, maybe it is a POSIX thing? At any rate, functionally solved. My bad! Though, I have noticied this in scripts and even elsewhere in my configuration. If I have a script that can take optional arguments, or a function or alias that can, such as

_git_add() {
        if [ -z "${1}" ]; then
                        git add . --verbose
        else
                        git add "${@}" --verbose
        fi
}
alias ga='_git_add'

and I run it as 'ga' it should then run git add . --verbose as "${1}" is empty, but instead I get yash: parameter1' is not set` and it skips to the else statement.

magicant commented 3 weeks ago

The shell complains about non-existing variables if the nounset option is on. It seems to be turned on here in your case. If you want the shell to silently ignore such variables, you can remove the set command. Another workaround is (as you already mentioned) to use ${DIRENV_DIR:-""}, or simply ${DIRENV_DIR-}.