Skip to content

Support global mirror configuration #9947

@samuelmurray

Description

@samuelmurray

Description

Dependency mirroring in SPM is a great tool for corporate environments where certain public URLs are not accessible. The feature was recently extended to support binary target, #9647.
In the original proposal, the prospect of having a global configuration (stored in ~/.swiftpm) was discussed

We considered adding a global configuration file for storing the mirror information. A global file could be convenient for some users, but it can also cause "gotcha" moments if the file is used when it shouldn't be used and vice versa. Users who understand this risk can export the SWIFTPM_MIRROR_CONFIG in their shell to achieve a similar effect.

While I can respect the intent, I think the benefit of allowing a global config file outweighs the downsides. We can make a comparison to package registries. While the features are distinct, they have a large overlap in what issues they solve. In the proposal for registries the concept of a global config was discussed in length, with no obvious downsides listed.

The user can pass the --global option to the set or unset subcommands to update the user-level configuration file located at ~/.swiftpm/configuration/registries.json. [...]
https://github.com/swiftlang/swift-evolution/blob/main/proposals/0292-package-registry-service.md#global-registry-configuration

This means that we can have <project>/.swiftpm/configuration/registries.md, <project>/.swiftpm/configuration/mirrors.json, ~/.swiftpm/configuration/registries.md, but not ~/.swiftpm/configuration/mirrors.md.

As the support for mirrors is extended (for example the support for binary targets), and SPM is more widely used, the need for allowing global configuration increases. Having to add the same mirror configuration to each repository as cumbersome, and arguably, that poses a higher risk of "gotcha" moments where the configuration differs between repositories, if the configuration is updated in some project but not in another. Ultimately, it should be up to the users of Swift to decide if a local or global configuration is more appropriate in their environment. While some of this can be mitigated by using the SWIFTPM_MIRROR_CONFIG environment value, as suggested by the proposal, this has the downside of not allowing for local overrides of global configuration, and also doesn't work well with GUI application such as Xcode. Although not directly tied to the feature request, an added bonus is that the global configuration could work for .xcodeprojects in Xcode, for which local SPM configuration is difficult to use, if at all possible.

As a side-note, many other package managers support global configuration for similar features. ~/.m2/settings.xml for Maven, ~/.npmrc for npm, and ~/.nuget/NuGet/NuGet.Config for NuGet, to name a few.

Proposed change

  • Allow for global configuration of mirrors in ~/.swiftpm/configuration/mirrors.md, analogous to global configuration of registries.
  • Add --global flag to swift package config set-mirror, get-mirror and unset-mirror for modifying and inspecting the global configuration, analogously to global configuration of registries.
  • Modify the package resolution to use any global configuration, if it exist, with local configuration having higher priority.
  • The environment variable SWIFTPM_MIRROR_CONFIG does not affect the path to the global config, but only the local.

Expected behavior

No response

Actual behavior

No response

Steps to reproduce

No response

Swift Package Manager version/commit hash

Swift Package Manager - Swift 6.3.0

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

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions