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

Support for using ~/.config on Mac for command line apps #47

Closed
lavifb opened this issue Dec 7, 2018 · 40 comments
Closed

Support for using ~/.config on Mac for command line apps #47

lavifb opened this issue Dec 7, 2018 · 40 comments

Comments

@lavifb
Copy link

lavifb commented Dec 7, 2018

While not the official Apple sanctioned place for config files, the standard on the command line for MacOS tends to be using the Linux style ~/.config for config files. Can we add support for using ~/.config on Mac?

There is more discussion here:
https://github.com/rust-lang-nursery/cli-wg/issues/7#issuecomment-439223000

@cjbassi
Copy link

cjbassi commented Feb 11, 2019

Do cli apps on Mac also use the XDG data folder (~/.local/share/) and cache folder (~/.cache/)? If so, I'm wondering if it would be better to instead use https://github.com/whitequark/rust-xdg for command line applications at least for Base Dirs and Project Dirs, and use directories-rs for gui applications (assuming cli apps on Windows use xdg too).

@lavifb
Copy link
Author

lavifb commented Feb 11, 2019

Yeah that definitely works for Mac but then it doesn’t for Windows. (I don’t have a windows machine but as far as I can tell XDG is not the standard there)

@lavifb
Copy link
Author

lavifb commented Feb 11, 2019

For instance, Neovim does not use XDG on windows
https://neovim.io/doc/user/starting.html#vimrc

@FranklinYu
Copy link

FranklinYu commented Mar 31, 2019

I want to add my answer on Stack Overflow to the reasons of using ~/.config for CLI.

If we don’t want to break compatibility, how about providing a struct CliProjectDirs?

@retep998
Copy link

assuming cli apps on Windows use xdg too

Nothing on Windows uses XDG.

@soc
Copy link
Collaborator

soc commented Mar 31, 2019

I will not support this:

Either we also change cache folders and therefore force everyone to add exclusions to macOS' backup software (Library/Caches is excluded, .cache isn't) or spread the folders into completely different places in the filesystem.

As a general advice for macOS devs: If you are developing on their platform, do what the platform owners tell you. They are the lords, you are the share-croppers.

@soc soc closed this as completed Mar 31, 2019
@soc
Copy link
Collaborator

soc commented Mar 31, 2019

I closed this, but anyone should feel free to reopen if that person has new information.

@FranklinYu
Copy link

If I manually set the environment variable $XDG_CONFIG_HOME would it be respected on macOS?

@lilyball
Copy link

lilyball commented Jan 9, 2020

Cross-platform CLI apps that write to ~/Library on macOS feel wrong to me. I would really like my CLI apps to use ~/.config even on macOS. Using ~/Library/Caches is much more reasonable since, as a user, I don't have to care about that, and it won't get backed up by Time Machine. But configuration and user data should go into the appropriate CLI location.

@DanCardin
Copy link

It feels like respecting a set value for XDG_*_HOME in all cases would be ideal, and then falling back to the existing directories when unset.

While I would probably opt to not set XDG_CACHE_HOME because i don't care and thus get the existing behavior (but if someone wants to opt into a specific spot, go for it), I very much do want to set XDG_CONFIG_HOME (as much of the point of a standard location like is so that I can port my config folder to some other machine)

@FranklinYu
Copy link

It feels like respecting a set value for XDG_*_HOME in all cases would be ideal, and then falling back to the existing directories when unset.

Agree. When users set XDG_CONFIG_HOME themselves, it’s a clear indicator that this user wants configuration to be placed there. We should assume that user knows what he is doing, instead of making the decision for them.

@lilyball
Copy link

lilyball commented Mar 9, 2020

I would be very surprised if a program behaved differently with XDG_CONFIG_HOME=$HOME/.config versus XDG_CONFIG_HOME being unset.

@soc
Copy link
Collaborator

soc commented Mar 9, 2020

If I manually set the environment variable $XDG_CONFIG_HOME would it be respected on macOS?

No, it won't.

@cjbassi
Copy link

cjbassi commented Aug 30, 2020

Suggestion: Add an argument to the ProjectDirs constructor called use_xdg_on_macos: bool so that users can specify if they want that feature or not. That way both GUI and CLI programs using directories-rs can work as expected since users can specify which option they want based on the type of program they are creating.

@OJFord
Copy link

OJFord commented Feb 23, 2021

As a general advice for macOS devs: If you are developing on their platform, do what the platform owners tell you. They are the lords, you are the share-croppers.

OK, so if they tell me that their $XDG_CONFIG_HOME is at /Users/lord/.config, I should use that. Except, with dirs-dev, I can't.

I am a macOS 'platform owner', as well as Linux, and my $XDG_CONFIG_HOME = $HOME/.config (i.e. explicitly, not the unset fallback per spec) on both.

I can.. understand wanting to use Library or whatever if nothing's specified, but if $XDG_* are actually present in the environment, using Library is knowingly doing what the user doesn't want.

(By the way, I found etcetera, which supports different 'strategies' for choosing base directories, such as an Xdg strategy, and the default is what we're all after - something Windowsy on Windows, and XDG on everything else. (But even if that default changes, the Xdg strategy is there and could be used even on Windows if you wanted.))

@poliorcetics
Copy link

The justification for refusing this feels very wrong to me. Apple is not all-knowing and users that are setting XDG_* variables can be expected to know what they are doing and/or use CLI tools for which they want to save the configuration files to a VCS repo.

I can understand the default case not respecting XDG_* vars since it's not recommended behaviour but a new module xdg that respects it would be nice, especially for CLI apps.

@poliorcetics
Copy link

See dirs-dev/dirs-rs#40

@soc
Copy link
Collaborator

soc commented Apr 25, 2022

Apple is not all-knowing

Not all-knowing, but omnipotent on their hardware. They call the shots on their devices. That's the bargain you make when you buy something from them.

@OJFord
Copy link

OJFord commented Apr 25, 2022

@soc Apple does not tell you not to use environment variables to configure where data is stored on 'their' devices, that's absurd.

@soc
Copy link
Collaborator

soc commented Apr 25, 2022

@OJFord Apple defines where various kinds of data are stored. The rules do not contain an "in case you want to make up your on conventions ..." section.

@OJFord
Copy link

OJFord commented Apr 25, 2022

It defines defaults and standard practices.

Sane CLI/TUI and other programmer tools in particular respect XDG if used.

Hell, many use the $HOME or $HOME/.config without the option; respecting neither Apple nor XDG's standard.

I have absolutely no idea why you would think it makes sense togo out of your way to ignore (based on the platform) an environment variable explicitly set by the user. Is Apple paying you to uphold such ideals?

I don't currently have any macOS systems, so I don't care that much, I just think this is absurd, and I wouldn't use this crate for my own tools on that basis; not wishing it on any Mac users I may have.

Sharparam added a commit to Sharparam/facti that referenced this issue Aug 19, 2023
The directories crate doesn't use XDG on macOS, which is apparently
the preferred way for CLI apps to store configuration.

See:
dirs-dev/directories-rs#47
dirs-dev/directories-rs#62
@sdavids
Copy link

sdavids commented Nov 7, 2023

Either we also change cache folders and therefore force everyone to add exclusions to macOS' backup software (Library/Caches is excluded, .cache isn't) or spread the folders into completely different places in the filesystem.

You can address that issue by setting an extended attribute after you create the directory:

xattr -w com.apple.metadata:com_apple_backup_excludeItem \
  com.apple.backupd "${XDG_CACHE_HOME}"

xattr -w com.apple.metadata:com_apple_backup_excludeItem \
  com.apple.backupd "${XDG_RUNTIME_DIR}"

@soc
Copy link
Collaborator

soc commented Nov 9, 2023

@sdavids This library does – by design – neither create directories nor check whether they exist. Mutating extended attributes is not going to happen.

@adriangalilea
Copy link

I do understand the rationale of @soc as much as I hate the outcome.

Every time I see ~/Library/Application Support I get triggered: absurdly long names, uppercase, spaces in between that cause all sort of annoying scaping headaches...

I legit don't care if my computer crashes and burns and/or all my life's work's get's deleted as long as I can avoid using MacOS designated default dirs, I would take all the blame that came with it, but of course doing it as a Library that aims to do one thing would mean having to deal with all those user errors constantly, so I can't blame @soc for not wanting to cross that path, after all, is a MacOS flaw, and we should point our forks towards that porch. But of course nothing would change, just like it still has the worst Window Management on all the OS's available.

But while I respect the decision, and judging by the amount of petitions, why not allow for an env var that bypassed the OS detection? Wouldn't it be good for debugging too?

The only alternative would be switching to etcetera, right?

@DanCardin
Copy link

I have personally switched to etcetera over this, and i think it works perfectly well, with a nice API.

The main "problem" is, for whatever reason, new tools seem to tend to choose this lib by default, not realizing the side effect; then receive bug reports about the macos behavior afterward (like nushell). And then either manually work around it, like i've seen a few tools do, or else feel stuck because it would result in wide ranging breaking changes to switch (like nushell, who's issue has been open for 5 years).

At the same time, this library is farly clear in the readme about what it provides, and it's not in its own best interests to specifically call out this behavior any more clearly...

@soc
Copy link
Collaborator

soc commented Aug 9, 2024

Every time I see ~/Library/Application Support I get triggered: absurdly long names, uppercase, spaces in between that cause all sort of annoying scaping headaches...

Can't you create a symlink if that's your issue?

@adriangalilea
Copy link

adriangalilea commented Aug 9, 2024

Can't you create a symlink if that's your issue?

Nope, I share my dotfiles on mac and linux, in fact my ~ is a git repo. So no, I use XDG paths for everything I use and favor software that honors XDG envs even on mac. Went as far as to create a golang app just for being able to set XDG dirs on linux and mac and my dotfiles are also public which I use in both systems atm. I'm very happy with this setup.

@soc
Copy link
Collaborator

soc commented Aug 9, 2024

Not sure I get that – if you symlink ~./config to ~./Library/Application Support your tool wouldn't even have to care about macOS having different rules, would it?

I'd imagine the bigger issue you have is that the application naming rules are different between Linux and macOS, i. e. your application FooBar uses a foobar directory on Linux, but com.something.FooBar on macOS.

Do your tool use some kind of mapping file that translates between naming on Linux and naming on macOS?

@ssokolow
Copy link

ssokolow commented Aug 9, 2024

I think the "in fact my ~ is a git repo." part is the key detail.

It sounds like they don't go with my "~/.profile_repo is a git repo and ~/.profile_repo/install.py sets up/updates symlinks" approach.

(An approach I take because it keeps git diff or git gui limited to only the files I've chosen to version without needing to use .gitignore to blacklist every single directory/file that I don't want to show up.)

@adriangalilea
Copy link

adriangalilea commented Aug 9, 2024

I think the "in fact my ~ is a git repo." part is the key detail.

Yup

It sounds like they don't go with my "~/.profile_repo is a git repo and ~/.profile_repo/install.py sets up/updates symlinks" approach.

Not sure I got that part

(An approach I take because it keeps git diff or git gui limited to only the files I've chosen to version without needing to use .gitignore to blacklist every single directory/file that I don't want to show up.)

You should look into stow then. I essentially .gitignore *and then whitelist things with !foo

I don't do any mapping, just all my stuff uses XDG dire. And ~ is literally a repo which I just use like you would any other repo so my config is versioned, backed up, with 0 dependenciescies, across all my unix systems. The only thing is that I need to install the software differently but I'm also automating that up. i just run 2 commands and my system is ready to go weather it be a rpi, vps, or fresh mac install. Then I git pull at the start of my .zshrc so everything is always up to date when I login to the system. Without any extra steps. And all my aliases, functions and cli tools are there.

@soc
Copy link
Collaborator

soc commented Aug 9, 2024

I don't do any mapping, just all my stuff uses XDG dire. And ~ is literally a repo which I just use like you would any other repo so my config is versioned, backed up, with 0 dependenciescies, across all my unix systems.

So your whole scheme not only requires that the applications you use are poorly ported to macOS, but also that the application authors never improve on that? 😦

@DanCardin
Copy link

So your whole scheme not only requires that the applications you use are poorly ported to macOS, but also that the application authors never improve on that? 😦

you're putting a lot of assumption and assertion about how macos CLI applications should and should not act, with (imo) very little evidence to support that things should act that way, and no other way.

Swiftlang's 1st party package manager supports XDG on macos. Also homebrew does, as an example of a piece of CLI software (originally) explicitly designed for macos. As do numerous other apps, both CLI and otherwise that have gotten feedback from enough people to decide to support it.

also nushell/nushell#893 (comment)

That said, I'm pretty surprised to see this has remained open for 5 years when the solution is so simple, especially considering the resistance to changing it seems to be on ideological grounds rather than practical ones.

I'm also puzzled by those quoting the macOS Library Directory Details, which say this about Application Support:

Contains all app-specific data and support files. These are the files that your app creates and manages on behalf of the user and can include files that contain user data.

It may be a little bit subtle to those unfamiliar with macOS development, but the use of "app" is very specific here, and nushell is not an app. (If it was, it would have a bundle ID, it would be installed in /Applications, etc.)

The File System Basics document that has also been referenced says the same thing:

An app might use this directory to store a modifiable copy of resources contained initially in the app’s bundle. A game might use this directory to store new levels purchased by the user and downloaded from a server.

All content in this directory should be placed in a custom subdirectory whose name is that of your app’s bundle identifier or your company.

Again, note the references to a bundle and a bundle identifier — these are things that nushell does not have because nushell isn't an app!

and

"These are the files that your app creates and manages on behalf of the user" seems more important to me than bundle id, config files are managed directly by the user and not "on behalf of the user" ?

@soc
Copy link
Collaborator

soc commented Aug 9, 2024

Ok, that argument.

@ssokolow
Copy link

ssokolow commented Aug 9, 2024

Yeah. By that reasoning, it sounds like ~./Library/Application Support/<Bundle ID> is the counterpart to Flatpak's ~/.var/app/<App ID> and nobody argues that non-Flatpak applications should put their data under ~/.var/app/.

@ssokolow
Copy link

ssokolow commented Aug 9, 2024

You should look into stow then. I essentially .gitignore *and then whitelist things with !foo

Perhaps, but I generally prefer not to add new dependencies when I'm doing OK with what I have.

I don't do any mapping, just all my stuff uses XDG dire. And ~ is literally a repo which I just use like you would any other repo so my config is versioned, backed up, with 0 dependenciescies, across all my unix systems. The only thing is that I need to install the software differently but I'm also automating that up. i just run 2 commands and my system is ready to go weather it be a rpi, vps, or fresh mac install. Then I git pull at the start of my .zshrc so everything is always up to date when I login to the system. Without any extra steps. And all my aliases, functions and cli tools are there.

I use Ansible playbooks inside my repo for that. Bear in mind that my repo isn't really something I use as a roaming profile... more a template for bringing up user profiles on new machines with some dipping sauce for easing keeping it up to date, plus some Ansible playbooks for installing the system images, that gets overlaid locally with the machine-specific or sensitive bits and then persisted via backups.

(Heck, I had to restore from my playbook and a whole-$HOME nightly rsync backup a few months ago. I found it so irritating to wait for all that apt-get install-ing and flatpak install-ing and rsync-ing that I now boot via ZFSBootMenu (using the trick from their manual to hot-spare mirror /boot/efi using mdraid), have one of my tiers of backup being an hourly ZFS snapshot sync to a ZRAID mirrored pair, and am preparing to install the RMA'd NVMe drive as a ZRAID mirror for the replacement NVMe drive that I rush-ordered so I'd only have to live off my laptop for two days. With ZFS native snapshot sync, it took under 2 hours to do a from-scratch backup of my NVMe boot drive to the 7200 RPM "bulk drive" pair and it should take under 2 hours to go back in the other direction if both drives in the soon-to-be-mirrored-pair fail.)

@soc
Copy link
Collaborator

soc commented Aug 9, 2024

Yeah.

It's just that I heard variations of "here is my very specific reading of rules such that mysteriously the subset of applications I care about is exempt" ... for more than 10 years.

This is the library for the 99.8% of people who either want things to work consistently or do not want to care because all things work consistently.

It's not the library for the 0.2% of people that have to have their own special carve-out from the standard approach and subsequently ruin things for everyone else.

@ssokolow
Copy link

ssokolow commented Aug 9, 2024

I find it convincing that Swift shares that interpretation of how the Apple guides repeatedly refer to the application's bundle ID.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests