Skip to content

Commit

Permalink
Update readme
Browse files Browse the repository at this point in the history
  • Loading branch information
bolshakov committed Oct 20, 2024
1 parent 9a833dc commit 47af3de
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 33 deletions.
125 changes: 94 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,42 @@
# ⚙️ConfigX

ConfigX is a simple configuration library that you can use with your application or libraries.

ConfigX is NOT that kind of library that allows you configuring any Ruby object, instead
it takes a different approach. It reads configuration from YAML files and environment variables
and load it into a ruby object. It's highly influenced by the [config] gem, but it does
not define a global objects and allows you having multiple independent configurations.
ConfigX is a lightweight configuration library that helps you manage settings for applications or libraries.
Unlike other configuration libraries, ConfigX does not allow configuring arbitrary Ruby objects. Instead,
it focuses on loading configuration from YAML files and environment variables into structured Ruby objects.
Inspired by the [config] gem, ConfigX avoids defining global objects and supports multiple
independent configurations.

## Installation

Install the gem and add to the application's Gemfile by executing:
To install, add the gem to your Gemfile:

$ bundle add configx
```bash
$ bundle add configx
```

If bundler is not being used to manage dependencies, install the gem by executing:
Or, if you’re not using Bundler:

$ gem install configx
```bash
$ gem install configx
```

## Usage

Start using the library as simple as loading configuration from default locations:
To load configuration from the default locations, use:

```ruby
config = ConfigX.load
```

It loads configuration from the following locations in the specified order:
This loads configuration from the following sources in order:

1. `config/settings.yml`
2. `config/settings/production.yml`
3. `config/settings.local.yml`
4. `config/settings/production.local.yml`
5. Environment variables

All the configuration source are merged an intuitive way. For instance,
The configuration is merged in an intuitive way, with environment variables taking precedence. For example:

* **config/settings.yml**

Expand All @@ -59,7 +62,7 @@ api:
export SETTINGS__API__ACCESS_TOKEN=foobar
```

The resulting configuration will be:
Results in:

```ruby
config = ConfigX.load
Expand All @@ -70,7 +73,7 @@ config.api.access_token # => "foobar"

### Customizing Configuration

You can customize the configuration by passing optional arguments to the `load` method:
You can customize how configurations are loaded:

```ruby
ConfigX.load(
Expand All @@ -83,44 +86,104 @@ ConfigX.load(
)
```

The first four options, `env` (positional), `dir_name`, `file_name`, and `config_root` are used to specify
the configuration files to read:
Explanation of options:

* `env`, `dir_name`, `file_name`, and `config_root` specify where to look for configuration files.

In this example ConfigX will look for configuration files in the following order:

1. `{config_root}/{file_name}.yml`
2. `{config_root}/{file_name}/{env}.yml`
3. `{config_root}/{file_name}.local.yml`
4. `{config_root}/{file_name}/{env}.local.yml`

* `env_prefix` and `env_separator` define how environment variables map to configuration keys.

The `env_prefix` and `env_separator` options are used to specify how the environment variables should be constructed. In
the above example, they start from `SETTINGS` and use `__` as a separator.

For instance, the following environment variable:
For example, with the following environment variable:

```
export SETTINGS__API__ACCESS_TOKEN=foobar
```

corresponds to the following configuration:
ConfigX loads it into:

```yaml
---
api:
access_token: foobar
```
You can also pass boolean value to environment variables using convenient YAML syntax:
### Environment Variable Parsing
ConfigX automatically parses environment variable values and converts them to the appropriate types where possible.
It handles strings, booleans, numbers, and even arrays. The following types are supported:
#### Booleans:
```sh
```bash
export SETTINGS__API__ENABLED=true
export SETTINGS__API__ENABLED=false
export SETTINGS__API__ENABLED=on
export SETTINGS__API__ENABLED=off
```

Environment variables have the highest priority and override the values from the configuration files.
These values will be parsed into their corresponding boolean types (`true` or `false`):

```ruby
config.api.enabled # => true or false
```

#### Numbers:

```bash
export SETTINGS__API__RETRY_COUNT=5
export SETTINGS__API__TIMEOUT=30.5
```

Numeric values will be parsed as either integers or floats:

```ruby
config.api.retry_count # => 5
config.api.timeout # => 30.5
```


#### Arrays:

Sometimes you may want to just load configuration from a single source, for example, from for testing purposes:
Arrays can be specified by using comma-separated values:

```bash
export SETTINGS__API__SERVERS='["server1","server2","server3"]'
```

This will be parsed as an array:

```ruby
config.api.servers # => ["server1", "server2", "server3"]
```


#### Strings:

Regular string values remain unchanged:

```bash
export SETTINGS__API__ACCESS_TOKEN="my_secret_token"
```

This will simply be loaded as a string:

```ruby
config.api.access_token # => "my_secret_token"
```

Environment variables have the highest precedence and will override values from YAML configuration files.
This ensures that any environment-specific settings can be applied without modifying the configuration
files themselves.

### Loading Single Sources

To load configuration from a specific source (e.g., during testing):

```ruby
config = ConfigX.from({api: {enabled: true}})
Expand All @@ -129,8 +192,7 @@ config.api.enabled # => true

### Typed Config

ConfigX allows you to define typed configuration using the `ConfigX::Config` class which uses the `dry-struct` library
under the hood.
ConfigX supports typed configurations using `ConfigX::Config`, which leverages [dry-struct]:

```ruby
class Config < ConfigX::Config
Expand All @@ -142,16 +204,16 @@ class Config < ConfigX::Config
end
```

You can then load the configuration using the `load` method:
Load the typed configuration with:

```ruby
config = ConfigX.load(config_class: Config)
config.api.enabled #=> true
config.api.endpoint #=> "https://example.com"
```

Using typed configuration allows you to define the structure of the configuration and automatically cast values to the
specified types.
Typed configurations enforce structure and type-checking.

## Development

After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
Expand All @@ -167,3 +229,4 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/bolsha
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).

[config]: https://rubygems.org/gems/config
[dry-struct]: https://dry-rb.org/gems/dry-struct/
6 changes: 4 additions & 2 deletions spec/config_x/env_source_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@
"MY_CONFIG__SIX" => "42",
"MY_CONFIG__SEVEN" => "64.4",
"MY_CONFIG__EIGHT" => "foo,bar",
"MY_CONFIG__NINE" => '["foo","bar"]'
"MY_CONFIG__NINE" => '["foo","bar"]',
"MY_CONFIG__TEN" => "- foo\n- bar"
}
end

Expand All @@ -73,7 +74,8 @@
"six" => 42,
"seven" => 64.4,
"eight" => "foo,bar",
"nine" => ["foo", "bar"]
"nine" => ["foo", "bar"],
"ten" => ["foo", "bar"]
})
end
end
Expand Down

0 comments on commit 47af3de

Please sign in to comment.