Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

top-level refactor #17

Merged
merged 2 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 6 additions & 25 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 with 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,24 +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.

Each sub-folder should contain a `default.nix`, with the following function
signature:

* pname: name of the folder. Useful to inject back.
* all the inputs

## How to support overrides?

Don't
Expand All @@ -80,12 +64,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