Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Follow XDG Base Directory Specification #1678

Open
jtrv opened this issue Dec 29, 2022 · 9 comments · May be fixed by #4542
Open

Follow XDG Base Directory Specification #1678

jtrv opened this issue Dec 29, 2022 · 9 comments · May be fixed by #4542
Labels
enhancement New feature or request

Comments

@jtrv
Copy link

jtrv commented Dec 29, 2022

What is the problem this feature would solve?

The .bun/ directory unnecessarily pollute users' $HOME directory.
Related: #696, #965

What is the feature you are proposing to solve the problem?

The XDGBDS defines where these files should be placed with environment variables to avoid polluting the $HOME directory.

From the XDGBDS:

The XDG Base Directory Specification is based on the following concepts:

  • There is a single base directory relative to which user-specific data files should be written. This directory is defined by the environment variable $XDG_DATA_HOME.

  • There is a single base directory relative to which user-specific configuration files should be written. This directory is defined by the environment variable $XDG_CONFIG_HOME.

  • There is a single base directory relative to which user-specific state data should be written. This directory is defined by the environment variable $XDG_STATE_HOME.

  • There is a single base directory relative to which user-specific executable files may be written.

  • There is a single base directory relative to which user-specific non-essential (cached) data should be written. This directory is defined by the environment variable $XDG_CACHE_HOME.

User-specific executable files may be stored in $HOME/.local/bin.

Implementing XDGBDS should work as follows:

IF a corresponding XDG environment variable exists THEN use it's location according to the spec.

ELSE If the corresponding XDG_* env var is not defined, the program must fallback to the specified defaults:

env fallback
XDG_DATA_HOME ~/.local/share
XDG_CONFIG_HOME ~/.config
XDG_STATE_HOME ~/.local/state
XDG_CACHE_HOME ~/.cache

So the default/fallback directory layout mapping should be:

current xdg compliant
~/.bun/bin/bun ~/.local/bin/bun
~/.bun/install/cache ~/.cache/bun
~/.bun/install/global/node_modules ~/.local/lib/node_modules
~/.bun/install/global/package.json ~/.config/bun/package.json
~/.bun/install/global/bun.lockb ~/.config/bun/bun.lockb

In addition, globally installed modules should go in ~/.local/lib/node_modules, with binaries symlinked under ~/.local/bin (which is what npm does).

What alternatives have you considered?

We can also fallback to the .bun directory for backwards compatibility but as others have mentioned below this is not ideal and not part of the XDGBDS.

The other alternative is to let all programs arbitrarily use the $HOME directory and create their own structure and organization for cache, data, config, etc. This is not optimal for any system with more than a few programs installed, which is why the XDGBDS exists to keep your system organized and easily navigable.

(Edited per ju1ius, ZerdoX-x)

@jtrv jtrv added the enhancement New feature or request label Dec 29, 2022
@ju1ius
Copy link

ju1ius commented Feb 25, 2023

IF a corresponding XDG environment variable exists THEN use it's location according to the spec.
ELSE use the current behavior / locations in the .bun/ directory.

FWIW, this is not how this is not exactly how the XDG base-dir spec works.
If an XDG_* env var is not defined, the program must fallback to the specified defaults:

env fallback
XDG_DATA_HOME ~/.local/share
XDG_CONFIG_HOME ~/.config
XDG_STATE_HOME ~/.local/state
XDG_CACHE_HOME ~/.cache

So the directory layout mapping should look like the following:

current xdg compliant
~/.bun/bin/bun ~/.local/bin/bun
~/.bun/install/cache ~/.cache/bun
~/.bun/install/global/node_modules ~/.local/lib/node_modules
~/.bun/install/global/package.json ~/.config/bun/package.json
~/.bun/install/global/bun.lockb ~/.config/bun/bun.lockb

In addition, globally installed modules should go in ~/.local/lib/node_modules, with binaries symlinked under ~/.local/bin (which is what npm does atm).

@jtrv
Copy link
Author

jtrv commented Feb 26, 2023

Good catch! I would also add that since the project is not yet 1.0, it's important to implement these breaking changes sooner or schedule them before 1.0 to mitigate the impact to the early adopters who can expect to see these sorts of breaking changes.

@jtrv
Copy link
Author

jtrv commented Aug 7, 2023

I noticed the banner for 1.0 launching September 7th, very cool! However I wanted to re-emphasize that adherence to XDGBDS should probably happen before or in 1.0 to avoid delaying the breaking changes to a future X.0 release and impacting a larger audience or other projects that might use the .bun directory. It will also likely grow in complexity to replace the .bun directory as more code relying on it gets merged.

@lgarron
Copy link
Contributor

lgarron commented Aug 7, 2023

FWIW, this is not how this is not exactly how the XDG base-dir spec works.
If an XDG_* env var is not defined, the program must fallback to the specified defaults:

Just another note on this: bun currently uses a folder with a dot prefix even when placing it inside an XDG var folder.

For example, https://github.com/oven-sh/bun/blob/b93f304c063698ada698eddc4321c5c7010e5e5d/src/install/install.zig uses $XDG_CACHE_HOME/.bun instead of $XDG_CACHE_HOME/bun.

This is unusual, in that I have yet to see see any other program use a . prefix for folders inside the XDG convention folders. This may cause the folder to be unexpectedly hidden when viewing it in a file explorer app or running ls without -a. (That is, someone may expect ~/.cache to be hidden — but that all folders are visible once they are viewing that hidden folder.)

I personally show all hidden files and folder, so this is not really an issue for me, but I think it's an opportunity to reduce the potential for surprise if these paths are revisited.

lgarron added a commit to lgarron/bun that referenced this issue Aug 31, 2023
… var is set).

This addresses the comment at oven-sh#1678 (comment)

> … I have yet to see see any other program use a `.` prefix for folders
> *inside* the XDG convention folders. This may cause the folder to be
> unexpectedly hidden when viewing it in a file explorer app or running
> `ls` without `-a`. (That is, someone may expect `~/.cache` to be
> hidden — but that all folders are visible once they are viewing that
> hidden folder.)

The only previous workaround would have been to set `$BUN_INSTALL`, but
that affects more than the cache directory. (And people who have been
using `$XDG_CACHE_HOME` presumably want to opt into the convention that
all cache directories are grouped into a single place that is easy to
audit and clean, separate from all config data.)

Since this:

- only affects the subset of users who have explictly
opted into `$XDG_CACHE_HOME`, and
- only affects cache data, which is meant to be safe to abandon/lose at
  any moment,

… it shouldn't be harmful to leave the old directory lying around and
allow a new one to be created. But it would also be possible to move the
existing directory with an additional change.
lgarron added a commit to lgarron/bun that referenced this issue Aug 31, 2023
This addresses the comment at oven-sh#1678 (comment)

> … I have yet to see see any other program use a `.` prefix for folders
> *inside* the XDG convention folders. This may cause the folder to be
> unexpectedly hidden when viewing it in a file explorer app or running
> `ls` without `-a`. (That is, someone may expect `~/.cache` to be
> hidden — but that all folders are visible once they are viewing that
> hidden folder.)

The only previous workaround would have been to set `$BUN_INSTALL`, but
that affects more than the cache directory. (And people who have been
using `$XDG_CACHE_HOME` presumably want to opt into the convention that
all cache directories are grouped into a single place that is easy to
audit and clean, separate from all config data.)

Since this:

- only affects the subset of users who have explictly
opted into `$XDG_CACHE_HOME`, and
- only affects cache data, which is meant to be safe to abandon/lose at
  any moment,

… it shouldn't be harmful to leave the old directory lying around and
allow a new one to be created. But it would also be possible to move the
existing directory with an additional change.
@paperdave paperdave added this to the 1.0 milestone Sep 3, 2023
@Electroid Electroid removed this from the 1.0 milestone Sep 3, 2023
booniepepper pushed a commit to booniepepper/bun that referenced this issue Sep 7, 2023
… var is set).

This addresses the comment at oven-sh#1678 (comment)

> … I have yet to see see any other program use a `.` prefix for folders
> *inside* the XDG convention folders. This may cause the folder to be
> unexpectedly hidden when viewing it in a file explorer app or running
> `ls` without `-a`. (That is, someone may expect `~/.cache` to be
> hidden — but that all folders are visible once they are viewing that
> hidden folder.)

The only previous workaround would have been to set `$BUN_INSTALL`, but
that affects more than the cache directory. (And people who have been
using `$XDG_CACHE_HOME` presumably want to opt into the convention that
all cache directories are grouped into a single place that is easy to
audit and clean, separate from all config data.)

Since this:

- only affects the subset of users who have explictly
opted into `$XDG_CACHE_HOME`, and
- only affects cache data, which is meant to be safe to abandon/lose at
  any moment,

… it shouldn't be harmful to leave the old directory lying around and
allow a new one to be created. But it would also be possible to move the
existing directory with an additional change.
@booniepepper booniepepper linked a pull request Sep 7, 2023 that will close this issue
5 tasks
@booniepepper
Copy link
Contributor

booniepepper commented Sep 7, 2023

I incorporated a change by @lgarron and also added to it in my PR. There was another place $HOME was being referenced, and some deviation from falling back to .cache if $XDG_CACHE_HOME is unset

Edit: After catching up a bit, I think my proposed change is not a hard breaking change. It would invalidate some peoples' cache (because the cache would move) but I think it doesn't break anything critical. It's definitely looking like the kinda thing that's better to do sooner than later

@Electroid Electroid removed the 1dotoh label Sep 8, 2023
@booniepepper
Copy link
Contributor

booniepepper commented Sep 11, 2023

Based on some comments from @lgarron it seems like:

  1. My change may not be the only place to update; the Zig layer might not be the only layer of implementation that might need to know about directory locations
  2. We should also consider following other OS standards when on a non-Linux OS. Mac/Windows have different conventions for where to put stuff.
    • There's a pretty fantastic Rust library called directories that documents recommended locations in its README and has a good model for where things should go

@ZerdoX-x
Copy link

ZerdoX-x commented Sep 11, 2023

Workaround for anyone trying to defend their $HOME:

  1. set env BUN_INSTALL to ${XDG_STATE_HOME}/bun (replace with ${HOME}/.local/share if it is not set)
  2. source new profile, login again, etc, depending on how you set your env variables
  3. install bun via script as usual
  4. do not forget to add ${BUN_INSTALL}/bin to your PATH env variable

Result:

$ curl -fsSL https://bun.sh/install | bash
bun was installed successfully to ~/.local/share/bun/bin/bun

@ZerdoX-x
Copy link

ZerdoX-x commented Sep 11, 2023

@jtrv (OP)

Implementing XDGBDS would work as follows:

IF a corresponding XDG environment variable exists THEN use it's location according to the spec.
ELSE use the current behavior / locations in the .bun/ directory.

Disagree with you as this behavior is still not specs compliant. Programs should use user's XDG envs if they are set and fall back to default values when they are not set. Program can still use user's $HOME dot dir if it exists, but only for backwards compatibility and this is not about spec itself at all.

This behavior I am talking about is described in document you are sourcing:

$XDG_DATA_HOME defines the base directory relative to which user-specific data files should be stored. If $XDG_DATA_HOME is either not set or empty, a default equal to $HOME/.local/share should be used.

Could you please update description of the issue according to the spec?

Software must not force users to define environment variables in order to keep their $HOME clean. And AFAIK these env variables are not even set in most distributions, so if it's going to be implemented this way, it will affect only really small percentage of Linux/BSD users, and only users who care and know about spec, and try to force apps to follow it. This is very important.


It's sad bun did not included this in 1.0 as now it's not as easy to implement with backward compatibility support.
There are a lot of examples projects adopting XDG specs with backwards compatibility, you can see "Supported" tables on this page: https://wiki.archlinux.org/title/XDG_Base_Directory#Supported
There are also links with discussions and version/commit which implemented spec, it may be useful for anyone who decides to contribute on this.

@jtrv
Copy link
Author

jtrv commented Sep 12, 2023

@ZerdoX-x thank you, I've updated the issue per ju1ius's comment as well

@Electroid Electroid changed the title [Feature Request]: Follow XDG Base Directory Specification Follow XDG Base Directory Specification Oct 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants