Skip to content

Commit

Permalink
Merge pull request #205 from nickel-lang/modules
Browse files Browse the repository at this point in the history
Use a module system for the different integrations
  • Loading branch information
thufschmitt authored Jun 20, 2024
2 parents 7b3a104 + 88b3dc7 commit b0585da
Show file tree
Hide file tree
Showing 20 changed files with 469 additions and 294 deletions.
7 changes: 7 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## HEAD

### Breaking changes

- The overall structure has been reshaped to use a NixOS-modules-like interface.
XXX: Extend and explain how to migrate

## Version 0.1 (2023-11-16)

First release (🎉)
24 changes: 14 additions & 10 deletions doc/dependency-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,21 @@ After running `nix flake init`, you should end-up with a `project.ncl` looking l
let inputs = import "./nickel.lock.ncl" in
let organist = inputs.organist in
{
shells = organist.shells.Bash,
shells.build = {
packages = {},
},
shells.dev = {
packages.hello = organist.lib.import_nix "nixpkgs#hello",
organist.contracts.OrganistExpression
& {
Schema,
config | Schema = {
shells = organist.shells.Bash,
shells.build = {
packages = {},
},
shells.dev = {
packages.hello = organist.lib.import_nix "nixpkgs#hello",
},
},
} | organist.contracts.OrganistExpression
} | organist.modules.T
```

This defines two variants of the shell: `build` and `dev`, both of which inherit from `organist.shells.Bash` (more precisely, `build` inherits from `organist.shells.Bash.build` and `dev` inherits from `organist.shells.Bash.dev`).
Expand Down
74 changes: 74 additions & 0 deletions doc/migrate-from-0.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Migrating from 0.1

Since 0.2, Organist uses a [module system] for the configuration.
This means that the `project.ncl` is now a module, with a slightly different interface.

## Migrating `project.ncl`

In the vast majority of cases, the migration consists of three things:

1. Declare a new `Schema` field;
2. Move all the options under a `config` field;
3. Replace the schema by `organist.module.T`, and instead merge the config with the previous schema.

As an example is probably more eloquent, this means rewriting:

```nickel
{
shells = …,
foo = bar,
} | (organist.OrganistExpression & organist.something.Schema & organist.somethingElse.Schema)
```

into:

```nickel
organist.OrganistExpression
& organist.something
& organist.somethingElse
& {
Schema,
config | Schema = {
shells = …,
foo = bar,
},
} | organist.module.T
```

## Migrating custom modules

Migrating custom modules is similar, except that
1. The module system now separates the _declaration_ of options from their _definition_ (respectively the `Schema` and `config` fields)
2. Modules must now merge with all of their dependencies (the modules whose option they use).

For instance, an hypothetical module like the one below:

```nickel
{
readme.content
| doc "Content of the README file"
| String,
files."foo".content = readme.content,
}
```

should be rewritten to

```nickel
(import organist.files) # Because we set the `files` option which is defined there
& {
# New options defined by the module
Schema = {
readme.content
| doc "Content of the README file"
| String,
},
# Implementation of the module, setting options from other modules
config | Schema = {
readme,
files."foo".content = readme.content,
},
}
```
10 changes: 4 additions & 6 deletions doc/services.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ For instance, if the `project.ncl` contains:

```nickel
let redis_listen_port = 64442 in
{
services.redis = nix-s%"%{organist.import_nix "nixpkgs#redis"}/bin/redis-server --port %{std.to_string redis_listen_port}"%,
organist.OrganistExpression
& organist.services
& {
config.services.redis = nix-s%"%{organist.import_nix "nixpkgs#redis"}/bin/redis-server --port %{std.to_string redis_listen_port}"%,
}
| (
organist.OrganistExpression
& organist.services.Schema
)
```

then running `nix run .#start-services start` will run a local `redis` instance listening on port 64442.
Expand Down
44 changes: 24 additions & 20 deletions examples/c-hello-world/project.ncl
Original file line number Diff line number Diff line change
@@ -1,30 +1,34 @@
let inputs = import "./nickel.lock.ncl" in
let organist = inputs.organist in

{
flake.packages."default" = flake.packages.hello,
flake.packages.hello =
organist.nix.builders.NixpkgsPkg
& {
name = "hello",
version = "0.1",
structured_env.buildInputs = {
gcc = organist.import_nix "nixpkgs#gcc",
coreutils = organist.import_nix "nixpkgs#coreutils",
bash = organist.import_nix "nixpkgs#bash",
},
env.src = organist.nix.builtins.import_file ".",
env.buildCommand =
nix-s%"
organist.OrganistExpression
& {
Schema,
config | Schema = {
flake.packages."default" = flake.packages.hello,
flake.packages.hello =
organist.nix.builders.NixpkgsPkg
& {
name = "hello",
version = "0.1",
structured_env.buildInputs = {
gcc = organist.import_nix "nixpkgs#gcc",
coreutils = organist.import_nix "nixpkgs#coreutils",
bash = organist.import_nix "nixpkgs#bash",
},
env.src = organist.nix.builtins.import_file ".",
env.buildCommand =
nix-s%"
cp $src/* .
mkdir -p $out/{include,lib}
gcc -shared hello.c -o libhello.so
cp *.so $out/lib/
cp hello.h $out/include/hello.h
"%
| organist.nix.derivation.NixString,
},
| organist.nix.derivation.NixString,
},

shells = organist.shells.Bash,
shells.build.packages.hello = flake.packages.hello,
} | organist.OrganistExpression
shells = organist.shells.Bash,
shells.build.packages.hello = flake.packages.hello,
},
} | organist.modules.T
27 changes: 14 additions & 13 deletions examples/direnv/project.ncl
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
let inputs = import "./nickel.lock.ncl" in
let organist = inputs.organist in

{
shells = organist.shells.Bash,
organist.OrganistExpression
& organist.tools.direnv
& {
Schema,
config | Schema = {
shells = organist.shells.Bash,

shells.build = {
packages = {},
},
shells.build = {
packages = {},
},

shells.dev = {
packages.direnv = organist.import_nix "nixpkgs#direnv"
},
}
| (
organist.OrganistExpression
& organist.tools.direnv.Schema
)
shells.dev = {
packages.direnv = organist.import_nix "nixpkgs#direnv"
},
},
} | organist.modules.T
44 changes: 23 additions & 21 deletions examples/filegen/project.ncl
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
let inputs = import "./nickel.lock.ncl" in
let organist = inputs.organist in

{
shells = organist.shells.Bash,
organist.OrganistExpression
& organist.tools.editorconfig
& {
Schema,
config | Schema = {
shells = organist.shells.Bash,

shells.build = {
packages = {},
},
shells.build = {
packages = {},
},

shells.dev = {
packages.hello = organist.import_nix "nixpkgs#hello",
},
shells.dev = {
packages.hello = organist.import_nix "nixpkgs#hello",
},

editorconfig.sections = {
"*".indent_style = 'space,
"*".indent_size = 2,
"*".insert_final_newline = true,
"Makefile".indent_style = 'tab,
"*.py" = {
indent_style = 'space,
indent_size = 4,
editorconfig.sections = {
"*".indent_style = 'space,
"*".indent_size = 2,
"*".insert_final_newline = true,
"Makefile".indent_style = 'tab,
"*.py" = {
indent_style = 'space,
indent_size = 4,
},
},
},
},
}
| (
organist.OrganistExpression
& organist.tools.editorconfig.Schema
)
| organist.modules.T
34 changes: 19 additions & 15 deletions examples/raw_nix_expression/project.ncl
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
let inputs = import "./nickel.lock.ncl" in
let organist = inputs.organist in

{
shells = organist.shells.Bash,
organist.OrganistExpression
& {
Schema,
config | Schema = {
shells = organist.shells.Bash,

shells.build = {
packages = {},
},
shells.build = {
packages = {},
},

shells.dev = {
packages.python =
organist.nix.derivation.CallNix
& {
function = m%"
shells.dev = {
packages.python =
organist.nix.derivation.CallNix
& {
function = m%"
{ python }: python.withPackages (p: [p.pyyaml])
"%,
args = {
python = organist.import_nix "nixpkgs#python3"
},
args = {
python = organist.import_nix "nixpkgs#python3"
},
},
},
},
} | organist.OrganistExpression
},
} | organist.modules.T
65 changes: 34 additions & 31 deletions examples/services/project.ncl
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,46 @@ let organist = inputs.organist in
let postgres_listen_port = 64441 in
let redis_listen_port = 64442 in

{
shells = organist.shells.Bash,
organist.OrganistExpression
& organist.tools.editorconfig
& organist.services
& {

shells.build = {
packages = {},
},
Schema,
config | Schema = {
shells = organist.shells.Bash,

shells.dev = {
packages = {
postgresql = organist.import_nix "nixpkgs#postgresql",
redis = organist.import_nix "nixpkgs#redis",
honcho = organist.import_nix "nixpkgs#honcho",
},
env.POSTGRES_PORT = "%{std.to_string postgres_listen_port}",
env.REDIS_URI = "redis://localhost:%{std.to_string redis_listen_port}",
},
shells.build = {
packages = {},
},

shells.dev = {
packages = {
postgresql = organist.import_nix "nixpkgs#postgresql",
redis = organist.import_nix "nixpkgs#redis",
honcho = organist.import_nix "nixpkgs#honcho",
},
env.POSTGRES_PORT = "%{std.to_string postgres_listen_port}",
env.REDIS_URI = "redis://localhost:%{std.to_string redis_listen_port}",
},

services = {
postgres =
let start_script =
{
name = "start-postgres",
runtime_inputs.postgres = organist.import_nix "nixpkgs#postgresql",
content.text = nix-s%"
services = {
postgres =
let start_script =
{
name = "start-postgres",
runtime_inputs.postgres = organist.import_nix "nixpkgs#postgresql",
content.text = nix-s%"
mkdir -p ./.postgres-data
initdb ./.postgres-data
postgres -D ./.postgres-data -k "$PWD/.postgres-data" -p %{std.to_string postgres_listen_port}
"%
} | organist.nix.builders.ShellApplication
in
nix-s%"%{start_script}/bin/start-postgres"%,
redis = nix-s%"%{organist.import_nix "nixpkgs#redis"}/bin/redis-server --port %{std.to_string redis_listen_port}"%,
},
} | organist.nix.builders.ShellApplication
in
nix-s%"%{start_script}/bin/start-postgres"%,
redis = nix-s%"%{organist.import_nix "nixpkgs#redis"}/bin/redis-server --port %{std.to_string redis_listen_port}"%,
},
},
}
| (
organist.OrganistExpression
& organist.tools.editorconfig.Schema
& organist.services.Schema
)
| organist.modules.T
Loading

0 comments on commit b0585da

Please sign in to comment.