Utilities and templates for Swift Package Manager manifest files (Package.swift).
A powerful environment variable manager designed for use in Swift Package Manager manifests, providing:
- Domain-based variable lookup: Automatically searches for domain-prefixed environment variables
- Multiple value types: Supports
Bool,Int, andString - Debug output: Prints environment variable resolution for better visibility during builds
- Clean API: Simplified environment variable usage with type-safe defaults
- Temporary domains: Use
withDomain()for scoped environment variable lookups - Configurable fallback: Control whether to fall back to raw key names with
includeFallbackToRawKey
Copy the EnvManager implementation directly into your Package.swift file, or use the sync script to keep it updated.
Copy the contents of Templates/EnvManager.swift.template into your Package.swift file.
Add markers to your Package.swift:
// swift-tools-version: 6.1
import Foundation
import PackageDescription
/* GENERATED BY SPMManifestTool BEGIN */
/* DO NOT EDIT */
/* GENERATED BY SPMManifestTool END */
// Rest of your Package.swiftThen run the sync script:
cd /path/to/SPMManifestTool
./Scripts/sync_env_manager.sh ../YourProject// By default, searches only: MYPROJECT_DEBUG
let debug = envBoolValue("DEBUG", default: false)
// Enable fallback to also search raw key: DEBUG
EnvManager.shared.includeFallbackToRawKey = true
let debugWithFallback = envBoolValue("DEBUG", default: false)
// Now searches: MYPROJECT_DEBUG, DEBUG
// Disable domain search for system variables
let isSPI = envBoolValue("SPI_BUILD", default: false, searchInDomain: false)Environment variable format:
"1"→true"0"→false- Any other value → falls back to default
// By default, searches only: MYPROJECT_TARGET_RELEASE
let releaseVersion = envIntValue("TARGET_RELEASE", default: 2024)
// Enable fallback to also search: TARGET_RELEASE
EnvManager.shared.includeFallbackToRawKey = true
let releaseWithFallback = envIntValue("TARGET_RELEASE", default: 2024)// With default value (searches only domain-prefixed versions)
let customPath = envStringValue("CUSTOM_PATH", default: "/default/path")
// Optional (no default)
let optionalPath = envStringValue("OPTIONAL_PATH")
// Returns nil if not found
// Enable fallback to search raw key as well
EnvManager.shared.includeFallbackToRawKey = true
let pathWithFallback = envStringValue("CUSTOM_PATH", default: "/default/path")When searchInDomain: true (the default), EnvManager searches for environment variables in this order:
DOMAIN1_KEYDOMAIN2_KEY(if multiple domains are registered)KEY(only ifEnvManager.shared.includeFallbackToRawKeyistrue)
For example, with domain "MyProject" and key "DEBUG":
With includeFallbackToRawKey = false (default):
- Checks
MYPROJECT_DEBUG - Falls back to default value
With includeFallbackToRawKey = true:
- Checks
MYPROJECT_DEBUG - Checks
DEBUG - Falls back to default value
By default, includeFallbackToRawKey is false, meaning EnvManager only searches domain-prefixed environment variables. You can enable fallback to raw key names globally:
// Default behavior - searches only: MYPROJECT_DEBUG
let debug = envBoolValue("DEBUG", default: false)
// Enable fallback globally
EnvManager.shared.includeFallbackToRawKey = true
// Now searches: MYPROJECT_DEBUG, DEBUG
let debugWithFallback = envBoolValue("DEBUG", default: false)
// Disable for specific lookups using searchInDomain: false
let systemVar = envBoolValue("SYSTEM_VAR", default: false, searchInDomain: false)
// Searches only: SYSTEM_VAR (ignores domains entirely)This is useful when you want strict control over environment variable scoping. Set includeFallbackToRawKey = true if you want more flexible lookups that fall back to unprefixed keys.
Use withDomain() to temporarily add a domain for specific lookups:
let agVersion = EnvManager.shared.withDomain("TEMP") {
envIntValue("TARGET_RELEASE", default: 2024)
}
// This searches in other registered domains and other TEMP_TARGET_RELEASE// swift-tools-version: 6.1
import Foundation
import PackageDescription
/* EnvManager code */
// Register project domain
EnvManager.shared.register(domain: "MyProject")
// Enable fallback to raw key names for convenience
EnvManager.shared.includeFallbackToRawKey = true
// Query environment variables
let development = envBoolValue("DEVELOPMENT", default: false)
let releaseVersion = envIntValue("TARGET_RELEASE", default: 2024)
// Use them in your package configuration
var swiftSettings: [SwiftSetting] = [
.swiftLanguageMode(.v5),
]
if development {
swiftSettings.append(.unsafeFlags(["-warnings-as-errors"]))
}
let package = Package(
name: "MyProject",
products: [
.library(name: "MyProject", targets: ["MyProject"]),
],
targets: [
.target(
name: "MyProject",
swiftSettings: swiftSettings
),
]
)EnvManager automatically prints debug information during package resolution:
[Env] MYPROJECT_DEVELOPMENT no set -> false
[Env] MYPROJECT_TARGET_RELEASE not set -> 2024(default)This helps you understand which environment variables are being used and their values.
- Swift 6.1 or later
MIT License. See LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.