A reasonable configuration language https://rcl-lang.org
Find a file
Ruud van Asseldonk a42ca7ca8e Reformat Python code, silence Mypy error
The .to_bytes() method has a default value for length, but apparently
Mypy does not know that yet. Maybe it is running for an older Python
version.
2024-02-15 23:37:52 +01:00
docs Document TOML output format 2024-02-15 00:38:07 +01:00
etc Add List.enumerate method 2024-02-10 14:37:28 +01:00
examples Finish first draft of the tutorial 2023-12-05 01:01:39 +01:00
fuzz Adjust the schema of the fuzzer, expand corpus 2024-02-15 22:25:49 +01:00
golden Add goldens for TOML exporter 2024-02-15 20:27:30 +01:00
ideas Add some more ideas 2024-01-30 23:57:38 +01:00
pyrcl Use the shared Env type for values 2024-02-10 16:22:06 +01:00
src Add goldens for TOML exporter 2024-02-15 20:27:30 +01:00
tools Reformat Python code, silence Mypy error 2024-02-15 23:37:52 +01:00
.gitignore Add Python venv shell hook 2023-09-24 19:16:53 +02:00
.gitmodules Add basic initial documentation 2023-08-13 21:31:17 +02:00
Cargo.lock Bring fuzz targets into the Cargo workspace 2024-02-10 17:52:59 +01:00
Cargo.toml Bring fuzz targets into the Cargo workspace 2024-02-10 17:52:59 +01:00
CONTRIBUTING.md Add public repository boilerplate 2023-08-10 17:23:35 +02:00
flake.lock Pin Nixpkgs to a version with Rust 1.70 2023-10-03 21:54:04 +02:00
flake.nix Bring fuzz targets into the Cargo workspace 2024-02-10 17:52:59 +01:00
LICENSE License the project under the Apache 2.0 license 2023-08-06 00:38:51 +02:00
mkdocs.yml Document the Python bindings 2024-02-01 21:50:32 +01:00
README.md Add link to blog post to readme 2024-02-04 14:03:41 +01:00
rust-toolchain.toml Pin the toolchain 2023-08-01 23:34:12 +02:00

Ruuds Configuration Language

Ruuds Configuration Language, RCL for short, is a domain-specific language optimized for specifying human-written data with just enough abstraction features to avoid repetition. It is a superset of json that extends it into a simple functional programming language that resembles Python and Nix. Use cases include:

  • Querying json documents, like jq, but with a more familiar language.
  • Generating repetitive configuration files, such as GitHub Actions workflows or Terraform configuration.
  • Enabling large repositories to split configuration into small reusable pieces that can be referenced from a single consistent entry point, in the same way that Nix enables this for Nixpkgs.

RCL can be used through the rcl command-line tool that can export documents to json and other formats. It can also be used through a native Python module, with an interface similar to the json module.

Warning

While RCL is usable, it is still in an early exploratory stage with frequent breaking changes. This is a hobby project without stability promise.

Getting started

See the manual for more information. The most useful chapters to get started:

You may also find the examples in the examples directory instructive.

Rationale

Why another config language?

  • HCL is too ad-hoc to be suitable for any serious abstraction (setunion is variadic so it only works with a statically known number of sets; flatten recursively flattens so it cant be typed properly and breaks generic code, for comprehensions cant do nested loops, for_each syntax is bolted on, etc.)

  • Nix-the-language is great but forces the entire Nix store on you when all I want is to evaluate expressions.

  • Python is great but requires some boilerplate for doing the IO if you want to use it as a configuration language. Also the syntactic order of list comprehensions prevents autocomplete in editors.

  • Dhall has the right ideas but the syntax and heavy use of Unicode symbols make it look ugly.

  • CUE and Nickel were not invented here.

  • For more background, see the blog post: A reasonable configuration language.

Classification

  • Purely functional: RCL documents are expressions that evaluate to values, rather than sequences of statements that have side effects. Values are immutable, there are no mutable objects. Functions are values.

  • Gradually typed: Optional type annotations can be used to prevent bugs and to make code more self-documenting. All type annotations are enforced.

  • Json superset: Vaporware, this is not fully implemented; floats are not yet supported.

Usage

Build:

cargo build --release

Print usage:

target/release/rcl
target/release/rcl eval --help

Evaluate an RCL expression to json:

target/release/rcl eval examples/tags.rcl

Query an RCL or json document:

target/release/rcl query examples/tags.rcl input.tags.ams01

Autoformat an RCL expression (non-destructive, prints to stdout):

target/release/rcl fmt examples/tags.rcl

Highlight an RCL expression in your terminal:

target/release/rcl highlight examples/tags.rcl

Development

Run all tests and checks below in one command:

nix flake check

Run golden tests:

cargo build
golden/run.py

Check the grammar for ambiguities:

bison -Werror=all src/grammar.y

Run unit tests and lints:

cargo test
cargo clippy

Typecheck Python sources

mypy --strict --exclude pyrcl .
mypy --strict pyrcl

Check formatting:

cargo fmt
black .

View coverage of the golden tests:

nix build .#coverage --out-link result
xdg-open result/index.html

Run the fuzzer:

cargo +nightly-2023-06-03 fuzz run main -- -dict=fuzz/dictionary.txt -timout=5

Building the Python module

Build the shared object:

cargo build --manifest-path pyrcl/Cargo.toml

Give the shared object the appropriate name for the Python interpreter to discover it:

mv target/debug/{libpyrcl,rcl}.so

Tell Python where to find the shared object, run the interpreter:

PYTHONPATH=target/debug python3
>>> import rcl
>>> help(rcl.loads)
>>> rcl.load_file("examples/buckets.rcl")

License

RCL is licensed under the Apache 2.0 license. It may be used in free software as well as closed-source applications, both for commercial and non-commercial use under the conditions given in the license. If you want to use RCL in your GPLv2-licensed software, you can add an exception to your copyright notice. Please do not open an issue if you disagree with the choice of license.