SCL: a new configuration language format

Hey there,

I made this a few months ago but forgot about it, a post on Reddit today about a very similar language made me think it was worth posting afterall: https://github.com/Keats/scl

The main idea is that it has some features needed for configuration like file inclusion (think nginx config) and env variable that are built-in instead of handled by the end program. It is also (imo) more readable than TOML and YAML, which I both find very confusing outside of a trivial example: you can see a few samples at https://github.com/Keats/scl/tree/master/parser/tests/valid

As an example, let's say you have a web app that is loading some configuration, you would have a few files depending on the environment:

# base.scl
debug = false
secret_key =  ${SECRET_KEY}
max_upload_size = 10Mb
# local.scl
include "base.scl"

root_url = "http://localhost:8000"
debug = true
secret_key = "some_default_secret"
# prod.scl
include "base.scl"

root_url = "https://my-site.com"

Loading the config in prod without $SECRET_KEY being set would error for example.

The parser is written and seemingly working despite a few TODOs regarding the grammar but I didn't want to do too much (like serde integration) without getting some feedback first.

Pre-empting answers "why not just use TOML?": no include, no environment variable and very confusing imo once you get some nesting going on

Any thoughts?

1 Like

I find that that's the tool I was looking for a month ago to configure web application ENV variables according to different deploy environmts (a pretty common pratice).

I could not find anything resembling a hierarchical configuration manager that allows me to have a base file that is imported/included by a test, a staging and a production additional file.

I gave a look at the specification and it looks pretty much complete (thinking my use cases). I have two thoughts (just thinking aloud).

1) conditional includes

$ cat general_config.scl
include "base.scl"
deploy_mode = ${DEPLOY_MODE || "STAGING"}
if deploy_mode == "STAGING" {
    include "staging.scl"
}

but you excluded the use case on purpose (doesn't allow any logic in it.) and that's fine - I guess. I can get around this with:

$ export DEPLOY_MODE=STAGING
$ cargo run (loads "staging.scl")

2) how do I load a config file?





-- Thanks!

Keep in mind right now it's more of a preview so I wouldn't use it in production or for anything other than playing around.

The simple way right now is:

use scl::parse_file;
let res = parse_file("local.scl");  // path to the file
1 Like

Why are dates supported but not times? Not that I have a specific use-case in mind but I wonder it here was a specific reason for this design decision.

Mostly start with minimum set of features and add more if necessary: the opposite being much harder.

The reason was that datetimes in configuration files are not THAT common in my experience (I could be wrong though!), it is usually dates and sometimes time if you have some CRON like tasks.