### Build and Run Swift Package Example Source: https://github.com/apple/swift-configuration/blob/main/Examples/README.md Navigate to an example directory and use Swift Package Manager commands to build and run the example. ```zsh cd Examples/{example-name} swift build swift run {target-name} ``` -------------------------------- ### Build Swift CLI Example Source: https://github.com/apple/swift-configuration/blob/main/Examples/hello-world-cli-example/README.md Navigate to the example directory and build the executable using Swift. ```zsh cd Examples/hello-world-cli-example swift build ``` -------------------------------- ### Example System Information for Bug Report Source: https://github.com/apple/swift-configuration/blob/main/CONTRIBUTING.md When reporting issues, provide detailed system and Swift Configuration version information. This example shows the expected format. ```text Swift Configuration version: 1.0.0 Context: While testing my application that uses with swift-configuration, I noticed that ... Steps to reproduce: 1. ... 2. ... 3. ... 4. ... $ swift --version Swift version 4.0.2 (swift-4.0.2-RELEASE) Target: x86_64-unknown-linux-gnu Operating system: Ubuntu Linux 16.04 64-bit $ uname -a Linux beefy.machine 4.4.0-101-generic #124-Ubuntu SMP Fri Nov 10 18:29:59 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux My system has IPv6 disabled. ``` -------------------------------- ### Synchronous Configuration Get Example Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Documentation.md Use the 'get' pattern to synchronously retrieve an integer configuration value with a default. ```swift let timeout = config.int(forKey: "http.timeout", default: 60) ``` -------------------------------- ### Asynchronous Configuration Fetch Example Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Documentation.md Use the 'fetch' pattern to asynchronously retrieve the most up-to-date integer configuration value. ```swift let timeout = try await config.fetchInt(forKey: "http.timeout", default: 60) ``` -------------------------------- ### Import and Use Configuration in Swift Code Source: https://github.com/apple/swift-configuration/blob/main/README.md Basic example of importing the Configuration library and using an EnvironmentVariablesProvider to read an integer value with a default. ```swift import Configuration let config = ConfigReader(provider: EnvironmentVariablesProvider()) let httpTimeout = config.int(forKey: "http.timeout", default: 60) print("The HTTP timeout is: \(httpTimeout)") ``` -------------------------------- ### Build Docker Image for Example App Source: https://github.com/apple/swift-configuration/blob/main/Examples/reloading-example/README.md Build a Docker image for the Hummingbird application that includes the dynamic reconfiguration logic. ```bash docker build -t reloading-example:latest . ``` -------------------------------- ### Synchronous Local Access with Get Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Choosing-access-patterns.md Use the 'get' pattern for immediate, synchronous access to configuration values already in memory. This is ideal for performance-critical scenarios, stable configurations, simple providers, and startup or request handling. ```swift let config = ConfigReader(provider: EnvironmentVariablesProvider()) // Get the current timeout value synchronously let timeout = config.int(forKey: "http.timeout", default: 30) // Get a required value that must be present let apiKey = try config.requiredString(forKey: "api.key", isSecret: true) ``` -------------------------------- ### Watch Configuration Updates Example Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Documentation.md Use the 'watch' pattern to asynchronously receive updates when an integer configuration value changes. ```swift try await config.watchInt(forKey: "http.timeout", default: 60) { updates in for try await timeout in updates { print("HTTP timeout updated to: \(timeout)") } } ``` -------------------------------- ### Initialize FileProvider with JSONSnapshot Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Proposals/SCO-0001.md Example of creating a FileProvider for JSON configuration files. Ensure the file exists at the specified path. ```swift let jsonProvider = try await FileProvider( filePath: "/etc/config.json" ) ``` -------------------------------- ### Example PropertyList file structure Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Proposals/SCO-0005.md This is an example of a property list file in XML format, demonstrating nested dictionaries and integer values. Both XML and binary plist formats are supported. ```xml http timeout 30 ``` -------------------------------- ### Configuration with Context Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Choosing-reader-methods.md Provides examples of how to use configuration variants (optional, default, required) with added context, allowing for more specific configuration retrieval based on environment or region. ```swift // Optional with context let timeout = config.int( forKey: ConfigKey( "service.timeout", context: ["environment": "production", "region": "us-east-1"] ) ) ``` ```swift // Default with context let timeout = config.int( forKey: ConfigKey( "service.timeout", context: ["environment": "production"] ), default: 30 ) ``` ```swift // Required with context let timeout = try config.requiredInt( forKey: ConfigKey( "service.timeout", context: ["environment": "production"] ) ) ``` -------------------------------- ### Initialize FileProvider with YAMLSnapshot Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Proposals/SCO-0001.md Example of creating a FileProvider for YAML configuration files. Ensure the file exists at the specified path. ```swift let yamlProvider = try await FileProvider( filePath: "/etc/config.yaml" ) ``` -------------------------------- ### Set Library Configuration via Environment Variables Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Configuring-libraries.md Example of how to set configuration values for a library by exporting environment variables. These variables correspond to the keys expected by the library's ConfigReader initializer. ```bash # Set configuration for your library through environment variables. export TIMEOUT=60.0 export MAX_CONCURRENT_CONNECTIONS=10 export BASE_URL="https://api.production.com" export DEBUG_LOGGING=true ``` -------------------------------- ### JSON configuration for application settings Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Configuring-applications.md Example of a JSON file structure for configuring application settings, covering server and client HTTP configurations. ```json { "http": { "server": { "host": "localhost", "port": 8080 }, "client": { "timeout": 30.0, "maxConcurrentConnections": 20, "baseURL": "https://example.com", "debugLogging": true } } } ``` -------------------------------- ### Allow ReloadingFileProvider to Start with Missing Configuration Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Troubleshooting.md Use `allowMissing: true` with ReloadingFileProvider to allow the application to start even if the configuration file is not immediately available. The provider will attempt to load the file when it becomes available. ```swift let provider = try await ReloadingFileProvider( filePath: "/mnt/config/app.json", allowMissing: true // Allow startup with empty config, load when available ) ``` -------------------------------- ### Environment variables for application configuration Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Configuring-applications.md Example of environment variables used to configure application settings, including server host, port, and HTTP client parameters. ```bash export HTTP_SERVER_HOST=localhost export HTTP_SERVER_PORT=8080 export HTTP_CLIENT_TIMEOUT=30.0 export HTTP_CLIENT_MAX_CONCURRENT_CONNECTIONS=20 export HTTP_CLIENT_BASE_URL="https://example.com" export HTTP_CLIENT_DEBUG_LOGGING=true ``` -------------------------------- ### Example: Using config.int(forKey:as:) Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Proposals/SCO-0004.md Demonstrates how to use the config.int(forKey:as:) method to read an integer configuration value and convert it into a custom domain type like Duration. This requires the target type to conform to ExpressibleByConfigInt. ```swift let timeout = config.int(forKey: "timeout", as: Duration.self) // timeout is now a Duration, e.g., 5 seconds ``` -------------------------------- ### Example: Custom APIVersion Wrapper Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Proposals/SCO-0004.md Shows how to implement a custom wrapper type, APIVersion, conforming to ExpressibleByConfigInt. This allows reading integer-based version numbers from configuration into a strongly-typed APIVersion object. ```swift struct APIVersion: ExpressibleByConfigInt { let major: Int let minor: Int init?(configInt: Int) { guard configInt > 0 else { return nil } self.major = configInt / 100 self.minor = configInt % 100 } var configInt: Int { major * 100 + minor } } // Usage: // let version = config.int(forKey: "api_version", as: APIVersion.self) ``` -------------------------------- ### Multi-layered configuration with optional file provider Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Proposals/SCO-0003.md Illustrates using `FileProvider` with `allowMissing: true` in a multi-layered configuration setup. This ensures that the application can still load configurations from other sources even if the optional file is absent. ```swift // Multi-layered configuration with optional overrides let config = ConfigReader(provider: [ EnvironmentVariablesProvider(), try await FileProvider( filePath: "optional-config.json", allowMissing: true // Won't fail if missing ), InMemoryProvider(data: ["fallback": "values"]) ]) ``` -------------------------------- ### In-memory default configuration values Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Configuring-applications.md Example of using a Swift dictionary to provide in-memory default configuration values for application settings. ```swift [ "http.server.port": 8080, "http.server.host": "127.0.0.1", "http.client.timeout": 30.0, "http.client.maxConcurrentConnections": 20, "http.client.baseURL": "https://example.com", "http.client.debugLogging": true, ] ``` -------------------------------- ### Default Key Decoder Usage Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Proposals/SCO-0002.md Demonstrates the usage of the default dot-based key decoder when both targets assume its use. This setup ensures correct key scoping and reading. ```swift import HTTPClient let config = ConfigReader( provider: EnvironmentVariablesProvider() // ✅ Uses the default dot-based key decoder. ) // ✅ Uses scoping correctly let client = Client(config: config.scoped(to: "http.client")) ``` ```swift extension Client { public init(config: ConfigReader) { // ✅ reads ["http", "client", "read", "timeout"] self.timeout = config.int(forKey: "read.timeout", default: 30) } } ``` -------------------------------- ### Use InMemoryProvider for testing Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Using-in-memory-providers.md An example of using InMemoryProvider to set up mock configuration values for unit testing a DatabaseConnection class. ```swift func testDatabaseConnection() { let testProvider = InMemoryProvider(values: [ "database.host": "test-db.example.com", "database.port": 5433, "database.name": "test_db" ]) let config = ConfigReader(provider: testProvider) let connection = DatabaseConnection(config: config) // Test your database connection logic } ``` -------------------------------- ### Setup JSON File Provider with Environment Variables Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Using-reloading-providers.md Configure a ReloadingFileProvider to watch a JSON file for configuration changes. It uses environment variables to determine the file path and polling interval. ```swift let envProvider = EnvironmentVariablesProvider() let envConfig = ConfigReader(provider: envProvider) let jsonProvider = try await ReloadingFileProvider( config: envConfig.scoped(to: "json") // Reads JSON_FILE_PATH and JSON_POLL_INTERVAL_SECONDS ) ``` -------------------------------- ### Asynchronous Fresh Access with Fetch Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Choosing-access-patterns.md Employ the 'fetch' pattern to asynchronously retrieve the most current configuration values from the authoritative data source. This is suitable for scenarios where data freshness is critical, when using remote providers, or for infrequent access and setup operations. ```swift let config = ConfigReader(provider: remoteConfigProvider) // Fetch the latest timeout from a remote configuration service let timeout = try await config.fetchInt(forKey: "http.timeout", default: 30) // Fetch with context for environment-specific configuration let dbConnectionString = try await config.fetchRequiredString( forKey: ConfigKey( "database.url", context: [ "environment": "production", "region": "us-west-2", "service": "user-service" ] ), isSecret: true ) ``` -------------------------------- ### Watch for configuration changes with MutableInMemoryProvider Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Using-in-memory-providers.md Use the async sequence of a MutableInMemoryProvider to observe changes to specific configuration keys. This example shows how to watch for string changes and handle updates. ```swift let config = ConfigReader(provider: provider) try await config.watchString( forKey: "logging.level", as: Logger.Level.self, default: .debug ) { updates in for try await level in updates { print("Logging level changed to: \(level)") } } ``` -------------------------------- ### Handle Optional Configuration Files Gracefully Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Troubleshooting.md Use the `allowMissing: true` parameter with FileProvider to prevent application crashes when an optional configuration file is not found. This allows the application to start with an empty configuration if the file is absent. ```swift let provider = try await FileProvider( filePath: "/etc/optional-config.json", allowMissing: true ) ``` -------------------------------- ### Configure Library Using Environment Variables Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Configuring-libraries.md Demonstrates how a user can configure your library by creating a ConfigReader from environment variables and then initializing your library's configuration using it. This allows your library to adapt to the user's environment without code changes. ```swift import Configuration import YourHTTPLibrary // Create a config reader from environment variables. let config = ConfigReader(provider: EnvironmentVariablesProvider()) // Initialize your library's configuration from a config reader. let httpConfig = HTTPClientConfiguration(config: config) // Create your library instance with the configuration. let httpClient = HTTPClient(configuration: httpConfig) // Start using your library. httpClient.get("/users") { response in // Handle the response. } ``` -------------------------------- ### FileProvider Initialization Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Proposals/SCO-0001.md Demonstrates how to initialize FileProvider with a specific file path or using a configuration reader. ```APIDOC ## FileProvider Initialization ### Description Initializes a `FileProvider` to read configuration from a file on disk. It supports generic snapshot types for different file formats like JSON and YAML. ### Initializers #### `init(snapshotType:parsingOptions:filePath:)` Creates a file provider that reads from the specified file path. - **Parameters**: - `snapshotType` (Snapshot.Type) - The type of snapshot to create from the file contents. Defaults to `Snapshot.self`. - `parsingOptions` (Snapshot.ParsingOptions) - Options used by the snapshot to parse the file data. Defaults to `.default`. - `filePath` (FilePath) - The path to the configuration file to read. - **Throws**: If the file cannot be read or if snapshot creation fails. ```swift let jsonProvider = try await FileProvider( filePath: "/etc/config.json" ) let yamlProvider = try await FileProvider( filePath: "/etc/config.yaml" ) ``` #### `init(snapshotType:parsingOptions:config:)` Creates a file provider using a file path obtained from a configuration reader. - **Configuration keys**: - `filePath` (string, required): The path to the configuration file to read. - **Parameters**: - `snapshotType` (Snapshot.Type) - The type of snapshot to create from the file contents. Defaults to `Snapshot.self`. - `parsingOptions` (Snapshot.ParsingOptions) - Options used by the snapshot to parse the file data. Defaults to `.default`. - `config` (ConfigReader) - A configuration reader that contains the required configuration keys. - **Throws**: If the `filePath` key is missing, if the file cannot be read, or if snapshot creation fails. ```swift let envConfig = ConfigReader(provider: EnvironmentVariablesProvider()) let provider = try await FileProvider(config: envConfig) ``` ``` -------------------------------- ### Get Pattern Error Handling in Swift Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Choosing-access-patterns.md The 'get' pattern returns nil or a default value for missing or invalid configuration. Use required variants to throw errors for missing values. ```swift // Returns nil or default value for missing/invalid config let timeout = config.int(forKey: "http.timeout", default: 30) // Required variants throw errors for missing values do { let apiKey = try config.requiredString(forKey: "api.key") } catch { // Handle missing required configuration } ``` -------------------------------- ### ConfigKey Initialization Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Reference/ConfigKey.md Learn how to create new configuration keys using different initializers. ```APIDOC ## Creating a Configuration Key This section describes the initializers available for creating `ConfigKey` objects. ### Initializers - `init(_:context:)-(String,_)` - Initializes a `ConfigKey` with a single string component and a context. - `init(_:context:)-([String],_)` - Initializes a `ConfigKey` with an array of string components and a context. ``` -------------------------------- ### Documenting Configuration Keys in Swift Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Best-practices.md Use documentation comments to clearly explain configuration keys, their types, requirements, defaults, and constraints. ```swift public struct HTTPClientConfiguration { /// ... /// /// ## Configuration keys: /// - `timeout` (double, optional, default: 30.0): Request timeout in seconds. /// - `maxRetries` (int, optional, default: 3, range: 0-10): Maximum retry attempts. /// - `baseURL` (string, required): Base URL for requests. /// - `apiKey` (string, required, secret): API authentication key. /// /// ... public init(config: ConfigReader) { // Implementation... } } ``` -------------------------------- ### Setting up a Configuration Hierarchy Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Example-use-cases.md Combines multiple providers like environment variables, JSON files, and defaults to create an override hierarchy. Consults providers in order until a value is found. ```swift import Configuration let config = ConfigReader(providers: [ // First check environment variables. EnvironmentVariablesProvider(), // Then check the config file. try await FileProvider(filePath: "/etc/config.json"), // Finally, use hardcoded defaults. InMemoryProvider(values: [ "app.name": "MyApp", "server.port": 8080, "logging.level": "info" ]) ]) ``` -------------------------------- ### Set up configuration hierarchy with multiple providers Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Configuring-applications.md Define the order of configuration sources, prioritizing environment variables, then a JSON file, and finally in-memory defaults. Access logging with secret redaction is enabled. ```swift import Configuration import Logging // Create a logger. let logger: Logger = ... // Set up the configuration hierarchy: // - environment variables first, // - then JSON file, // - then in-memory defaults. // Also emit log accesses into the provider logger, // with secrets automatically redacted. let config = ConfigReader( providers: [ EnvironmentVariablesProvider(), try await FileProvider( filePath: "/etc/myapp/config.json", allowMissing: true // Optional: treat missing file as empty config ), InMemoryProvider(values: [ "http.server.port": 8080, "http.server.host": "127.0.0.1", "http.client.timeout": 30.0 ]) ], accessReporter: AccessLogger(logger: logger) ) // Start your application with the config. try await runApplication(config: config, logger: logger) ``` -------------------------------- ### Handle Optional Configuration Files (Default Behavior) Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Example-use-cases.md Demonstrates the default behavior of FileProvider where a missing configuration file will throw an error. Ensure the file exists or set allowMissing to true. ```swift import Configuration // This will throw an error if config.json doesn't exist let config = ConfigReader( provider: try await FileProvider( filePath: "/etc/config.json", allowMissing: false // This is the default ) ) ``` -------------------------------- ### View Configuration Access Logs from File Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Documentation.md Shows how to enable logging of configuration access to a file by setting an environment variable and then how to view these logs using the `tail -f` command. ```env CONFIG_ACCESS_LOG_FILE=/var/log/myapp/config-access.log ``` ```zsh tail -f /var/log/myapp/config-access.log ``` -------------------------------- ### Demonstrate Provider Priority (CLI vs. Env) Source: https://github.com/apple/swift-configuration/blob/main/Examples/hello-world-cli-example/README.md Illustrates that command-line arguments override environment variables by providing both configuration sources simultaneously. ```zsh GREETED_NAME="EnvValue" swift run CLI --greeted-name "CLIValue" ``` -------------------------------- ### Fetching a Value from a Remote Source Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Example-use-cases.md Asynchronously retrieves a configuration value from a remote provider using the 'fetch' access pattern. This makes a network call to get the latest value. ```swift import Configuration let myRemoteProvider = MyRemoteProvider(...) let config = ConfigReader(provider: myRemoteProvider) // Makes a network call to retrieve the up-to-date value. let samplingRatio = try await config.fetchDouble(forKey: "sampling.ratio") ``` -------------------------------- ### Create ConfigReader with Provider Hierarchy Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Documentation.md Demonstrates creating a ConfigReader with multiple providers to establish a fallback hierarchy. Environment variables are checked first, followed by command-line arguments, a JSON file, and finally in-memory defaults. ```swift // Create a hierarchy of providers with fallback behavior. let config = ConfigReader(providers: [ // First, check environment variables. EnvironmentVariablesProvider(), // Then, check command-line options. CommandLineArgumentsProvider(), // Then, check a JSON config file. try await FileProvider(filePath: "/etc/config.json"), // Finally, fall back to in-memory defaults. InMemoryProvider(values: [ "http.timeout": 60, ]) ]) // Uses the first provider that has a value for "http.timeout". let timeout = config.int(forKey: "http.timeout", default: 15) ``` -------------------------------- ### Combine Configuration Providers in Swift Source: https://github.com/apple/swift-configuration/blob/main/README.md Demonstrates how to combine environment variables and JSON file providers for hierarchical configuration. Values from higher-priority sources override lower-priority ones. A default value is used if no source provides the key. ```json { "http": { "timeout": 30 } } ``` ```env # Environment variables: HTTP_TIMEOUT=15 ``` ```swift let config = ConfigReader(providers: [ EnvironmentVariablesProvider(), try await FileProvider(filePath: "/etc/config.json") ]) let httpTimeout = config.int(forKey: "http.timeout", default: 60) print(httpTimeout) // prints 15 ``` -------------------------------- ### Add Configuration Product to Target Source: https://github.com/apple/swift-configuration/blob/main/README.md Illustrates how to link the 'Configuration' product from the Swift Configuration package to your target in Package.swift. ```swift .product(name: "Configuration", package: "swift-configuration") ``` -------------------------------- ### Creating a Key-Mapping Provider Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Reference/KeyMappingProvider.md This section explains how to initialize a key-mapping provider with an upstream provider and a key mapper. ```APIDOC ## Initializing Configuration/KeyMappingProvider ### Description Initializes a new instance of `KeyMappingProvider`. ### Method `init(upstream:keyMapper:)` ### Parameters - **upstream** (ConfigurationProvider) - Required - The upstream configuration provider to delegate to. - **keyMapper** (KeyMapper) - Required - The key mapper to transform keys. ``` -------------------------------- ### Preview Documentation Locally Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Development/Development.md Preview the generated documentation locally using the 'swift package preview-documentation' command. This requires setting the SWIFT_PREVIEW_DOCS environment variable. ```bash SWIFT_PREVIEW_DOCS=1 swift package --disable-sandbox preview-documentation --target Configuration ``` -------------------------------- ### ReloadingFileProvider Initialization Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Proposals/SCO-0001.md Demonstrates how to initialize ReloadingFileProvider with a file path or a configuration reader. ```APIDOC ## ReloadingFileProvider Initialization ### Description Initializes a `ReloadingFileProvider` which monitors a configuration file for changes and reloads automatically. ### Method `init` ### Endpoint N/A (Initializes a Swift class) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```swift // Using with a JSON snapshot and a custom poll interval let jsonProvider = try await ReloadingFileProvider( filePath: "/etc/config.json", pollInterval: .seconds(30) ) // Using with a YAML snapshot let yamlProvider = try await ReloadingFileProvider( filePath: "/etc/config.yaml" ) // Using with configuration from a reader let envConfig = ConfigReader(provider: EnvironmentVariablesProvider()) let provider = try await ReloadingFileProvider(config: envConfig) ``` ### Response None (Initializes an object) #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Create Namespaced Reader with Scoped Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Documentation.md Illustrates using ConfigReader.scoped(to:) to create a reader for a specific namespace, allowing access to nested configuration values with shorter keys. This example assumes a JSON configuration with an 'http' object containing a 'timeout' key. ```json { "http": { "timeout": 60 } } ``` ```swift // Create the root reader. let config = ConfigReader(provider: provider) // Create a scoped reader for HTTP settings. let httpConfig = config.scoped(to: "http") // Now you can access values with shorter keys. // Equivalent to reading "http.timeout" on the root reader. let timeout = httpConfig.int(forKey: "timeout") ``` -------------------------------- ### Initialize FileProvider using ConfigReader Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Proposals/SCO-0001.md Initializes a FileProvider by reading the file path from a ConfigReader, which can use environment variables or other sources. Requires a 'filePath' key in the configuration. ```swift let envConfig = ConfigReader(provider: EnvironmentVariablesProvider()) let provider = try await FileProvider(config: envConfig) ``` -------------------------------- ### Creating an in-memory provider Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Reference/InMemoryProvider.md Demonstrates the initialization of an InMemoryProvider with a name and a dictionary of values. ```APIDOC ## Initializing InMemoryProvider ### Description Initializes an in-memory configuration provider with a given name and a dictionary of key-value pairs. ### Method `init(name:values:)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) None #### Response Example None ``` -------------------------------- ### Configure In-Memory Provider Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Documentation.md Sets up an in-memory configuration provider with predefined key-value pairs. Useful for testing or simple configurations. ```swift let provider = InMemoryProvider(values: [ "http.timeout": 30, ]) let config = ConfigReader(provider: provider) ``` -------------------------------- ### Configuration/FileProvider Initialization Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Reference/FileProvider.md Provides details on initializing a file provider for configuration files. ```APIDOC ## Initializing a File Provider ### Description Initializes a file provider for configuration files with specified options and file path. ### Method `init(snapshotType:parsingOptions:filePath:allowMissing:)` ### Parameters - **snapshotType** (enum) - Required - The type of snapshot to use for parsing. - **parsingOptions** (enum) - Required - Options for parsing the configuration file. - **filePath** (String) - Required - The path to the configuration file. - **allowMissing** (Bool) - Optional - Whether to allow the file to be missing. --- ### Description Initializes a file provider for configuration files with specified options and a configuration object. ### Method `init(snapshotType:parsingOptions:config:)` ### Parameters - **snapshotType** (enum) - Required - The type of snapshot to use for parsing. - **parsingOptions** (enum) - Required - Options for parsing the configuration file. - **config** (Configuration) - Required - The configuration object to use. ``` -------------------------------- ### Load configuration from a PropertyList file Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Proposals/SCO-0005.md Instantiate a FileProvider with PropertyListSnapshot for a given file path and then create a ConfigReader to access configuration values. Default values can be provided for keys. ```swift import Configuration let provider = try await FileProvider(filePath: "Config.plist") let config = ConfigReader(provider: provider) let timeout = config.int(forKey: "http.timeout", default: 30) ``` -------------------------------- ### ConfigReader Initialization Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Reference/ConfigReader.md APIs for initializing a ConfigReader with different provider configurations. ```APIDOC ## ConfigReader Initialization ### Description Initializes a `ConfigReader` instance. ### Topics - `ConfigReader/init(provider:accessReporter:)` - `ConfigReader/init(providers:accessReporter:)` ``` -------------------------------- ### Handle Optional Configuration Files (Allow Missing) Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Example-use-cases.md Configure FileProvider with allowMissing: true to treat missing configuration files as empty. This prevents errors and allows default values to be used. ```swift import Configuration // This won't throw if config.json is missing - treats it as empty let config = ConfigReader( provider: try await FileProvider( filePath: "/etc/config.json", allowMissing: true ) ) // Returns the default value if the file is missing let port = config.int(forKey: "server.port", default: 8080) ``` -------------------------------- ### FileProvider ConfigProvider Conformance - snapshot() Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Proposals/SCO-0001.md Returns the current immutable snapshot of the configuration values. ```swift public func snapshot() -> any ConfigSnapshotProtocol ``` -------------------------------- ### Migrate from FileProvider to ReloadingFileProvider Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Using-reloading-providers.md Demonstrates the initialization change required when migrating from a static FileProvider to a dynamic ReloadingFileProvider. ```swift // Before let provider = try await FileProvider(filePath: "/etc/config.json") // After let provider = try await ReloadingFileProvider(filePath: "/etc/config.json") ``` -------------------------------- ### Apply Kubernetes Manifests Source: https://github.com/apple/swift-configuration/blob/main/Examples/reloading-example/README.md Apply the Kubernetes configuration map and deployment manifests to create the necessary resources in the cluster. ```bash kubectl apply -f deploy/example-configmap.yaml kubectl apply -f deploy/example-deployment.yaml ``` -------------------------------- ### Log Configuration Access with AccessReporter Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Documentation.md Demonstrates how to use AccessReporter with an AccessLogger to log all accesses to a configuration reader. This helps in debugging and understanding how configuration values are being read, with sensitive values automatically redacted. ```swift let logger = Logger(label: "config") let config = ConfigReader( provider: provider, accessReporter: AccessLogger(logger: logger) ) // Now all configuration access is logged, with secret values redacted ``` -------------------------------- ### Run CLI with Command-Line Argument Source: https://github.com/apple/swift-configuration/blob/main/Examples/hello-world-cli-example/README.md Provide the greetedName configuration via a command-line argument when running the Swift CLI application. ```zsh swift run CLI --greeted-name "Developer" ``` -------------------------------- ### AccessEvent.Metadata Initialization Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Reference/AccessEvent-Metadata.md Learn how to create new instances of AccessEvent.Metadata with various access event details. ```APIDOC ## Initializing Access Event Metadata ### Description Initializes a new instance of `AccessEvent.Metadata`. ### Method `init(accessKind:key:valueType:sourceLocation:accessTimestamp:)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response None ### Related Topics - `AccessKind` ``` -------------------------------- ### FileProvider Initializer with ConfigReader Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Proposals/SCO-0001.md Creates a FileProvider using a file path obtained from a ConfigReader. This initializer expects a 'filePath' key within the provided configuration. ```swift public init( snapshotType: Snapshot.Type = Snapshot.self, parsingOptions: Snapshot.ParsingOptions = .default, config: ConfigReader ) async throws ``` -------------------------------- ### Run Formatting Checks with act and Bind Mount Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Development/Development.md Execute formatting checks using 'act' while bind-mounting the working directory. This ensures changes are reflected directly and efficiently. ```bash % act --bind workflow_call -j soundness --input format_check_enabled=true ``` -------------------------------- ### Create Local Kubernetes Cluster with Kind Source: https://github.com/apple/swift-configuration/blob/main/Examples/reloading-example/README.md Use this command to create a local Kubernetes cluster for testing purposes. ```bash kind create cluster ``` -------------------------------- ### Initialize ReloadingFileProvider with ConfigReader Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Proposals/SCO-0001.md Initialize the provider using a ConfigReader, which should contain a 'filePath' key for the configuration file. This method allows for configuration of the provider itself through other configuration sources. ```swift let envConfig = ConfigReader(provider: EnvironmentVariablesProvider()) let provider = try await ReloadingFileProvider(config: envConfig) ``` -------------------------------- ### Implement File Configuration Snapshot in Swift Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Proposals/SCO-0001.md Conform to the `FileConfigSnapshot` protocol to create configuration snapshots from file data. This involves defining the `ParsingOptions` type and implementing an initializer that parses raw data. ```swift struct MyFormatSnapshot: FileConfigSnapshot { typealias ParsingOptions = MyParsingOptions let values: [String: ConfigValue] let providerName: String init(data: RawSpan, providerName: String, parsingOptions: MyParsingOptions) throws { self.providerName = providerName // Parse the data according to your format self.values = try parseMyFormat(data, using: parsingOptions) } } ``` -------------------------------- ### Optional File-Based Providers Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Example-use-cases.md Shows how to configure various file-based providers to optionally allow missing files, treating them as empty configurations. ```swift import Configuration // Optional secrets directory let secretsConfig = ConfigReader( provider: try await DirectoryFilesProvider( directoryPath: "/run/secrets", allowMissing: true ) ) // Optional environment file let envConfig = ConfigReader( provider: try await EnvironmentVariablesProvider( environmentFilePath: "/etc/app.env", allowMissing: true ) ) // Optional reloading configuration let reloadingConfig = ConfigReader( provider: try await ReloadingFileProvider( filePath: "/etc/dynamic-config.yaml", allowMissing: true ) ) ``` -------------------------------- ### ConfigBytesFromBase64StringDecoder Initialization Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Reference/ConfigBytesFromBase64StringDecoder.md Demonstrates how to initialize the ConfigBytesFromBase64StringDecoder to create bytes from a base64 encoded string. ```APIDOC ## Initializing ConfigBytesFromBase64StringDecoder ### Description Initializes a new instance of `ConfigBytesFromBase64StringDecoder`. This decoder is used to convert a base64 encoded string into its raw byte representation. ### Method `init()` ### Endpoint N/A (This is a class initializer, not an API endpoint) ### Parameters This initializer does not take any parameters. ### Request Example ```swift let decoder = ConfigBytesFromBase64StringDecoder() ``` ### Response N/A (Initializers do not have explicit responses in this context.) ``` -------------------------------- ### EnvironmentVariablesProvider Initialization Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Reference/EnvironmentVariablesProvider.md Provides details on the different ways to initialize an EnvironmentVariablesProvider. ```APIDOC ## EnvironmentVariablesProvider Initialization ### Description Initializes an `EnvironmentVariablesProvider` with various configurations. ### Methods - `init(secretsSpecifier:bytesDecoder:arraySeparator:)` - `init(environmentVariables:secretsSpecifier:bytesDecoder:arraySeparator:)` - `init(environmentFilePath:allowMissing:secretsSpecifier:bytesDecoder:arraySeparator:)` ### Parameters #### `init(secretsSpecifier:bytesDecoder:arraySeparator:)` - **secretsSpecifier** (SecretsSpecifier) - Specifies how to handle secrets. - **bytesDecoder** (BytesDecoder) - Decoder for byte values. - **arraySeparator** (String?) - Separator for array values. #### `init(environmentVariables:secretsSpecifier:bytesDecoder:arraySeparator:)` - **environmentVariables** ([String: String]) - A dictionary of environment variables. - **secretsSpecifier** (SecretsSpecifier) - Specifies how to handle secrets. - **bytesDecoder** (BytesDecoder) - Decoder for byte values. - **arraySeparator** (String?) - Separator for array values. #### `init(environmentFilePath:allowMissing:secretsSpecifier:bytesDecoder:arraySeparator:)` - **environmentFilePath** (String) - Path to the environment file. - **allowMissing** (Bool) - Whether to allow missing environment files. - **secretsSpecifier** (SecretsSpecifier) - Specifies how to handle secrets. - **bytesDecoder** (BytesDecoder) - Decoder for byte values. - **arraySeparator** (String?) - Separator for array values. ### Request Body N/A ### Request Example N/A ### Response N/A ### Error Handling N/A ``` -------------------------------- ### Providing Sensible Defaults in Swift Configuration Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Best-practices.md Offer default values for configuration keys to ensure libraries function without explicit user configuration for common scenarios. ```swift // Good: Provides sensible defaults let timeout = config.double(forKey: "http.timeout", default: 30.0) let maxConnections = config.int(forKey: "http.maxConnections", default: 10) // Avoid: Requiring configuration for common scenarios let timeout = try config.requiredDouble(forKey: "http.timeout") // Forces users to configure ``` -------------------------------- ### Optional Features with Defaults Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Choosing-reader-methods.md Shows how to use default variants for optional configuration values, providing sensible default values when a setting is not explicitly provided. ```swift // Optional features with sensible defaults let timeout = config.int(forKey: "http.timeout", default: 30) let retryCount = config.int(forKey: "retries", default: 3) ``` -------------------------------- ### AccessLogger Initialization Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Reference/AccessLogger.md Provides details on how to create and initialize an AccessLogger instance. ```APIDOC ## AccessLogger Initialization ### Description Initializes a new instance of `AccessLogger` with specified logger, level, and message. ### Method `init(logger:level:message:)` ### Parameters This initializer does not have explicit path, query, or request body parameters. The parameters are passed directly during initialization. - **logger** (LoggerProtocol) - The logger instance to use. - **level** (LogLevel) - The logging level for the messages. - **message** (String) - The message to be logged. ### Request Example ```swift let logger = ConsoleLogger() let accessLogger = AccessLogger(logger: logger, level: .info, message: "User accessed resource") ``` ### Response This is an initializer and does not return a value in the traditional sense. It creates an instance of `AccessLogger`. ``` -------------------------------- ### Create and Run ReloadingFileProvider Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Using-reloading-providers.md Create a reloading provider for JSON configuration files and run it within a ServiceGroup. Configure the file path, whether to allow missing files, and the polling interval. ```swift import ServiceLifecycle let provider = try await ReloadingFileProvider( filePath: "/etc/config.json", allowMissing: true, // Optional: treat missing file as empty config pollInterval: .seconds(15) ) let serviceGroup = ServiceGroup( services: [provider], logger: logger ) try await serviceGroup.run() ``` -------------------------------- ### Creating a Directory Files Provider Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Reference/DirectoryFilesProvider.md Initializes a new instance of a directory files provider. This provider can load configuration values from files located in a given directory. ```APIDOC ## Initializing DirectoryFilesProvider ### Description Initializes a new instance of a directory files provider. This provider can load configuration values from files located in a given directory. ### Method `init` ### Parameters #### Path Parameters - **directoryPath** (String) - Required - The path to the directory containing configuration files. - **allowMissing** (Bool) - Optional - If `true`, the provider will not throw an error if the directory is missing. Defaults to `false`. - **secretsSpecifier** (String?) - Optional - A string used to identify secrets within configuration files. - **arraySeparator** (Character?) - Optional - The character used to separate elements in array values within configuration files. ``` -------------------------------- ### Prefixing Configuration Keys Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Example-use-cases.md Wraps an existing provider with a KeyMappingProvider to prepend a constant prefix to all configuration keys. This is useful for namespacing settings, like prepending 'myapp.' to keys. ```swift import Configuration // Create a base provider for environment variables let envProvider = EnvironmentVariablesProvider() // Wrap it with a key mapping provider to automatically prepend "myapp." to all keys let prefixedProvider = envProvider.prefixKeys(with: "myapp") let config = ConfigReader(provider: prefixedProvider) // This reads from the "MYAPP_DATABASE_URL" environment variable. let databaseURL = config.string(forKey: "database.url", default: "localhost") ``` -------------------------------- ### Handle Environment-Specific Optional Configuration Files Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Troubleshooting.md Configure FileProvider to gracefully handle missing environment-specific configuration files by setting `allowMissing: true`. This is useful when different environments may have different config files. ```swift let configPath = "/etc/\(environment)/config.json" let provider = try await FileProvider( filePath: configPath, allowMissing: true // Gracefully handle missing env-specific configs ) ``` -------------------------------- ### FileProvider Initializer with FilePath Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Proposals/SCO-0001.md Creates a FileProvider by directly specifying the snapshot type, parsing options, and the file path. The file is read once upon initialization. ```swift public init( snapshotType: Snapshot.Type = Snapshot.self, parsingOptions: Snapshot.ParsingOptions = .default, filePath: FilePath ) async throws ``` -------------------------------- ### Create InMemoryProvider with basic values Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Using-in-memory-providers.md Instantiate an InMemoryProvider with a dictionary of configuration values. This provider is immutable. ```swift let provider = InMemoryProvider(values: [ "database.host": "localhost", "database.port": 5432, "api.timeout": 30.0, "debug.enabled": true ]) let config = ConfigReader(provider: provider) let host = config.string(forKey: "database.host") // "localhost" let port = config.int(forKey: "database.port") // 5432 ``` -------------------------------- ### FileProvider with allowMissing parameter Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Proposals/SCO-0003.md Demonstrates the new `allowMissing` parameter for `FileProvider`. Set to `true` to prevent initialization failures when the configuration file is missing. ```swift // Current behavior - throws if config.json doesn't exist let provider = try await FileProvider(filePath: "config.json") // New behavior - succeeds even if config.json doesn't exist let provider = try await FileProvider( filePath: "config.json", allowMissing: true ) ``` -------------------------------- ### ConfigBytesFromHexStringDecoder Initialization Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Reference/ConfigBytesFromHexStringDecoder.md Provides information on how to initialize the ConfigBytesFromHexStringDecoder. ```APIDOC ## ConfigBytesFromHexStringDecoder ### Description Initializes a new instance of the hex string decoder. ### Method init() ### Endpoint N/A (This is a class initializer, not an API endpoint) ### Parameters None ### Request Example ```swift let decoder = ConfigBytesFromHexStringDecoder() ``` ### Response N/A (This is an initializer, not an API call with a response) ``` -------------------------------- ### Use ConfigReader with ReloadingFileProvider Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Using-reloading-providers.md Illustrates how to use ConfigReader with a ReloadingFileProvider to watch for configuration changes or read values on demand. This provides live updates and default values. ```swift let config = ConfigReader(provider: provider) // Live updates. try await config.watchDouble(forKey: "timeout") { updates in // Handle changes } // On-demand reads - returns the current value, so might change over time. let timeout = config.double(forKey: "timeout", default: 60.0) ``` -------------------------------- ### Use InMemoryProvider as a fallback Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Guides/Using-in-memory-providers.md Demonstrates configuring a ConfigReader with multiple providers, using an InMemoryProvider as a fallback when environment variables are not set. ```swift let fallbackProvider = InMemoryProvider(values: [ "api.timeout": 30.0, "retry.maxAttempts": 3, "cache.enabled": true ]) let config = ConfigReader(providers: [ EnvironmentVariablesProvider(), fallbackProvider // Used when environment variables are not set ]) ``` -------------------------------- ### Creating a File Access Logger Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Reference/FileAccessLogger.md This snippet shows how to initialize a FileAccessLogger with a specified file path and time zone. ```APIDOC ## Initializing FileAccessLogger ### Description Initializes a new instance of `FileAccessLogger`. ### Method `init(filePath: String, timeZone: TimeZone)` ### Parameters #### Path Parameters - **filePath** (String) - Required - The path to the log file. - **timeZone** (TimeZone) - Required - The time zone to use for logging. ### Request Example ```swift let logger = FileAccessLogger(filePath: "/var/log/app.log", timeZone: TimeZone.current) ``` ### Response #### Success Response (200) N/A (Initializers do not typically return a response in this format). #### Response Example N/A ``` -------------------------------- ### Configuration/ConfigUpdatesAsyncSequence Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Reference/ConfigUpdatesAsyncSequence.md Provides details on creating and managing asynchronous update sequences for configuration. ```APIDOC ## Configuration/ConfigUpdatesAsyncSequence ### Description This section details the creation of asynchronous update sequences for configuration management. ### Topics #### Creating an asynchronous update sequence - ``init(_:)``: Initializes a new asynchronous update sequence. ### Method N/A (This describes a type, not an HTTP endpoint) ### Endpoint N/A ### Parameters N/A ### Request Example N/A ### Response N/A ``` -------------------------------- ### Configure Provider Hierarchy Source: https://github.com/apple/swift-configuration/blob/main/Sources/Configuration/Documentation.docc/Documentation.md Creates a configuration reader that consults multiple providers in a specified order. Environment variables are checked before JSON file values. ```swift // Environment variables consulted first, then JSON. let primaryProvider = EnvironmentVariablesProvider() let secondaryProvider = try await FileProvider( filePath: "/etc/config.json" ) let config = ConfigReader(providers: [ primaryProvider, secondaryProvider ]) let httpTimeout = config.int(forKey: "http.timeout", default: 60) print(httpTimeout) // prints 30 ```