mirror of
https://github.com/tweag/nickel.git
synced 2024-10-06 16:18:08 +03:00
172 lines
5.5 KiB
Markdown
172 lines
5.5 KiB
Markdown
# The Nickel developer guide
|
|
|
|
There are two ways to set up a development environment for Nickel: using
|
|
[Nix][nix], or directly via your preferred system package manager. Nix is able
|
|
to drop you in a development shell with everything needed (the Rust toolchain,
|
|
mostly) to hack on Nickel in one command, without installing anything globally
|
|
on your system. _While Nix is also capable of building Nickel by itself, using
|
|
cargo (either a system-wide installation or the one given by the Nix development
|
|
shell) is the recommended way of building when working on the Nickel repository
|
|
itself_. The reason is that incremental compilation for Rust and Nix is not
|
|
there yet, and incremental rebuilds using only Nix are going to be painfully
|
|
long.
|
|
|
|
## Content
|
|
|
|
The Nickel repository consist in 3 crates:
|
|
|
|
- `nickel-lang` (path: `.`). The main crate containing the interpreter as a
|
|
library as well as the `nickel` binary.
|
|
- `nickel-lang-lsp` (path: `lsp/nls/`). the Nickel Language Server (NLS), an LSP
|
|
server for Nickel.
|
|
- `nickel-lang-utilities`: (path: `utilities/`). An auxiliary crate regrouping
|
|
helpers for tests and benchmarks. Not required to build `nickel` itself.
|
|
|
|
Other noteworthy items:
|
|
|
|
- The user manual in `doc/manual/`, as a bunch of markdown files.
|
|
- A VSCode extension for NLS in `lsp/client-extension/`.
|
|
|
|
## Setup a development environment
|
|
|
|
### Using Nix
|
|
|
|
To set up a development environment using a recent Nix (>= 2.4):
|
|
|
|
1. Clone the repository: `git clone git@github.com:tweag/nickel.git`
|
|
2. At the root of the repository, run `nix develop`. You should now be dropped
|
|
in a shell with all the required tool to hack on Nickel (`rust`, `cargo`,
|
|
etc.)
|
|
|
|
### Without Nix
|
|
|
|
Otherwise, you can install the Rust toolchain separately: follow the
|
|
instructions of the [Rust installation guide][install-rust].
|
|
|
|
## Building
|
|
|
|
You can build all crates at once:
|
|
|
|
```shell
|
|
$ cargo build --all
|
|
$ ./target/debug/nickel --version
|
|
nickel-lang 0.1.0
|
|
$ ./target/debug/nls --version
|
|
nickel-lang-lsp 0.1.0
|
|
```
|
|
|
|
### Nickel
|
|
|
|
To only build the main crate `nickel-lang`, run:
|
|
|
|
```shell
|
|
$ cargo build
|
|
$ ./target/debug/nickel --version
|
|
nickel-lang 0.1.0
|
|
```
|
|
|
|
### NLS (nickel-lang-lsp)
|
|
|
|
To build NLS separately, the LSP server for Nickel, build the `nickel-lang-lsp` crate:
|
|
|
|
```shell
|
|
$ cargo build -p nickel-lang-lsp
|
|
$ ./target/debug/nls --version
|
|
nickel-lang-lsp 0.1.0
|
|
```
|
|
|
|
(Alternatively, you can run `cargo build` directly inside `lsp/nls/`).
|
|
|
|
### WebAssembly REPL
|
|
|
|
There is a WebAssembly (WASM) version of the REPL, which is used for the online
|
|
playground on [nickel-lang.org][nickel-lang.org]. To ease the build, we use the
|
|
`nickel-repl` located in `nickel-wasm-repl`, which just wraps and re-export
|
|
the `nickel-lang` with the right settings for building to WebAssembly.
|
|
|
|
The Nix flake has also an output to do the whole build, but incremental
|
|
compilation is not as good as with direct usage of `cargo`.
|
|
|
|
Both methods are described below.
|
|
|
|
#### Using Nix
|
|
|
|
At the root of the repository:
|
|
|
|
```shell
|
|
$ nix build .#buildWasm
|
|
$ ls result/nickel-repl
|
|
LICENSE package.json nickel_lang_bg.js nickel_lang_bg.wasm [..]
|
|
```
|
|
|
|
#### Using Cargo
|
|
|
|
1. [Install `wasm-pack`][install-wasm-pack]
|
|
2. Run `wasm-pack` on the `nickel-repl` crate:
|
|
|
|
```shell
|
|
cd nickel-repl-wasm
|
|
wasm-pack build -- --no-default-features --features repl-wasm
|
|
```
|
|
|
|
A `pkg` directory, containing the corresponding NPM package, should now be
|
|
available.
|
|
|
|
## Testing
|
|
|
|
Tests are run via `cargo test`. They are two types of tests:
|
|
|
|
- Unit tests, located directly in the corresponding module.
|
|
- Integration tests, located in the dedicated crate `tests`.
|
|
|
|
You can take inspiration from the existing tests to add your own. By convention,
|
|
tests expected to pass are written in a standalone Nickel file in `tests/pass/`.
|
|
Each `.ncl` file defines a list of expressions that must individually evaluate
|
|
to the boolean `true`. The whole file is an expression that returns true if and
|
|
only if every tests pass, or fail with a contract failure to help locating the
|
|
failing test (instead of returning just `false`).
|
|
|
|
If a test expected to pass is failing, run it directly using nickel with `nickel
|
|
-f tests/pass/test_that_doesnt_pass.ncl` to get better error messages than
|
|
`cargo test`.
|
|
|
|
Tests expected to fail are often embedded directly into rust source code,
|
|
because you usually want to additionally check that the error is the one you
|
|
expect. For example ([`tests/records_fail.rs`](./tests/records_fail.rs)):
|
|
|
|
```rust
|
|
#[test]
|
|
fn non_mergeable() {
|
|
assert_matches!(
|
|
eval("({a=1} & {a=2}).a"),
|
|
Err(Error::EvalError(EvalError::MergeIncompatibleArgs(..)))
|
|
);
|
|
assert_matches!(
|
|
eval("({a | default = false} & {a | default = true}).a"),
|
|
Err(Error::EvalError(EvalError::MergeIncompatibleArgs(..)))
|
|
);
|
|
}
|
|
```
|
|
|
|
## Benchmarking
|
|
|
|
If your change is likely to impact performance, it is recommended to run the
|
|
benchmark suite on master and on your branch to assess any performance changes.
|
|
Please report your findings in the description of the PR.
|
|
|
|
The benchmark suite is located in the `benches/` directory. To run it:
|
|
|
|
```shell
|
|
cargo bench
|
|
```
|
|
|
|
Note that a full run takes some time, up to a dozen of minutes. You can run
|
|
specific benchmarks instead of the full suite. Please refer to the documentation
|
|
of [`cargo bench`][doc-cargo-bench].
|
|
|
|
[nix]: https://nixos.org/
|
|
[install-rust]: https://www.rust-lang.org/tools/install
|
|
[install-wasm-pack]: https://rustwasm.github.io/wasm-pack/installer/
|
|
[doc-cargo-bench]: https://doc.rust-lang.org/cargo/commands/cargo-bench.html
|
|
[nickel-lang.org]: https://nickel-lang.org
|