Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ jobs:
linux_env_vars: '{"ENABLE_ALL_TRAITS":"1"}'
linux_5_10_enabled: false
linux_6_0_enabled: false
linux_6_1_arguments_override: "--explicit-target-dependency-import-check error"
linux_6_1_enabled: false
linux_6_2_arguments_override: "--explicit-target-dependency-import-check error"
linux_nightly_6_1_enabled: false
linux_nightly_next_enabled: false
linux_nightly_next_arguments_override: "--explicit-target-dependency-import-check error"
linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error"
# Windows is disabled, blocked on Swift Service Lifecycle Windows support: https://github.com/swift-server/swift-service-lifecycle/issues/213
Expand Down Expand Up @@ -45,6 +48,8 @@ jobs:
runner_pool: nightly
build_scheme: swift-configuration-Package
xcode_16_2_enabled: false
xcode_16_3_enabled: false
xcode_16_4_enabled: false

release-builds:
name: Release builds
Expand All @@ -53,6 +58,8 @@ jobs:
linux_env_vars: '{"ENABLE_ALL_TRAITS":"1"}'
linux_5_10_enabled: false
linux_6_0_enabled: false
linux_6_1_enabled: false
linux_nightly_next_enabled: false
windows_6_0_enabled: false
windows_6_1_enabled: false
windows_nightly_next_enabled: false
Expand All @@ -75,6 +82,8 @@ jobs:
MATRIX_LINUX_COMMAND: ./Scripts/run-linkage-test.sh
MATRIX_LINUX_5_10_ENABLED: false
MATRIX_LINUX_6_0_ENABLED: false
MATRIX_LINUX_6_1_ENABLED: false
MATRIX_LINUX_NIGHTLY_NEXT_ENABLED: false
MATRIX_LINUX_NIGHTLY_MAIN_ENABLED: false

linkage-test:
Expand Down Expand Up @@ -102,6 +111,8 @@ jobs:
MATRIX_LINUX_COMMAND: ./Scripts/test-examples.sh
MATRIX_LINUX_5_10_ENABLED: false
MATRIX_LINUX_6_0_ENABLED: false
MATRIX_LINUX_6_1_ENABLED: false
MATRIX_LINUX_NIGHTLY_NEXT_ENABLED: false
MATRIX_LINUX_NIGHTLY_MAIN_ENABLED: false

example-packages:
Expand Down
13 changes: 12 additions & 1 deletion .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ jobs:
linux_env_vars: '{"ENABLE_ALL_TRAITS":"1"}'
linux_5_10_enabled: false
linux_6_0_enabled: false
linux_6_1_arguments_override: "--explicit-target-dependency-import-check error"
linux_6_1_enabled: false
linux_6_2_arguments_override: "--explicit-target-dependency-import-check error"
linux_nightly_6_1_enabled: false
linux_nightly_next_enabled: false
linux_nightly_next_arguments_override: "--explicit-target-dependency-import-check error"
linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error"
# Windows is disabled, blocked on Swift Service Lifecycle Windows support: https://github.com/swift-server/swift-service-lifecycle/issues/213
Expand Down Expand Up @@ -52,6 +55,8 @@ jobs:
runner_pool: general
build_scheme: swift-configuration-Package
xcode_16_2_enabled: false
xcode_16_3_enabled: false
xcode_16_4_enabled: false

release-builds:
name: Release builds
Expand All @@ -60,6 +65,8 @@ jobs:
linux_env_vars: '{"ENABLE_ALL_TRAITS":"1"}'
linux_5_10_enabled: false
linux_6_0_enabled: false
linux_6_1_enabled: false
linux_nightly_next_enabled: false
windows_6_0_enabled: false
windows_6_1_enabled: false
windows_nightly_next_enabled: false
Expand All @@ -82,6 +89,8 @@ jobs:
MATRIX_LINUX_COMMAND: ./Scripts/run-linkage-test.sh
MATRIX_LINUX_5_10_ENABLED: false
MATRIX_LINUX_6_0_ENABLED: false
MATRIX_LINUX_6_1_ENABLED: false
MATRIX_LINUX_NIGHTLY_NEXT_ENABLED: false
MATRIX_LINUX_NIGHTLY_MAIN_ENABLED: false

linkage-test:
Expand Down Expand Up @@ -109,6 +118,8 @@ jobs:
MATRIX_LINUX_COMMAND: ./Scripts/test-examples.sh
MATRIX_LINUX_5_10_ENABLED: false
MATRIX_LINUX_6_0_ENABLED: false
MATRIX_LINUX_6_1_ENABLED: false
MATRIX_LINUX_NIGHTLY_NEXT_ENABLED: false
MATRIX_LINUX_NIGHTLY_MAIN_ENABLED: false

example-packages:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ Package.resolved
*.pyc
.docc-build
.vscode
.devcontainer
2 changes: 1 addition & 1 deletion .spi.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: 1
builder:
configs:
- swift_version: '6.1'
- swift_version: '6.2'
documentation_targets:
- Configuration
- ConfigurationTesting
2 changes: 1 addition & 1 deletion Examples/hello-world-cli-example/Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version: 6.1
// swift-tools-version: 6.2

import PackageDescription

Expand Down
4 changes: 2 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version: 6.1
// swift-tools-version: 6.2

import PackageDescription
#if canImport(FoundationEssentials)
Expand Down Expand Up @@ -29,7 +29,7 @@ var traits: Set<Trait> = [
.trait(
name: "ReloadingSupport",
description:
"Adds support for reloading built-in provider variants, such as ReloadingJSONProvider and ReloadingYAMLProvider (when their respective traits are enabled).",
"Adds support for reloading built-in provider variants, such as ReloadingFileProvider.",
enabledTraits: [
"LoggingSupport"
]
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ The example code below creates the two relevant providers, and resolves them in
```swift
let config = ConfigReader(providers: [
EnvironmentVariablesProvider(),
try await JSONProvider(filePath: "/etc/config.json")
try await FileProvider<JSONSnapshot>(filePath: "/etc/config.json")
])
let httpTimeout = config.int(forKey: "http.timeout", default: 60)
print(httpTimeout) // prints 15
Expand Down Expand Up @@ -100,11 +100,11 @@ To enable an additional trait on the package, update the package dependency:
```

Available traits:
- **`JSONSupport`** (default): Adds support for `JSONProvider`, a `ConfigProvider` for reading JSON files.
- **`JSONSupport`** (default): Adds support for `FileProvider<JSONSnapshot>`, a `ConfigProvider` for reading JSON files.
- **`LoggingSupport`** (opt-in): Adds support for `AccessLogger`, a way to emit access events into a `SwiftLog.Logger`.
- **`ReloadingSupport`** (opt-in): Adds support for auto-reloading variants of file providers, such as `ReloadingJSONProvider` (when `JSONSupport` is enabled) and `ReloadingYAMLProvider` (when `YAMLSupport` is enabled).
- **`ReloadingSupport`** (opt-in): Adds support for auto-reloading variants of file providers, such as `ReloadingFileProvider<JSONSnapshot>` (when `JSONSupport` is enabled) and `ReloadingFileProvider<YAMLSnapshot>` (when `YAMLSupport` is enabled).
- **`CommandLineArgumentsSupport`** (opt-in): Adds support for `CommandLineArgumentsProvider` for parsing command line arguments.
- **`YAMLSupport`** (opt-in): Adds support for `YAMLProvider`, a `ConfigProvider` for reading YAML files.
- **`YAMLSupport`** (opt-in): Adds support for `FileProvider<YAMLSnapshot>`, a `ConfigProvider` for reading YAML files.

## Supported platforms and minimum versions

Expand All @@ -120,8 +120,8 @@ The library includes comprehensive built-in provider support:

- Environment variables: [`EnvironmentVariablesProvider`](https://swiftpackageindex.com/apple/swift-configuration/documentation/configuration/environmentvariablesprovider)
- Command-line arguments: [`CommandLineArgumentsProvider`](https://swiftpackageindex.com/apple/swift-configuration/documentation/configuration/commandlineargumentsprovider)
- JSON file: [`JSONProvider`](https://swiftpackageindex.com/apple/swift-configuration/documentation/configuration/jsonprovider) and [`ReloadingJSONProvider`](https://swiftpackageindex.com/apple/swift-configuration/documentation/configuration/reloadingjsonprovider)
- YAML file: [`YAMLProvider`](https://swiftpackageindex.com/apple/swift-configuration/documentation/configuration/yamlprovider) and [`ReloadingYAMLProvider`](https://swiftpackageindex.com/apple/swift-configuration/documentation/configuration/reloadingyamlprovider)
- JSON file: [`FileProvider<JSONSnapshot>`](https://swiftpackageindex.com/apple/swift-configuration/documentation/configuration/fileprovider) and [`ReloadingFileProvider<JSONSnapshot>`](https://swiftpackageindex.com/apple/swift-configuration/documentation/configuration/reloadingfileprovider)
- YAML file: [`FileProvider<YAMLSnapshot>`](https://swiftpackageindex.com/apple/swift-configuration/documentation/configuration/fileprovider) and [`ReloadingFileProvider<YAMLSnapshot>`](https://swiftpackageindex.com/apple/swift-configuration/documentation/configuration/reloadingfileprovider)
- Directory of files: [`DirectoryFilesProvider`](https://swiftpackageindex.com/apple/swift-configuration/documentation/configuration/directoryfilesprovider)
- In-memory: [`InMemoryProvider`](https://swiftpackageindex.com/apple/swift-configuration/documentation/configuration/inmemoryprovider) and [`MutableInMemoryProvider`](https://swiftpackageindex.com/apple/swift-configuration/documentation/configuration/mutableinmemoryprovider)
- Key transforming: [`KeyMappingProvider`](https://swiftpackageindex.com/apple/swift-configuration/documentation/configuration/keymappingprovider)
Expand Down
2 changes: 1 addition & 1 deletion Sources/Configuration/ConfigReader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import Foundation
/// // First, check environment variables
/// EnvironmentVariablesProvider(),
/// // Then, check a JSON config file
/// try await JSONProvider(filePath: "/etc/config.json"),
/// try await FileProvider<JSONSnapshot>(filePath: "/etc/config.json"),
/// // Finally, fall back to in-memory defaults
/// InMemoryProvider(values: [
/// "http.timeout": 60,
Expand Down
45 changes: 45 additions & 0 deletions Sources/Configuration/Deprecations.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftConfiguration open source project
//
// Copyright (c) 2025 Apple Inc. and the SwiftConfiguration project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftConfiguration project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

#if JSONSupport
/// A provider of configuration in JSON files.
@available(Configuration 1.0, *)
@available(*, deprecated, message: "Renamed to FileProvider<JSONSnapshot>")
public typealias JSONProvider = FileProvider<JSONSnapshot>
#endif

#if YAMLSupport
/// A provider of configuration in YAML files.
@available(Configuration 1.0, *)
@available(*, deprecated, message: "Renamed to FileProvider<YAMLSnapshot>")
public typealias YAMLProvider = FileProvider<YAMLSnapshot>
#endif

#if ReloadingSupport

#if JSONSupport
/// A reloading provider of configuration in JSON files.
@available(Configuration 1.0, *)
@available(*, deprecated, message: "Renamed to ReloadingFileProvider<JSONSnapshot>")
public typealias ReloadingJSONProvider = ReloadingFileProvider<JSONSnapshot>
#endif

#if YAMLSupport
/// A reloading provider of configuration in JSON files.
@available(Configuration 1.0, *)
@available(*, deprecated, message: "Renamed to ReloadingFileProvider<YAMLSnapshot>")
public typealias ReloadingYAMLProvider = ReloadingFileProvider<YAMLSnapshot>
#endif

#endif
35 changes: 18 additions & 17 deletions Sources/Configuration/Documentation.docc/Documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ For example, to read the timeout configuration value for an HTTP client, check o
}
```
```swift
let provider = try await JSONProvider(
let provider = try await FileProvider<JSONSnapshot>(
filePath: "/etc/config.json"
)
let config = ConfigReader(provider: provider)
Expand All @@ -61,7 +61,7 @@ For example, to read the timeout configuration value for an HTTP client, check o
}
```
```swift
let provider = try await ReloadingJSONProvider(
let provider = try await ReloadingFileProvider<JSONSnapshot>(
filePath: "/etc/config.json"
)
// Omitted: Add `provider` to a ServiceGroup
Expand All @@ -76,7 +76,7 @@ For example, to read the timeout configuration value for an HTTP client, check o
timeout: 30
```
```swift
let provider = try await YAMLProvider(
let provider = try await FileProvider<YAMLSnapshot>(
filePath: "/etc/config.yaml"
)
let config = ConfigReader(provider: provider)
Expand All @@ -90,7 +90,7 @@ For example, to read the timeout configuration value for an HTTP client, check o
timeout: 30
```
```swift
let provider = try await ReloadingYAMLProvider(
let provider = try await ReloadingFileProvider<YAMLSnapshot>(
filePath: "/etc/config.yaml"
)
// Omitted: Add `provider` to a ServiceGroup
Expand Down Expand Up @@ -187,11 +187,11 @@ To enable an additional trait on the package, update the package dependency:
```

Available traits:
- **`JSONSupport`** (default): Adds support for ``JSONProvider``, a ``ConfigProvider`` for reading JSON files.
- **`JSONSupport`** (default): Adds support for ``JSONSnapshot``, which enables using ``FileProvider`` and ``ReloadingFileProvider`` with JSON files.
- **`LoggingSupport`** (opt-in): Adds support for ``AccessLogger``, a way to emit access events into a `SwiftLog.Logger`.
- **`ReloadingSupport`** (opt-in): Adds support for auto-reloading variants of file providers, such as ``ReloadingJSONProvider`` (when `JSONSupport` is enabled) and ``ReloadingYAMLProvider`` (when `YAMLSupport` is enabled).
- **`ReloadingSupport`** (opt-in): Adds support for ``ReloadingFileProvider``, which provides auto-reloading capability for file-based configuration.
- **`CommandLineArgumentsSupport`** (opt-in): Adds support for ``CommandLineArgumentsProvider`` for parsing command line arguments.
- **`YAMLSupport`** (opt-in): Adds support for ``YAMLProvider``, a ``ConfigProvider`` for reading YAML files.
- **`YAMLSupport`** (opt-in): Adds support for ``YAMLSnapshot``, which enables using ``FileProvider`` and ``ReloadingFileProvider`` with YAML files.

### Supported platforms and minimum versions

Expand Down Expand Up @@ -235,8 +235,8 @@ The library includes comprehensive built-in provider support:

- Environment variables: ``EnvironmentVariablesProvider``
- Command-line arguments: ``CommandLineArgumentsProvider``
- JSON file: ``JSONProvider`` and ``ReloadingJSONProvider``
- YAML file: ``YAMLProvider`` and ``ReloadingYAMLProvider``
- JSON file: ``FileProvider`` and ``ReloadingFileProvider`` with ``JSONSnapshot``
- YAML file: ``FileProvider`` and ``ReloadingFileProvider`` with ``YAMLSnapshot``
- Directory of files: ``DirectoryFilesProvider``
- In-memory: ``InMemoryProvider`` and ``MutableInMemoryProvider``
- Key transforming: ``KeyMappingProvider``
Expand All @@ -259,7 +259,7 @@ let config = ConfigReader(providers: [
// Then, check command-line options.
CommandLineArgumentsProvider(),
// Then, check a JSON config file.
try await JSONProvider(filePath: "/etc/config.json"),
try await FileProvider<JSONSnapshot>(filePath: "/etc/config.json"),
// Finally, fall back to in-memory defaults.
InMemoryProvider(values: [
"http.timeout": 60,
Expand All @@ -272,10 +272,10 @@ let timeout = config.int(forKey: "http.timeout", default: 15)

#### Hot reloading

Long-running services can periodically reload configuration with ``ReloadingJSONProvider`` and ``ReloadingYAMLProvider``:
Long-running services can periodically reload configuration with ``ReloadingFileProvider``:

```swift
let provider = try await ReloadingJSONProvider(filePath: "/etc/config.json")
let provider = try await ReloadingFileProvider<JSONSnapshot>(filePath: "/etc/config.json")
// Omitted: add provider to a ServiceGroup
let config = ConfigReader(provider: provider)

Expand Down Expand Up @@ -407,18 +407,17 @@ Any package can implement a ``ConfigProvider``, making the ecosystem extensible
- ``ConfigReader``
- ``ConfigProvider``
- ``ConfigSnapshotReader``
- ``ConfigSnapshotProtocol``
- <doc:Choosing-access-patterns>
- <doc:Choosing-reader-methods>
- <doc:Handling-secrets-correctly>

### Built-in providers
- ``EnvironmentVariablesProvider``
- ``CommandLineArgumentsProvider``
- ``JSONProvider``
- ``YAMLProvider``
- ``ReloadingJSONProvider``
- ``ReloadingYAMLProvider``
- ``FileProvider``
- ``ReloadingFileProvider``
- ``JSONSnapshot``
- ``YAMLSnapshot``
- <doc:Using-reloading-providers>
- ``DirectoryFilesProvider``
- <doc:Using-in-memory-providers>
Expand All @@ -427,6 +426,8 @@ Any package can implement a ``ConfigProvider``, making the ecosystem extensible
- ``KeyMappingProvider``

### Creating a custom provider
- ``ConfigSnapshotProtocol``
- ``FileParsingOptions``
- ``ConfigProvider``
- ``ConfigContent``
- ``ConfigValue``
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ Use the "watch" pattern when:

- Immediately emits the initial value, then subsequent updates.
- Continues monitoring until the task is cancelled.
- Works with providers like ``ReloadingJSONProvider`` and ``ReloadingYAMLProvider``.
- Works with providers like ``ReloadingFileProvider``.

For details on reloading providers, check out <doc:Using-reloading-providers>.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ let logger: Logger = ...

let config = ConfigReader(
providers: [
EnvironmentVariablesProvider(),
try await JSONProvider(filePath: "/etc/myapp/config.json"),
EnvironmentVariablesProvider(),
try await FileProvider<JSONSnapshot>(filePath: "/etc/myapp/config.json"),
InMemoryProvider(values: [
"http.server.port": 8080,
"http.server.host": "127.0.0.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ variable name above `SERVER_PORT`.

### Reading from a JSON configuration file

You can store multiple configuration values together in a JSON file and read them from the fileystem using ``JSONProvider``.
You can store multiple configuration values together in a JSON file and read them from the fileystem using ``FileProvider`` with ``JSONSnapshot``.
The following example creates a ``ConfigReader`` for a JSON file at the path `/etc/config.json`, and reads a url and port
number collected as properties of the `database` JSON object:

```swift
import Configuration

let config = ConfigReader(
provider: try await JSONProvider(filePath: "/etc/config.json")
provider: try await FileProvider<JSONSnapshot>(filePath: "/etc/config.json")
)

// Access nested values using dot notation.
Expand Down Expand Up @@ -92,7 +92,7 @@ let config = ConfigReader(providers: [
// First check environment variables.
EnvironmentVariablesProvider(),
// Then check the config file.
try await JSONProvider(filePath: "/etc/config.json"),
try await FileProvider<JSONSnapshot>(filePath: "/etc/config.json"),
// Finally, use hardcoded defaults.
InMemoryProvider(values: [
"app.name": "MyApp",
Expand Down Expand Up @@ -131,7 +131,7 @@ import Configuration
import ServiceLifecycle

// Create a reloading YAML provider
let provider = try await ReloadingYAMLProvider(
let provider = try await ReloadingFileProvider<YAMLSnapshot>(
filePath: "/etc/app-config.yaml",
pollInterval: .seconds(30)
)
Expand Down
Loading