A reasonable configuration language https://rcl-lang.org
Find a file
Ruud van Asseldonk be73b4a2c2 Ensure {} is a dict, not a set
This fixes the json compatibility issue. Also update some terminology
from "record" to "dict" now that I'm touching things anyway.
2023-09-24 12:28:45 +02:00
docs Ensure {} is a dict, not a set 2023-09-24 12:28:45 +02:00
etc/rcl.vim Avoid using cluster for Vim highlight 2023-09-23 00:32:07 +02:00
examples Make GitHub Actions example more powerful 2023-09-20 22:47:00 +02:00
fuzz Support colored json output 2023-09-24 00:21:02 +02:00
golden Ensure {} is a dict, not a set 2023-09-24 12:28:45 +02:00
ideas Ensure {} is a dict, not a set 2023-09-24 12:28:45 +02:00
src Ensure {} is a dict, not a set 2023-09-24 12:28:45 +02:00
tools Add a script to migrate the fuzz corpus 2023-09-23 22:26:21 +02:00
.gitignore Add a Nix flake 2023-08-11 20:36:37 +02:00
.gitmodules Add basic initial documentation 2023-08-13 21:31:17 +02:00
Cargo.lock Add pretty reporting of errors 2023-08-08 22:20:20 +02:00
Cargo.toml Strip release binary by default 2023-08-28 23:01:58 +02:00
CONTRIBUTING.md Add public repository boilerplate 2023-08-10 17:23:35 +02:00
flake.lock Add a Nix flake 2023-08-11 20:36:37 +02:00
flake.nix Put LLVM coverage report in output too 2023-08-15 23:50:59 +02:00
LICENSE License the project under the Apache 2.0 license 2023-08-06 00:38:51 +02:00
mkdocs.yml Add installation guide to the docs 2023-09-23 18:29:29 +02:00
README.md Fix typo in docs and readme 2023-09-24 01:00:28 +02:00
rust-toolchain.toml Pin the toolchain 2023-08-01 23:34:12 +02:00

Ruuds Configuration Language

Warning: RCL is vaporware. It is a proof-of-concept toy project. I will likely lose interest in it before it is mature enough for serious use.

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.

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.

Classification

  • Purely functional: RCL consists of expressions and has no statements. It has immutable values and no mutable objects. Functions are values.

  • Vaporware, not fully implemented: RCL is a superset of json.

  • Vaporware, not implemented: RCL should be statically typed, in the sense that errors in unreachable code should cause evaluation to fail.

  • Vaporware, not implemented: RCL should be structurally typed with Hindley-Milner-style type inference. Types should not be first-class, in the sense that the type and value namespaces dont mix, and you cant bind types to variables.

  • Strictly evaluated. Maybe it should become lazily evaluated when you want to build something big like Nixpkgs with it; for now strict is fast enough.

Usage

Build:

cargo build

Evaluate an RCL expression to json:

target/debug/rcl eval examples/tags.rcl

Query an RCL or json document:

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

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

target/debug/rcl fmt examples/tags.rcl

Highlight an RCL expression in your terminal:

target/debug/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 .

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

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.