Skip to content

Commit fd18ef2

Browse files
committed
add source
1 parent 9874cbf commit fd18ef2

File tree

5 files changed

+152
-0
lines changed

5 files changed

+152
-0
lines changed

README.md

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# flakegen
2+
3+
In Nix flakes, inputs must be written as pure data, without function
4+
(see issues [NixOS/nix#3966](https://github.com/NixOS/nix/issues/3966)
5+
and [NixOS/nix#4945](https://github.com/NixOS/nix/issues/4945)).
6+
To generate inputs with the full power of the Nix language,
7+
one can create a template file, e.g. `flake.in.nix` and generate the
8+
`flake.nix` by evaluating and pretty-printing the `inputs` attribute.
9+
10+
This flake is a convenience wrapper around that.
11+
12+
13+
## Usage
14+
15+
To start using this, run
16+
```
17+
nix flake init -t github:jorsn/flakegen
18+
```
19+
20+
This will create the files `flake.nix` and `flake.in.nix`.
21+
It will not overwrite existing files.
22+
After editing `flake.in.nix` as you like, run
23+
```
24+
nix run .#genflake flake.nix
25+
```
26+
to update the `flake.nix`.
27+
To preview the new `flake.nix` without replacing it, run the following:
28+
```
29+
nix run .#genflake
30+
```
31+
32+
33+
## Repair broken `flake.nix`
34+
35+
You can repair a broken `flake.nix` by
36+
deleting `flake.nix` and running
37+
```
38+
nix flake init -t github:jorsn/flakegen
39+
nix run .#genflake flake.nix
40+
```
41+
as long as `flake.in.nix` works.

flake.nix

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
{
2+
description = "Flake inputs with the full power of Nixlang";
3+
4+
inputs.systems.url = "github:nix-systems/default";
5+
6+
outputs = { self, systems }: with builtins; with self.lib; {
7+
8+
templates.default = {
9+
description = "Default template";
10+
path = ./template;
11+
};
12+
13+
__functor = _: path: let s = import systems; in { systems ? s, inputFile ? "flake.in.nix", apps ? {}, ... }@outputAttrs:
14+
{
15+
nextFlake = flake path inputFile;
16+
nextFlakeSource = flakeSource path inputFile;
17+
}
18+
// outputAttrs
19+
// {
20+
apps = self.lib.genAttrs (system:
21+
{ genflake = { type = "app"; program = ./genflake; }; }
22+
// apps.${system} or {}
23+
) systems;
24+
};
25+
26+
lib = {
27+
28+
flake = path: inputFile: toFile "flake.nix" (flakeSource path inputFile);
29+
30+
flakeSource = path: inputFile:
31+
let
32+
attrs = import (path + "/${inputFile}");
33+
attrs' = attrs // {
34+
inputs = { flakegen.url = "github:jorsn/flakegen"; } // (attrs.inputs or {});
35+
outputs = "<outputs>";
36+
};
37+
in "# Do not modify! This file is generated.\n\n"
38+
+ replaceStrings
39+
[ "\"<outputs>\"" ] [ "inputs: inputs.flakegen ./. ((import ./${inputFile}).outputs inputs)" ]
40+
(toPretty "" attrs')
41+
;
42+
43+
genAttrs = f: names:
44+
listToAttrs (map (name: { inherit name; value = f name; }) names);
45+
46+
toPretty =
47+
let
48+
printChild = prefix: x:
49+
let
50+
names = attrNames x;
51+
in
52+
if isAttrs x && length names == 1
53+
then "." + head names + printChild prefix x.${head names}
54+
else " = " + print prefix x
55+
;
56+
57+
mapAttrsToList = f: attrs: attrValues (mapAttrs f attrs);
58+
mapAttrsToLines = f: attrs: concatStringsSep "\n" (mapAttrsToList f attrs);
59+
print = prefix: x:
60+
if isString x
61+
then "\"${x}\""
62+
else if ! isAttrs x
63+
then toString x
64+
else let prefix' = prefix + " "; in ''
65+
{
66+
${mapAttrsToLines (n: v: prefix' + n + printChild prefix' v + ";") x}
67+
${prefix}}'';
68+
in print;
69+
};
70+
71+
};
72+
73+
}

genflake

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/sh
2+
3+
if [ "$1" = '' ]; then
4+
nix eval --raw .#nextFlakeSource
5+
else
6+
cp $(nix eval --raw .#nextFlake) "$1"
7+
fi

template/flake.in.nix

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
3+
description = "The real nix file";
4+
5+
inputs = let
6+
dep = url: { inherit url; inputs.nixpkgs.follows = "nixpkgs"; };
7+
in {
8+
# flakegen needn't be declared, here. It is automatically added when
9+
# generating flake.nix.
10+
nixlib.url = "github:nix-community/nixpkgs.lib";
11+
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
12+
nix-darwin = (dep "github:LnL7/nix-darwin");
13+
home-manager = (dep "github:nix-community/home-manager");
14+
};
15+
16+
outputs = { nixpkgs, ... }@inputs: {
17+
# you can write the outputs as usual. They will be called from the generated
18+
# flake.nix.
19+
packages.x86_64-linux.hello = nixpkgs.legacyPackages.x86_64-linux.hello;
20+
};
21+
22+
}

template/flake.nix

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Do not modify! This file is generated.
2+
3+
{
4+
description = "A very basic flake";
5+
6+
inputs.flakegen.url = "github:jorsn/flakegen";
7+
8+
outputs = { flakegen, ... }: flakegen ./. {};
9+
}

0 commit comments

Comments
 (0)