asdf-vm / asdf

Extendable version manager with support for Ruby, Node.js, Elixir, Erlang & more
https://asdf-vm.com/
MIT License
22k stars 782 forks source link

Support XDG locations for files (including plugins) #687

Open jthegedus opened 4 years ago

jthegedus commented 4 years ago

Idea

Edit: it seems supporting the XDG spec would satisfy most peoples needs, so renaming to capture this intent.

Currently asdf-nodejs, asdf-ruby and asdf-python among other plugins allow for $HOME/.default-<tool>-packages config files. It is clear from the discussions in each plugin that people want to be able to configure the file location.

Proposals

Perhaps asdf core can provide plugins with ASDF_CONFIG dir that is the directory of .asdfrc by default?


This way, users can configure this, and plugin authors can focus on the default packages filename appropriate for their plugin and install those packages instead of also having to support a diverging set of dirs.

Or perhaps this is too much and simply doing:

default_gem_path() {
  local config_path=${ASDF_CONFIG_FILE:-"$HOME/.asdfrc"}
  local config_dir=$(dirname "$config_path") 

in each plugin is enough. (This was proposed in asdf-ruby https://github.com/asdf-vm/asdf-ruby/pull/114/files)

Related

andrewthauer commented 4 years ago

The main reason I would want to see this is to be more XDG compliant. For instance, I currently do the following in order to keep my $HOME directory cleaner.

export ASDF_CONFIG_FILE="${XDG_CONFIG_HOME}/asdf/asdfrc"

Ideally the ${XDG_CONFIG_HOME} would be the default location for all asdf related config files vs $HOME. Currently it's possible to override this for some parts of asdf via environment variable, but not for deafult-* files.

Stratus3D commented 4 years ago

I know some existing version managers (like rbenv for Ruby) currently look for .default-gems in the users home directory. I don't know if rbenv allows the user to customize the location of the file, but I would guess most rbenv users don't, so ideally asdf-ruby would look for .default-gems in the users home directory by default too. I'm open to a new feature that allows users to better organize things with asdf, but I also think we should imitate the behavior of other widely used legacy version managers whenever possible.

andrewthauer commented 4 years ago

To be clear, I brought up XDG as a very valid example of why people may want to override the location of these files. Currently the default-* files are the only standard parts I'm unable to do this with.

In regards to rbenv, the rbenv-default-gems plugin does allow you to override the default directory. I believe it uses $(rbenv root)/default-gems which before I switched to asdf :) could be set with export RBENV_ROOT="${XDG_DATA_HOME}/rbenv" (which would = ~/.local/share/rbenv on most systems).

brianvanburken commented 3 years ago

I agree that we should imitate the behavior of legacy version managers by default. If no ENV variable is set then that should be the default behavior. I do notice that there are a few PR's still open which do adhere to this meanwhile providing an option to override this. This does raise the question: should the core enforce this or leave it up to the plugins to decide on their own? The latter would be more suited.

I would also like to see these changes in the plugin. My reason is that I also follow the principles of XDG and have moved most of my configuration to ~/.config/asdf/ on my macOS system.

For reference and inspiration, here are a few PR's which propose the ability to move default package files to custom locations.

https://github.com/danhper/asdf-python/pull/63 (merged) https://github.com/asdf-vm/asdf-nodejs/pull/170 (merged) https://github.com/asdf-vm/asdf-ruby/pull/114

jthegedus commented 3 years ago

Sounds like we're all on the same page; support existing ecosystem defaults with a config var for custom location. Should this be part of the asdf core though?

andrewthauer commented 3 years ago

I would advocate for making asdf core XDG complaint. It should be possible to do this in a backwards compatible way like many other tools have done in the past. Currently I do the following:

export ASDF_DATA_DIR="${XDG_DATA_HOME:-~./local/share}/asdf"
export ASDF_CONFIG_FILE="${XDG_CONFIG_HOME:-~./config}/asdf/asdfrc"

Introducing an ASDF_CONFIG_DIR variable would allow for something like this:

export ASDF_CONFIG_DIR="${XDG_CONFIG_HOME}/asdf"
export ASDF_CONFIG_FILE="${ASDF_CONFIG_DIR}/asdfrc"
export ASDF_NODEJS_DEFAULT_PACKAGES="${ASDF_CONFIG_DIR}/nodejs_default_packages"

The ASDF_CONFIG_FILE variable would then default to using the ASDF_CONFIG_DIR as the base directory (defaulted to $HOME/.config/asdf) unless overridden. Any plugins can then start using the ASDF_CONFIG_DIR as the base config directory and/or provide a custom environment override as needed.

Stratus3D commented 3 years ago

From @brennanfee on #844:

I would STRONGLY encourage that #687 be updated to refer to and use XDG_CONFIG as its implementation. Given that it has become a standard on nearly all Linux distributions and if implemented with a default when NOT set can work equally well on Mac and Windows.

For reference here is the "official" documentation: https://specifications.freedesktop.org/basedir-spec/latest/

More info: https://www.freedesktop.org/wiki/Software/xdg-user-dirs/

jwillikers commented 3 years ago

Following the XDG spec is important for people taking snapshots / backups of their home directory. By not following the XDG spec, storage can quickly and unexpectedly fill up. While most users know to exclude ~/.cache, they aren't likely to think of excluding ~/.asdf. I think it's important for a project like asdf to respect the standard user directory layout just as system-wide package managers respect the standard system-level directory layout.

eriteric commented 3 years ago

Looking forward to this

erikw commented 2 years ago

@jthegedus could you update this ticket to be about general XDG compliance as discussed in #201 (that this ticket should be)?

I would like to include in the discussion that also directories like $HOME/.asdf/ should reside in $XDG_DATA_HOME/asdf/ as well (which would default to $HOME/.local/share/asdf/).

I currently use:

export ASDF_CONFIG_FILE=${XDG_CONFIG_HOME}/asdf/asdfrc
export ASDF_DATA_DIR=${XDG_DATA_HOME}/asdf

export ASDF_PYTHON_DEFAULT_PACKAGES_FILE=${XDG_CONFIG_HOME}/pip/default-python-packages
export ASDF_NPM_DEFAULT_PACKAGES_FILE=${XDG_CONFIG_HOME}/npm/default-npm-packages
export ASDF_GEM_DEFAULT_PACKAGES_FILE=${XDG_CONFIG_HOME}/gem/default-gems

Yays to less clutter in our home directores! 🥳

quintrino commented 2 years ago

I also ran into the ASDF_DEFAULT_TOOL_VERSIONS_FILENAME issue talked about in #1248 where I'd been using it to shift my global tool-versions to make it XDG compliant, so I look forward to a fix for that issue at the very least. (everything else ASDF related is currently XDG compliant in my setup)

doolio commented 2 years ago

To add to this discussion I would like the asdf completions to also be XDG compliant and thus reside under $XDG_DATA_HOME/bash-completion/completions/asdf/ or ~/.local/share/bash-completion/completions/asdf if $XDG_DATA_HOME is not set.

I presume the fish completions should follow a similar convention.

doolio commented 2 years ago

From @brennanfee on #844:

I would STRONGLY encourage that #687 be updated to refer to and use XDG_CONFIG as its implementation. Given that it has become a standard on nearly all Linux distributions and if implemented with a default when NOT set can work equally well on Mac and Windows.

I think they mean $XDG_CONFIG_HOME rather than $XDG_CONFIG.

erikw commented 1 year ago

I'd like to add that asdf also created the file $HOME/.tools-version. It would be great if this also lived in a proper XDG directory!

I tired setting ASDF_DEFAULT_TOOL_VERSIONS_FILENAME however after trying it seems to not work using this to move the top-level $HOME/.tools-version file, the purpose is different for this environment variable.

Edit. Workaround is here: https://github.com/asdf-vm/asdf/issues/1248#issuecomment-1155978678

bigodel commented 6 months ago

Edit. Workaround is here: #1248 (comment)

please do note that this workaround only works for the global .tool-versions file, but it uses that as a relative name to find the location of any .tool-versions file, as mentioned on the reply right below my commnet.