Go to file
Alexandr Goncharov 780aa86403
build workflow testing
2020-06-24 20:56:42 +03:00
.github/workflows build workflow testing 2020-06-24 20:56:42 +03:00
.vscode remove app launch option from vscode 2020-06-12 18:47:58 +03:00
Sources/Conf Adding TOC to the README 2020-06-24 20:23:36 +03:00
Tests Add require tests 2020-06-12 18:47:58 +03:00
scripts Initial commit 2020-06-09 13:08:17 +03:00
.drone.jsonnet Initial commit 2020-06-09 13:08:17 +03:00
.gitignore Ignore Xcode settings generated for Package.swift 2020-06-09 13:28:22 +03:00
.swiftlint.yml Initial commit 2020-06-09 13:08:17 +03:00
CHANGELOG.md Add custom parsers support 2020-06-12 18:47:58 +03:00
LICENSE Initial commit 2020-06-09 13:08:17 +03:00
Package.swift Add swift language version to the package manifest 2020-06-24 20:23:36 +03:00
README.md Add github badge 2020-06-24 20:38:54 +03:00

README.md

Conf

Config made easy

Build status Build Status Swift 5

This package provide easy way to work with configs. Mostly usefull in CLI-tools. Extentable and customisable.

Contents

Usage

For more details please refer the tests

Creating the config

let config = Config(useEnvironment: true)

Load configurations

try config.load(.file(name: ".env.dev"))
// or
let url = Bundle.main.url(forResource: "myConfig", withExtension: "plist")!
try config.load(.url(url), format: .plist)
// or
let json = """
{"key": "value"}
"""
try config.load(.string(json), format: .json)

Data representation

All values are stored as Key-String pairs. There are convenience methods to use LosslessStringConvertible.

The Key represents the value position in the provided source.

For basic key-value formats it is just a string.

For nested types key is the array of strings.

Arrays are mapped as multiple key-value pairs:

Key<arrayName, 0> = <first element>
Key<arrayName, 1> = <second element>
...
Key<arrayName, count-1> = <last element>

Reading the value

Values can be accessed via subscripts

let path: String? = config["PATH"]

let port: Int? = config["HTTP_PORT"]

let key = Key("myKey")
let value = config[key]

let value = config[["key", "nested"]]

let value = config[["array", 2]]

extension Key {
    static let clientId = Key("SECRET_CLIENT_ID")
}

let value = config[.clientId]

Require the value

For required values you can use require method which throws ConfigurationError.missing(key:) if value is not found.

let requiredValue = try config.require("secret")

struct MyCredentials {
    let username: String
    let password: String
}

extension Config {
    func credentials() throws -> MyCredentials {
        try MyCredentials(username: require("username"),
                          password: require("password"))
    }
}

Updating values

Values can be updated via subscript

config["foo"] = "bar"
config["answer"] = 42

Creating the keys

let key: Key = "myKey"
let key: Key = 99
let key: Key = Key(23.4)
let key: Key = Key("some")
let key: Key = ["24", 72, 23.4, true]
let key: Key = Key([1, 2, 3])

Working with process environment

Conf can fallback to the environment variables. This is controlled by useEnvironment variable in the constructor.

Env values can be assessed separately with Environment

let env = Environment()
let home = env["HOME"]
let path = env.PATH
env.TMPDIR = "/tmp"

Customisation

Adding data format

If you want to add support for different config format you just need to implement your own parser function and call load with Format.custom.

For example here is how yaml support can be added with Yams

let yamlParser: ParserType = { data in
    guard let rawYaml = String(data: data, encoding: .utf8),
        let values = try Yams.load(yaml: rawYaml) as? [String: Any]
        else {
            struct InvalidYaml: Error {}
            throw InvalidYaml()
    }
    return values
}

try config.load(.file(name: "config.yml"), format: .custom(yamlParser))

Custom parsing

It is also possbile to provide completelly custom implementation of the data fetching behaviour. To do this you need to adopt ConfigurationProvider

struct CustomConfigurationProvider: ConfigurationProvider {
    func configuration() throws -> [Key : String] {
        return ["key": "value"]
    }
}
config.load(from: CustomConfigurationProvider())

TODO

  • Cocoapods support
  • Carthage support
  • Github mirror