I’d like to start a discussion around whether swift-configuration, or a similar mechanism, could be supported directly in Package.swift manifests in the future.
Current practice
Today we mostly rely on environment variables, which means duplicating the same helper logic in every package. For example:
func envEnable(_ key: String, default defaultValue: Bool = false) -> Bool { guard let value = Context.environment[key] else { return defaultValue } if value == "1" { return true } else if value == "0" { return false } else { return defaultValue } }
This works, but it’s verbose and not very maintainable when used across multiple packages.
Use cases
Conditionally enabling dependencies or features (e.g. CI vs local builds).
Centralizing configuration in JSON/YAML or env vars instead of hardcoding values in multiple manifests.
Drive build options or code generation from a shared config.
Why it’s not possible today
Manifests are restricted to PackageDescription and cannot import other libraries.
SwiftPM requires deterministic resolution; external config or I/O would break reproducibility.
This constraint is fine for tagged release of remote package. But it makes pure local package a lot harder to use and manage.
Security and bootstrapping concerns if a manifest depends on a package to configure itself.
From my perspective, any use of environment variable in a Package.swift is an indication of a missing feature in SwiftPM. I very much favour the idea of removing usage of environment variables in Package.swift. This is one aspect of the Quality Vision document (yet to be posted) I have for Swift Package Manager.
Here's a use case I would like to see supported:
I build at desk using swift build
the CI does a swift build with it's own configuration, and which generates some sort of metadata file
The CI build fails
To reproduce the same environment as CI at-desk, I could so swift build <additional args> where <additional args> would pass it the metadata file. The CI failure is reproducible at-desk.
Perhaps the SwiftPM team should survey the community on what they're using env variables in manifests for now, would provide a good list of config options that are so important that they're crowbarring them in already.
This is definitely something I want to address. It’s really unfortunate people have had to resort to using environment variables in their manifests to implement configurability, including SwiftPM itself. The distance between where envvars are defined and where they are used in the manifest is too far and error prone. I’d like to make this tighter and more obvious. There are a couple of things off the top of my head we could do.
First allow for -D options like CMake does so that at least the configuration is done on the SwiftPM command line. I’d certainly be open to more feature rich approaches such as those offered by swift-configuration also. That will require the package manifest be able to import from dependencies, but I have ideas there as well.
The second thing I want to do is make .when conditions richer. You should able to express conditions based on configuration right on the thing you want to be conditional. Something like:
which would then be activated by swift build -DENABLE_MYCONFIG .
That’s just one option. Would love to hear more ideas on this. I am working towards a SwiftPM Vision document where we as community would like to take SwiftPM to make it easier to use everywhere :). Ideas like this should definitely be a part of that.