Open excid3 opened 5 years ago
It depends on those hooks are implemented. I do think there is a need for something like this, but I want to make sure the solution we come up with is generic enough to satisfy all the possible use cases. We've already got a need for something like asdf-vars in several other plugins. For example, the Erlang plugin reads certain environment variables during installation, and Erlang itself also reads other environment variables at runtime. There is definitely a need for a more standardized way of making sure environment variables are set before compilation or execution of a program.
So to answer your question, yes, we definitely want something like this. But we want to make sure it's the right solution so we don't have to revisit this in the future.
For asdf-vars, I think we could potentially bake that functionality right into asdf. Imagine an optional .asdf-ruby-compile-env
and .asdf-ruby-runtime-env
files that get sourced before compilation and before runtime. asdf would just look for files matching the pattern .asdf-<plugin name>-*-env
and it would work across the board for all plugins with no changes necessary to any of the plugins.
For more generalized "before exec" hooks we'd want to make it easy for the user to plug in anything they wanted without having to jump through too many hoops. We'd also want to limit the scope of the "before exec" hook. The hook shouldn't be responsible for directory traversal, version manipulation, or need to duplicate any of the existing functionality of asdf.
I want to clarify too, my use case for asdf-vars is actually more for setting environment variables for apps separately.
For example, I can set DATABASE_URL=whatever
in .asdf-vars
in two different folders which allows my apps to run on the same machine without conflicts.
This could be useful for other things, but I don't know of enough of the use cases where you'd want something like -compile-env
and -runtime-env
etc. A generic version might actually cover most things, but I'd be curious to hear about other use cases.
I fear there will be a tension here between environment variables that are part of your personal setup (e.g. the local DB port/URL as you suggest, or the local path to a sibling repository) and environment variables that you want set consistently for everyone working on the project (e.g. compilation flags for Erlang). I could even imagine someone wanting a different environment variable file for production.
I very much appreciate this idea for both use cases presented so far, but already there seems to be a conflict at the level of "do I want to track this file in version control?" What happens when you want both?
Agreed. And one thing that asdf-vars / rbenv-vars does is recursively look up the folder stack for vars files. That way you could keep shared variables in version control and production can have it's own, untracked vars in a parent folder. The merging allows you some flexibility there.
@excid3 yes, we could have to traverse your directory structure looking for a .asdf-ruby-vars
file until it finds one. Placing one in your project would set env vars just for that project, placing one in parent directory would set env vars for that dir and all sub dirs.
@Jwashton yes that is a concern. Check personal settings into VC could be a problem. Of course we could tell people not to check the env files in, or to only check in sample env files that would be renamed by the user. I'm on the fence about this feature. I can see benefits to having it, but it would have the potential to cause a lot of problems.
This is my mindset when figuring out how proposed features should be implemented:
I'm not really sure where this feature falls.
I believe there's a great tool for the use case of per-project environment variables already: https://direnv.net/
In the unix spirit it does one thing and does it well.
It also has a feature to "authorize" a .envrc
file to ensure you are not exposed to risky env vars from projects you clone and cd
into.
I think the one downside of direnv is that it installs itself by prepending it self to your prompt so it gets triggered every time.
Correct me if I'm wrong, but this won't work if you're over SSH using a non-login, non-interactive shell, which is what I'm considering using asdf with.
_direnv_hook() {
local previous_exit_status=$?;
eval "$(direnv export bash)";
return $previous_exit_status;
};
if ! [[ "$PROMPT_COMMAND" =~ _direnv_hook ]]; then
PROMPT_COMMAND="_direnv_hook;$PROMPT_COMMAND";
fi
I'm not familiar with direnv, but I do know it's far more intrusive than asdf. All asdf really does is stick a few things on your PATH
.
I just came across a situation where I'd like to create some directories after redis is installed, which would be a perfect use for a post-install hook. It would be great for setting up config files too.
I've been putting together a PR that adds support for intrusive plugins, in two main ways:
So given my proposal about aliases, a possible approach would be:
alias-add
, alias-remove
, alias-list
I looked into adding hooks to various points in the utils/command scripts, but the reality is that there is no sane way to do so without making large portions of the internals effectively a public API. The advantage of the approach above is that plugins can modify any public env vars, perform arbitrary work at initialization, and can transparently modify the command/arguments asdf will dispatch on - and that's a powerful tool set, but ultimately the burden is on the plugin author, not the asdf maintainers. By allowing dispatch to plugin porcelain in the case of unresolved commands, plugins can feel like a natural part of the CLI, and again without imposing any maintenance burden on the asdf maintainers.
I haven't had time to experiment further, but figured I'd leave my notes here for feedback.
Hi, I was wondering if there was an update on this issue. I'm interested in using asdf
to add env vars like asdf
works for other tools. Getting everyone on my team to follow the install steps at the top of this issue would be suboptimal. I also found this plugin that might be a little easier to setup: https://github.com/asdf-community/asdf-direnv
For anyone curious, I forked asdf and added asdf vars
that loads .asdf-vars
files and evaluates them during exec.
https://github.com/asdf-vm/asdf/compare/master...excid3:asdf:master
For anyone curious, I forked asdf and added
asdf vars
that loads.asdf-vars
files and evaluates them during exec.
Cool, will this get merged to main asdf?
Rbenv allows you to install plugins that hook into more functionality of the version manager. For example, rbenv-vars allows you to set project specific environment variables and are automatically loaded when Ruby is executed.
I've replicated this for asdf called asdf-vars, but right now I have to inject into the asdf-exec script to add this functionality. The downside is that this is going to cause a conflict when updating asdf in the future.
There's a list of other interesting plugins here: https://github.com/rbenv/rbenv/wiki/Plugins
These are the hooks that they support for plugins: https://github.com/rbenv/rbenv/wiki/Authoring-plugins#rbenv-hooks
Would adding hooks to support non-language plugins to asdf be something that would get accepted as a PR or is already on the roadmap?