Skip to content

Commit

Permalink
top-level refactor
Browse files Browse the repository at this point in the history
For very simple flakes, it doesn't make sense to create a whole folder
structure.

ADDITIONS:

* Add a top-level package.nix that maps to `packages.<system>.default`
* Add a top-level formatter.nix that maps to `formatter.<system>` and `packages.<system>.formatter`.
* Load devshells from the devshells/ folder.

CHANGES:

* perSystem values now merge legacyPackages and packages in that order.
* packages are loaded with `callPackage`.

BREAKING:
* Remove `packages/<pname>/package.nix` as it makes the interface too
  complicated.
* lib/default.nix: take `{ flake, inputs }:` instead of `inputs`.
  • Loading branch information
zimbatm committed Jun 25, 2024
1 parent 73e1f31 commit fdc4ac6
Show file tree
Hide file tree
Showing 7 changed files with 371 additions and 246 deletions.
21 changes: 6 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
## What's blueprint?

Blueprint is a light framework that replaces Nix glue code with a regular folder structure. Focus on deploying your infrastructure / package sets instead of reinventing the wheel.
Blueprint replaces Nix glue code by a regular folder structure. Focus on deploying your infrastructure / package sets instead of reinventing the wheel.

The ambition is to handle all the workflows to reduce the cost of self-hosting infrastructure (we're not quite there yet).

Expand All @@ -27,18 +27,20 @@ In some ways, this is the spiritual successor to `flake-utils`, my first
attempt at making flakes easier to use.

What it's good for:

* Home and SME configurations
* Package sets

What it's bad for:

* Complicated setups (although we try to provide gracefull fallback)
* Developer environments (see devenv.sh)

## Design principles

* User workflows come first.
* KISS. We don't need complicated module systems with infinite recursions.
* 1:1 mapping. Keep the mapping between attributes predictable.
* Think about user workflows.

## Features

Expand All @@ -54,14 +56,6 @@ What it's bad for:
* Darwin configurations
* devshell

## Blacklisted inputs

In order to avoid name clashes, avoid loading inputs with the following names:
* lib
* pname
* system
* pkgs

## Packages folder

If the ./pkgs folder exists, load every sub-folder in it and map it to the `packages` output.
Expand All @@ -80,12 +74,9 @@ Don't

Don't


## Related projects

* [flake-utils](https://github.com/numtide/flake-utils) the OG for flake libraries.
* [flake-utils-plus]() extending flake-utils with more stuff.
* [flake-parts](https://flake.parts) uses the Nix module system. It's too complicated for my taste.
* [std]() ??
* [snowflake-lib](TODO)

* [std](https://github.com/divnix/std)
* [snowflake-lib](https://github.com/snowfallorg/lib)
64 changes: 43 additions & 21 deletions docs/folder-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@

## High-level

* `devshell.nix` for your developer shell.
* `devshells/` for devshells.
* `hosts/` for machine configurations.
* `lib/` for Nix functions.
* `modules/` for NixOS and other modules.
* `pkgs/` for packages.
* `packages/` for packages.
* `templates/` for flake templates.

* `devshell.nix` for the default devshell
* `formatter.nix` for the default formatter
* `package.nix` for the default package

## File arguments

Each file typically gets passed a number of arguments.
Expand All @@ -20,23 +24,26 @@ Some of the files are instantiated multiple times, once per configured system. S
Those take the following arguments:

* `inputs`: maps to the flake inputs.
* `flake`: maps to the flake itself. It's a shorthand for `inputs.self`.
* `system`: the current system attribute.
* `perSystem`: contains the packages of all the inputs, filtered per system.
Eg: `perSystem.nixos-anywhere.default` is a shorthand for `inputs.nixos-anywhere.packages.<system>.default`.
* `flake`: points to the current flake. It's a shorthand for `inputs.self`.
* `pkgs`: and instance of nixpkgs, see [configuration](configuration.md) on how it's configured.

## Mapping

### `devshell.nix`
### `devshell.nix`, `devshells/<pname>(.nix|/default.nix)`

Contains the developer shell if specified.

Called with the [per-system](#per-system) attributes.
Inputs:

The [per-system](#per-system) values, plus the `pname` attribute.

Flake outputs:
* `devShells.<system>.default`
* `checks.<system>.devshell`

* `devShells.<system>.<pname>`
* `checks.<system>.devshell-<pname>`

#### Example

Expand All @@ -50,7 +57,7 @@ pkgs.mkShell {
}
```

### `hosts/<hostname>/(configuration.nix|darwin-configuration.nix)`
### `hosts/<hostname>/(configuration.nix|darwin-configuration.nix)`

Each folder contains either a NixOS or nix-darwin configuration:

Expand All @@ -59,10 +66,12 @@ Each folder contains either a NixOS or nix-darwin configuration:
Evaluates to a NixOS configuration.

Additional values passed:

* `inputs` maps to the current flake inputs.
* `flake` maps to `inputs.self`.

Flake outputs:

* `nixosConfigurations.<hostname>`
* `checks.<system>.nixos-<hostname>` - contains the system closure.

Expand All @@ -87,35 +96,43 @@ Flake outputs:
Evaluates to a [nix-darwin](https://github.com/LnL7/nix-darwin) configuration.

To support it, also add the following lines to the `flake.nix` file:

```nix
{
inputs.nix-darwin.url = "github:LnL7/nix-darwin";
}
```

Additional values passed:

* `inputs` maps to the current flake inputs.
* `flake` maps to `inputs.self`.

Flake outputs:

* `darwinConfiguration.<hostname>`
* `checks.<system>.darwin-<hostname>` - contains the system closure.

### `lib/default.nix`

Loaded if it exists.

It takes the `inputs` as a positional argument.
Inputs:

* `flake`
* `inputs`

Flake outputs:

* `lib` - contains the return value of `lib/default.nix`

Eg:

```nix
inputs:
{ flake, inputs }:
{ }
```

Flake outputs:
* `lib` - contains the return value of `lib/default.nix`

### `modules/<type>/(<name>|<name>.nix)`

Where the type can be:
Expand All @@ -125,24 +142,28 @@ Where the type can be:

These and other unrecognized types also make to `modules.<type>.<name>`.

### `packages/<pname>/(default.nix|package.nix)`
### `package.nix`, `formatter.nix`, `packages/<pname>(.nix|/default.nix)`

This `packages/` folder contains all your packages.

This folder contains all your packages.
For single-package repositories, we also allow a top-level `package.nix` that
maps to the "default" package.

Inputs:

The [per-system](#per-system) values, plus the `pname` attribute.

Flake outputs:

* `packages.<system>.<pname>` - will contain the package
* `checks.<system>.pkgs-<pname>` - also contains the package for `nix flake check`.
* `checks.<system>.pkgs-<pname>-<tname>` - adds all the package `passthru.tests`

#### `default.nix`
#### `default.nix` or top-level `package.nix`

Takes the "per-system" arguments. On top of this, it also takes a `pname`
argument.

#### `package.nix`

Use this when copying packages from `nixpkgs/pkgs/by-name`. `pkgs.callPackage` is called onto it.

#### `templates/<name>/`

Use this if you want your project to be initializable using `nix flake init`.
Expand All @@ -152,4 +173,5 @@ This is what is used by blueprint in the [getting started](getting-started.md) s
If no name is passed, it will look for the "default" folder.

Flake outputs:
* `templates.<name>`

* `templates.<name> -> path`
4 changes: 2 additions & 2 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
outputs =
inputs:
let
# use self to create self
blueprint = import ./lib inputs;
# Use self to create self
blueprint = import ./lib { inherit inputs; };
in
blueprint { inherit inputs; };
}
65 changes: 65 additions & 0 deletions formatter.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
pname,
pkgs,
flake,
}:
let
formatter = pkgs.writeShellApplication {
name = pname;

runtimeInputs = [
pkgs.deadnix
pkgs.nixfmt-rfc-style
];

text = ''
set -euo pipefail
set -x
deadnix --no-lambda-pattern-names --edit "$@"
nixfmt "$@"
'';

meta = {
description = "format your project";
};
};

check =
pkgs.runCommand "format-check"
{
nativeBuildInputs = [
formatter
pkgs.git
];

# only check on Linux
meta.platforms = pkgs.lib.platforms.linux;
}
''
export HOME=$NIX_BUILD_TOP/home
# keep timestamps so that treefmt is able to detect mtime changes
cp --no-preserve=mode --preserve=timestamps -r ${flake} source
cd source
git init --quiet
git add .
shopt -s globstar
${pname} **/*.nix
if ! git diff --exit-code; then
echo "-------------------------------"
echo "aborting due to above changes ^"
exit 1
fi
touch $out
'';
in
formatter
// {
passthru = formatter.passthru // {
tests = {
check = check;
};
};
}
Loading

0 comments on commit fdc4ac6

Please sign in to comment.