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

~/.swiftpm config, cache to follow the XDG base dir spec #6204

Closed
marcoSven opened this issue Mar 1, 2023 · 17 comments · Fixed by #7386
Closed

~/.swiftpm config, cache to follow the XDG base dir spec #6204

marcoSven opened this issue Mar 1, 2023 · 17 comments · Fixed by #7386

Comments

@marcoSven
Copy link

marcoSven commented Mar 1, 2023

Description

Conform to the XDG Base Directory spec with no symlinks from the "$HOME" directory.

I assume the purpose of these symlinks is discoverability.

An alternative solution would be to provide an option to not create the symlinks in the "$HOME" directory e.g. env variable

Expected behavior

No symlinks "~/.swiftpm" in the home directory

Actual behavior

No response

Steps to reproduce

No response

Swift Package Manager version/commit hash

No response

Swift & OS version (output of swift --version && uname -a)

macOS
Linux - all distributions
windows

@MaxDesiatov
Copy link
Member

Could you clarify what specific OS and if it's Linux, what distributions do you expect this to be applicable on?

@marcoSven
Copy link
Author

Apple Swift version 5.7.2 macOS 13.1

@MaxDesiatov
Copy link
Member

To my understanding this XDG spec is Linux-specific, how is it related to macOS then?

@marcoSven
Copy link
Author

My main intention is to prevent the creation of symlinks in the home directory, as a macOS user they are pointless to me.

What is the purpose of these symlinks? I assumed they are for discoverability and if that is the case I am suggesting a cross-platform solution, my impression is that XDG spec are widely adopted.

@lordzsolt
Copy link
Contributor

lordzsolt commented Mar 4, 2023

Here's a quick overview of what the XDG structure means:
https://wiki.archlinux.org/title/XDG_Base_Directory

The gist of it is, people (myself) don't want their $HOME directory cluttered with a bunch of useless folders, one of which is .swiftpm.
Additionally, some people like to version control these directories, especially the XDG_CONFIG_HOME, because this makes it dead simple to migrate them to another machine. Since all config files are under this folder.


npm for example exposes a couple of variables, to configure where config and cache files are stored:

export npm_config_userconfig=$XDG_CONFIG_HOME/npm/config
export npm_config_cache=$XDG_CACHE_HOME/npm

A further example, this is how bundler complied with XDG specs:
rubygems/bundler#6024


The request would to have SPM do the same.

Firstly, instead of hardcoding the dotfile location, allow the user to control this through some env variable:

extension FileSystem {
    /// SwiftPM directory under user's home directory (~/.swiftpm)
    public var dotSwiftPM: AbsolutePath {
        get throws {
            // Read some ENV variable, if defined, use that
            // Else fallback to default behavior
            return try self.homeDirectory.appending(component: ".swiftpm")
        }
    }

This would already please the vast majority of people requesting this feature.


Secondly, if you would like to fully comply with the XDG specs, the cache, config, security and cross-compilation directories should be individually configurable, through some ENV variables, example:

export SWIFT_PM_CONFIG=$XDG_CONFIG_HOME/swiftpm
export SWIFT_PM_CACHE=$XDG_CACHE_HOME/swiftpm
// Unsure what dotSwiftPMSecurityDirectory and swiftPMCrossCompilationDestinationsDirectory should be.
// Probably DATA?

Then, FileSystem+Extensions.swift would read these SWIFT_PM_*environmental variables, and use them if they are defined. If not define, fallback to default behavior.


Considering FileSystem+Extensions.swift already abstracts these paths, it should be trivial to use some ENV variables there.

I would be glad to submit a PR, as soon as we can agree on the details.

@lordzsolt
Copy link
Contributor

@MaxDesiatov Any thoughts on my comment?

@MaxDesiatov
Copy link
Member

MaxDesiatov commented Mar 26, 2023

I am suggesting a cross-platform solution, my impression is that XDG spec are widely adopted.

Would you provide some confirmation that macOS or Windows adopt XDG? I'm not sure that's the case, thus I'm not sure how this would be cross-platform. From that perspective, it's also unclear to me why this is filed as a bug report against macOS.

@marcoSven
Copy link
Author

marcoSven commented Mar 26, 2023

I don't think or at least I am not aware of an OS adoption of XDG. I meant that users adopting it, please see the more detailed comment from @lordzsolt above.

This ticket was intended as a feature request, it is also currently labeled as a feature request (enhancement).

Could you clarify what specific OS and if it's Linux, what distributions do you expect this to be applicable on?

I realize that my response is not correct, I am a macOS user but this request should be for all supported OS. I updated this now.

Maybe we shouldn't discuss the XDG topic. The main ask of this ticket is how can we prevent the creation of symlinks in the $HOME directory or how can we configure the location where these symlinks are created. I believe users would like the option to configure the locations with env variables. Please see the example from @lordzsolt.

Hope this clarifies the ask.

@lordzsolt
Copy link
Contributor

@MaxDesiatov Have you had a change to review my comment here?

I think it answers your question.

@alichtman
Copy link

Would you provide some confirmation that macOS or Windows adopt XDG?

The XDG Base Dir Spec is not an OS-level spec. It's a spec aimed at solving the problem explained above: "As a user, I don't want my home directory filled with random configuration files for programs I have installed." Instead of having every application author decide on their own storage method, XDG provides a standardized way to organize configs, stored data, and cache data.

The TL;DR is:

  1. Configs go in $XDG_CONFIG_HOME (which defaults to ~/.config)
  2. Cache data goes in $XDG_CACHE_HOME (which defaults to ~/.cache)
  3. Stored data goes in $XDG_DATA_HOME (which defaults to ~/.local/share)

On my machine, ~/.swiftpm contains the following folders:

~/.swiftpm via 💎 v2.5.1 took 34ms
03:36:10 PM ➜ sw_vers
ProductName:		macOS
ProductVersion:		13.4
BuildVersion:		22F66

~/.swiftpm via 💎 v2.5.1 took 1ms
03:35:43 PM ➜ ls
 cache ⇒ /Users/alichtman/Library/Caches/org.swift.swiftpm
 configuration ⇒ /Users/alichtman/Library/org.swift.swiftpm/configuration
 security ⇒ /Users/alichtman/Library/org.swift.swiftpm/security

~/.swiftpm/cache should probably live at $XDG_CACHE_HOME/swiftpm/cache.
~/.swiftpm/configuration should probably live at $XDG_CONFIG_HOME/swiftpm/configuration
~/.swiftpm/security should probable live at $XDG_DATA_HOME/swiftpm/security.

@MaxDesiatov

@SDGGiesbrecht
Copy link
Contributor

As a user, I don't want my home directory filled with random configuration files for programs I have installed.

Absolutely.

I assume the purpose of these symlinks is discoverability.

No. Actually, the symlinks are there because the files themselves formerly (and erroneously) lived there. Since older toolchains looked for them there, mutual compatibility between toolchains required a transition period where the old and new paths were unified by symlinks. Since that transitional code is marked for removal in the version following 5.6, I assume in was simply forgotten and that a PR to clean it out and eliminate the symlinks would very likely be accepted. The transition work started because everyone agrees with you about the files not belonging in ~.

Aside from the deprecated symlinks, SwiftPM derives its paths from Foundation, which has respected XDG on relevant platforms since at least 2017. Foundation’s abstractions use XDG on platforms where it makes sense, but not on those where it is at odds with the operating system. On macOS, Foundation adheres to App Store standards. For example, the real cache directory will automatically be cleaned up periodically by the operating system, whereas an arbitrary custom one will not. Foundation roughly cascades by doing what the platform wants (e.g. on macOS) and then for platforms which defer such responsibilities, it asks the user’s preferences through mechanisms like XDG (e.g. on Linux). So if you are using a platform where XDG applies (i.e. one that does not have native instructions for developers to follow), and your environment variables are being ignored, then please report the details in a fresh issue. But the discussion so far seems to only be about macOS, where adoption is unlikely and any attempt to convince otherwise would have to happen over in the Foundation repository anyway.

@alichtman
Copy link

alichtman commented Aug 28, 2023

I suppose I should clarify: I don't actually care about the XDG spec being followed on macOS. I care about not having this directory in $HOME. XDG is just a means to an end.

I only found this issue because one day ~/.swiftpm showed up. If it disappears from $HOME, I'm cool with that

@marcoSven
Copy link
Author

I don't actually care about the XDG spec being followed on macOS. I care about not having this directory in $HOME. XDG is just a means to an end.

Same here

@andrewcrook
Copy link

andrewcrook commented Nov 16, 2023

I personally use Foundation defaults for Native macOS Apps eg ~/Library etc .
custom settings should be through the GUI, plist and/or defaults command.

Anything, command line in Darwin, is usually ported from Linux or BSD I use XDG dirs.
To me it makes sense to keep the command line shell environments separate.
if you wanted them to be the same as foundation then you still have that option by setting XDG variables to the same directories.

Usually applications using XDG have an ordered list of default directories usually something like XDG_CONFIG_HOME/name/config_file then $HOME/.config_file and possibly depending on usage you may have global dirs for user and globals for all users e.g under /etc

It also makes sense to be able to override XDG and program defaults with a custom environment variables for individual configurations and custom development environments. or at least change the location of the main config file then to be able to configure other paths within that file.

@sdavids
Copy link

sdavids commented Jan 25, 2024

Since that transitional code is marked for removal in the version following 5.6, I assume in was simply forgotten and that a PR to clean it out and eliminate the symlinks would very likely be accepted.

Is there an open issue for this cleanup?

@lordzsolt
Copy link
Contributor

lordzsolt commented Mar 3, 2024

I assume the purpose of these symlinks is discoverability.

No. Actually, the symlinks are there because the files themselves formerly (and erroneously) lived there. Since older toolchains looked for them there, mutual compatibility between toolchains required a transition period where the old and new paths were unified by symlinks. Since that transitional code is marked for removal in the version following 5.6, I assume in was simply forgotten and that a PR to clean it out and eliminate the symlinks would very likely be accepted.

When reading the code comment you linked to, as well as the other temporary 5.6 migration in the same file, my impression is that the future plan is to have the files stored in the idiomatic location (under ~/Library) but still keep the symlinks in the user's home directory.

The migration code, which should be cleaned up just migrates from:

  • /Users/<user>/Library/org.swift.swiftpm -> /Users/<user>/Library/org.swift.swiftpm/configuration on macOS
  • ~/.swiftpm/config -> ~/.swiftpm/configuration on Linux

The code which is outside the temporary 5.6 migration comment, still creates the symlinks in ~/.swiftpm.

MaxDesiatov added a commit that referenced this issue Mar 3, 2024
### Motivation:

As discussed in #6204, users would like to have a clean home directory.
And in the discussions following the merge of #3430, it seems there is a
willingness to adhere to the XDG spec, and support `~/.config/swiftpm`.

### Modifications:

If the `XDG_CONFIG_HOME` environmental variable is defined, use
`$XDG_CONFIG_HOME/swiftpm` as the root `dotSwiftPM` directory.

### Result:

The symlinks that were previously stored in `~/.swiftpm` are now stored
in `$XDG_CONFIG_HOME/swiftpm` when this variable is defined, therefore
not cluttering the home directory of users.

Closes #6204

---------

Co-authored-by: Max Desiatov <m_desiatov@apple.com>
@sdavids
Copy link

sdavids commented Mar 4, 2024

Maybe some documentation somewhere?

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

Successfully merging a pull request may close this issue.

7 participants