Generate flake.nix from module options. Discussions: https://oeiuwq.zulipchat.com/join/nqp26cd4kngon6mo3ncgnuap/ dendrix.oeiuwq.com/Dendritic.html
dendritic nix inputs

bootstrap docs (#70)

authored by oeiuwq.com and committed by

GitHub 415ff19b b08ae708

+840 -104
+3 -3
README.md
··· 1 1 <!-- Badges --> 2 2 3 3 <p align="right"> 4 - <a href="https://github.com/sponsors/vic"><img src="https://img.shields.io/badge/sponsor-vic-white?logo=githubsponsors&logoColor=white&labelColor=%23FF0000" alt="Sponsor Vic"/> 4 + <a href="https://dendritic.oeiuwq.com/sponsor"><img src="https://img.shields.io/badge/sponsor-vic-white?logo=githubsponsors&logoColor=white&labelColor=%23FF0000" alt="Sponsor Vic"/> 5 5 </a> 6 - <a href="https://vic.github.io/dendrix/Dendritic-Ecosystem.html#vics-dendritic-libraries"> <img src="https://img.shields.io/badge/Dendritic-Nix-informational?logo=nixos&logoColor=white" alt="Dendritic Nix"/> </a> 6 + <a href="https://dendritic.oeiuwq.com"> <img src="https://img.shields.io/badge/Dendritic-Nix-informational?logo=nixos&logoColor=white" alt="Dendritic Nix"/> </a> 7 7 <a href="https://github.com/vic/flake-file/actions"> 8 8 <img src="https://github.com/vic/flake-file/workflows/flake-check/badge.svg" alt="CI Status"/> </a> 9 9 <a href="LICENSE"> <img src="https://img.shields.io/github/license/vic/flake-file" alt="License"/> </a> ··· 11 11 12 12 # Generate `flake.nix`/`unflake.nix`/`npins` from inputs defined as module options. 13 13 14 - > `flake-file` and [vic](https://bsky.app/profile/oeiuwq.bsky.social)'s [dendritic libs](https://vic.github.io/dendrix/Dendritic-Ecosystem.html#vics-dendritic-libraries) made for you with Love++ and AI--. If you like my work, consider [sponsoring](https://github.com/sponsors/vic) 14 + > `flake-file` and [vic](https://bsky.app/profile/oeiuwq.bsky.social)'s [dendritic libs](https://dendritic.oeiuwq.com) made for you with Love++ and AI--. If you like my work, consider [sponsoring](https://dendritic.oeiuwq.com/sponsor) 15 15 16 16 **flake-file** lets you generate a clean, maintainable `flake.nix` from Nix module options. Use the _real_ Nix language to define your inputs. 17 17
+18 -8
default.nix
··· 2 2 pkgs ? import <nixpkgs> { }, 3 3 modules ? [ ], 4 4 outdir ? ".", 5 - bootstrap ? true, 5 + bootstrap ? [ ], 6 + outputs ? null, 6 7 import-tree ? ( 7 8 pkgs.fetchFromGitHub { 8 9 owner = "vic"; ··· 23 24 type = lib.types.submodule { freeformType = lib.types.lazyAttrsOf lib.types.unspecified; }; 24 25 }; 25 26 27 + bootstrapInputs = 28 + let 29 + ins = import ./modules/bootstrap.nix { inherit lib; }; 30 + take = name: { flake-file.inputs.${name} = ins.flake-file.inputs.${name}; }; 31 + names = 32 + if bootstrap == true then lib.attrNames ins.flake-file.inputs else lib.flatten [ bootstrap ]; 33 + in 34 + map take names; 35 + 26 36 module = { 27 37 imports = [ 28 38 tree ··· 33 43 ./modules/write-inputs.nix 34 44 ./modules/write-flake.nix 35 45 ./modules/flake-options.nix 36 - (if bootstrap then ./modules/bootstrap.nix else { }) 46 + { imports = bootstrapInputs; } 47 + (if outputs == null then { } else { flake-file.outputs = outputs; }) 37 48 ]; 38 49 config.flake-file.intoPath = outdir; 39 50 options = { ··· 43 54 }; 44 55 }; 45 56 46 - outputs = 47 - (lib.evalModules { 48 - modules = [ module ]; 49 - specialArgs.inputs.self.outPath = ""; 50 - }).config; 57 + evaled = lib.evalModules { 58 + modules = [ module ]; 59 + specialArgs.inputs.self.outPath = ""; 60 + }; 51 61 52 62 in 53 - outputs 63 + evaled.config
+15 -4
docs/astro.config.mjs
··· 26 26 sidebar: [ 27 27 { 28 28 label: "flake-file", 29 - items: [{ label: "Overview", slug: "overview" }], 29 + items: [{ label: "Docs Overview", slug: "overview" }], 30 30 }, 31 31 { 32 32 label: "Learn", ··· 42 42 label: "Getting Started", 43 43 items: [ 44 44 { label: "Quick Start", slug: "tutorials/quick-start" }, 45 - { label: "Migration Guide", slug: "tutorials/migrate" }, 46 - { label: "Bootstrapping", slug: "tutorials/bootstrap" }, 45 + { 46 + label: "With Traditional Flake", 47 + slug: "tutorials/migrate-traditional-flake", 48 + }, 49 + { 50 + label: "With Flake Parts", 51 + slug: "tutorials/migrate-flake-parts", 52 + }, 53 + { label: "With No Flakes", slug: "tutorials/migrate-no-flakes" }, 54 + { label: "Sandboxed Bootstrap", slug: "tutorials/bootstrap" }, 47 55 ], 48 56 }, 49 57 { ··· 62 70 }, 63 71 { 64 72 label: "Reference", 65 - items: [{ label: "All Options", slug: "reference/options" }], 73 + items: [ 74 + { label: "All Options", slug: "reference/options" }, 75 + { label: "Bootstrap Options", slug: "reference/bootstrap" }, 76 + ], 66 77 }, 67 78 ], 68 79 components: {
+150 -1
docs/src/components/Ad.astro
··· 1 1 --- 2 + import { LinkButton, Icon } from '@astrojs/starlight/components'; 3 + --- 4 + 5 + <section class="sponsor-card"> 6 + <div class="content"> 7 + <div class="header"> 8 + <Icon name="heart" size="2.5rem" class="heart-icon" /> 9 + <h3><code>vic/flake-file</code>?</h3> 10 + </div> 11 + 12 + <LinkButton href="https://dendritic.oeiuwq.com/sponsor" variant="primary">Become a Sponsor</LinkButton> 13 + 14 + <p class="description"> 15 + flake-file is part of <a href="https://dendritic.oeiuwq.com">@vic's Dendritic Ecosystem</a> — made with love and maintained with passion. 16 + </p> 17 + 18 + <ul class="ecosystem"> 19 + <li><a href="https://github.com/vic/import-tree">import-tree</a></li> 20 + <li><a href="https://github.com/vic/flake-aspects">flake-aspects</a></li> 21 + <li><a href="https://github.com/vic/with-inputs">with-inputs</a></li> 22 + <li><a href="https://github.com/vic/den">den</a></li> 23 + <li><a href="https://github.com/vic/denful">denful</a></li> 24 + <li><a href="https://github.com/vic/dendrix">dendrix</a></li> 25 + </ul> 26 + 27 + </div> 28 + </section> 29 + 30 + <style> 31 + .sponsor-card { 32 + border-radius: 1rem; 33 + padding: 2rem 1.5rem; 34 + margin: 2rem 1rem; 35 + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); 36 + transition: all 0.4s ease; 37 + max-width: 20em; 38 + } 39 + 40 + .sponsor-card:hover { 41 + background: linear-gradient(135deg, #a855f7 0%, #06b6d4 100%); 42 + box-shadow: 0 15px 40px rgba(0, 0, 0, 0.2); 43 + transform: translateY(-2px); 44 + } 45 + 46 + .content { 47 + color: white; 48 + text-align: center; 49 + } 50 + 51 + .header { 52 + display: flex; 53 + align-items: center; 54 + justify-content: center; 55 + gap: 0.75rem; 56 + margin-bottom: 1rem; 57 + } 58 + 59 + .heart-icon { 60 + animation: pulse 2s ease-in-out infinite; 61 + } 62 + 63 + @keyframes pulse { 64 + 0%, 100% { 65 + opacity: 1; 66 + } 67 + 50% { 68 + opacity: 0.7; 69 + } 70 + } 71 + 72 + h3 { 73 + font-size: 1.5rem; 74 + font-weight: 700; 75 + margin: 0; 76 + letter-spacing: -0.02em; 77 + } 2 78 3 - --- 79 + .description { 80 + font-size: 0.95rem; 81 + line-height: 1.6; 82 + margin: 1rem 0 1.5rem 0; 83 + opacity: 0.95; 84 + } 85 + 86 + .description a { 87 + color: white; 88 + font-weight: 600; 89 + text-decoration: underline; 90 + text-decoration-thickness: 2px; 91 + text-underline-offset: 4px; 92 + } 93 + 94 + .description a:hover { 95 + opacity: 0.85; 96 + } 97 + 98 + .ecosystem { 99 + list-style: none; 100 + padding: 0; 101 + margin: 1.5rem 0; 102 + display: grid; 103 + grid-template-columns: repeat(2, 1fr); 104 + gap: 0.75rem; 105 + font-size: 0.9rem; 106 + } 107 + 108 + .ecosystem li { 109 + background: rgba(255, 255, 255, 0.15); 110 + padding: 0.5rem 0.75rem; 111 + border-radius: 0.5rem; 112 + backdrop-filter: blur(10px); 113 + } 114 + 115 + .ecosystem a { 116 + color: white; 117 + text-decoration: none; 118 + font-weight: 500; 119 + transition: opacity 0.2s; 120 + } 121 + 122 + .ecosystem a:hover { 123 + opacity: 0.85; 124 + text-decoration: underline; 125 + } 126 + 127 + .cta-button { 128 + display: inline-flex; 129 + align-items: center; 130 + gap: 0.5rem; 131 + background: rgba(255, 255, 255, 0.25); 132 + color: white; 133 + padding: 0.875rem 1.75rem; 134 + border-radius: 0.75rem; 135 + font-weight: 600; 136 + font-size: 1rem; 137 + text-decoration: none; 138 + border: 2px solid rgba(255, 255, 255, 0.4); 139 + transition: all 0.3s ease; 140 + margin-top: 1rem; 141 + cursor: pointer; 142 + } 4 143 144 + .cta-button:hover { 145 + background: rgba(255, 255, 255, 0.35); 146 + border-color: rgba(255, 255, 255, 0.6); 147 + transform: scale(1.05); 148 + } 149 + 150 + .cta-button:active { 151 + transform: scale(0.98); 152 + } 153 + </style>
+3 -3
docs/src/components/FooterLinks.astro
··· 3 3 --- 4 4 5 5 <section class="sl-flex"> 6 - <a href="/contributing" class="sl-flex"> 6 + <a href="https://github.com/vic/flake-file" class="sl-flex"> 7 7 <Icon name="rocket" size="1.2em" /> 8 8 Contribute 9 9 </a> 10 10 11 - <a href="/community" class="sl-flex"> 11 + <a href="https://den.oeiuwq.com/community" class="sl-flex"> 12 12 <svg 13 13 xmlns="http://www.w3.org/2000/svg" 14 14 width="16" ··· 24 24 Community 25 25 </a> 26 26 27 - <a href="/sponsor" class="sl-flex"> 27 + <a href="https://dendritic.oeiuwq.com/sponsor" class="sl-flex"> 28 28 <Icon name="heart" size="1.2em" /> 29 29 Sponsor 30 30 </a>
+4 -4
docs/src/components/SocialIcons.astro
··· 4 4 5 5 --- 6 6 7 - <a href="https://github.com/vic/den/releases"><img src="https://img.shields.io/github/v/release/vic/den?logo=github&color=white"/></a> 7 + <a href="https://github.com/vic/flake-file/releases"><img src="https://img.shields.io/github/v/release/vic/flake-file?logo=github&color=white"/></a> 8 8 9 - <a href="https://deepwiki.com/vic/den"><img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki"></a> 9 + <a href="https://deepwiki.com/vic/flake-file"><img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki"></a> 10 10 11 - <a href="https://vic.github.io/dendrix/Dendritic-Ecosystem.html#vics-dendritic-libraries"> <img src="https://img.shields.io/badge/@vic-Dendritic libs-informational?logo=nixos&logoColor=white" alt="Vic Dendritic Nix"/> </a> 11 + <a href="https://dendritic.oeiuwq.com"> <img src="https://img.shields.io/badge/@vic-Dendritic libs-informational?logo=nixos&logoColor=white" alt="Vic Dendritic Libs"/> </a> 12 12 13 - <a href="/sponsor"><img src="https://img.shields.io/badge/Sponsor-@vic-white?logo=githubsponsors&logoColor=white" alt="Sponsor Den"/> 13 + <a href="https://dendritic.oeiuwq.com/sponsor"><img src="https://img.shields.io/badge/Sponsor-@vic-white?logo=githubsponsors&logoColor=white" alt="Sponsor Den"/> 14 14 </a> 15 15 16 16 <Default />
+20 -4
docs/src/content/docs/overview.mdx
··· 1 1 --- 2 - title: Overview 2 + title: Docs Overview 3 3 description: Everything flake-file. 4 4 --- 5 5 ··· 27 27 Bootstrap a new project with the `dendritic` template and generate your first `flake.nix` in minutes. 28 28 <LinkButton href="/tutorials/quick-start" variant="minimal" icon="right-arrow">Learn More</LinkButton> 29 29 </Card> 30 + <Card title="Bootstrapping" icon="add-document"> 31 + Generate a first `flake.nix` without any existing flake using a one-shot bootstrap command. 32 + <LinkButton href="/tutorials/bootstrap" variant="minimal" icon="right-arrow">Learn More</LinkButton> 33 + </Card> 30 34 <Card title="Migration Guide" icon="pencil"> 31 35 Step-by-step guide for adopting flake-file in an existing flake-parts project. 32 36 <LinkButton href="/tutorials/migrate" variant="minimal" icon="right-arrow">Learn More</LinkButton> 33 37 </Card> 34 - <Card title="Bootstrapping" icon="add-document"> 35 - Generate a first `flake.nix` without any existing flake using a one-shot bootstrap command. 36 - <LinkButton href="/tutorials/bootstrap" variant="minimal" icon="right-arrow">Learn More</LinkButton> 38 + <Card title="Migrate a flake-parts flake" icon="pencil"> 39 + Adopt flake-file in a project that already uses flake-parts. 40 + <LinkButton href="/tutorials/migrate-flake-parts" variant="minimal" icon="right-arrow">Learn More</LinkButton> 41 + </Card> 42 + <Card title="Migrate a traditional flake" icon="pencil"> 43 + Adopt flake-file in a project with a traditional flake (no flake-parts). 44 + <LinkButton href="/tutorials/migrate-traditional-flake" variant="minimal" icon="right-arrow">Learn More</LinkButton> 45 + </Card> 46 + <Card title="Migrate without flakes" icon="pencil"> 47 + Adopt flake-file in a non-flake project using npins or unflake. 48 + <LinkButton href="/tutorials/migrate-no-flakes" variant="minimal" icon="right-arrow">Learn More</LinkButton> 37 49 </Card> 38 50 </CardGrid> 39 51 ··· 72 84 <Card title="All Options" icon="document"> 73 85 Complete reference for every `flake-file.*` module option. 74 86 <LinkButton href="/reference/options" variant="minimal" icon="right-arrow">Learn More</LinkButton> 87 + </Card> 88 + <Card title="Bootstrap Command" icon="setting"> 89 + All arguments and apps for the one-shot bootstrap command. 90 + <LinkButton href="/reference/bootstrap" variant="minimal" icon="right-arrow">Learn More</LinkButton> 75 91 </Card> 76 92 </CardGrid>
+103
docs/src/content/docs/reference/bootstrap.mdx
··· 1 + --- 2 + title: Bootstrap Command Reference 3 + description: All options for the flake-file bootstrap command. 4 + --- 5 + 6 + import { Aside } from '@astrojs/starlight/components'; 7 + 8 + The bootstrap command lets you generate `flake.nix`, `unflake.nix`, or `npins/` from scratch — without being inside an existing flake. 9 + 10 + ```shell 11 + nix-shell https://github.com/vic/flake-file/archive/refs/heads/main.zip \ 12 + -A flake-file.sh --run <app> [--arg <name> <value>]... 13 + ``` 14 + 15 + ## Apps 16 + 17 + The `flake-file.sh` shell provides these commands: 18 + 19 + | App | Description | 20 + | --- | --- | 21 + | `write-flake` | Generate a `flake.nix` file | 22 + | `write-inputs` | Generate an `inputs.nix` expression (for debugging) | 23 + | `write-unflake` | Generate `unflake.nix` via [unflake](https://codeberg.org/goldstein/unflake) | 24 + | `write-npins` | Generate/update `npins/` directory via [npins](https://github.com/andir/npins) | 25 + 26 + ## Arguments 27 + 28 + All arguments are passed as `--arg <name> <value>` to `nix-shell`. 29 + 30 + ### `modules` 31 + 32 + The Nix file or directory containing your flake-file module definitions. All `.nix` files in a directory are auto-imported via [import-tree](https://github.com/vic/import-tree). 33 + 34 + - **Type:** path 35 + - **Default:** `[]` (empty) 36 + 37 + ```shell 38 + # Single file 39 + --arg modules ./flake-file.nix 40 + 41 + # Directory (all .nix files imported) 42 + --arg modules ./modules 43 + ``` 44 + 45 + ### `bootstrap` 46 + 47 + Include predefined inputs from the built-in `bootstrap.nix`. When set to `true`, all bootstrap inputs are included. When set to a list, only the named inputs are included. 48 + 49 + - **Type:** `true` | list of input names 50 + - **Default:** `[]` (none) 51 + 52 + Available bootstrap inputs: 53 + 54 + | Name | Default URL | 55 + | --- | --- | 56 + | `import-tree` | `github:vic/import-tree` | 57 + | `flake-file` | `github:vic/flake-file` | 58 + | `flake-parts` | `github:hercules-ci/flake-parts` | 59 + | `nixpkgs` | `https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz` | 60 + 61 + ```shell 62 + # Include all bootstrap inputs 63 + --arg bootstrap true 64 + 65 + # Include only specific ones 66 + --arg bootstrap '["flake-file" "nixpkgs"]' 67 + ``` 68 + 69 + <Aside type="tip"> 70 + Bootstrap inputs use `lib.mkDefault`, so your modules can override any of them. 71 + </Aside> 72 + 73 + ### `outdir` 74 + 75 + The directory where generated files are written. 76 + 77 + - **Type:** string 78 + - **Default:** `"."` 79 + 80 + <Aside type="caution" title="Important!"> 81 + Always use `--argstr` since this value is a string not a Nix Path. 82 + </Aside> 83 + 84 + ```shell 85 + --argstr outdir ./my-project 86 + ``` 87 + 88 + ### `outputs` 89 + 90 + Override the `flake-file.outputs` expression. When not provided, the default from your modules is used. 91 + 92 + - **Type:** null | string (Nix expression) 93 + - **Default:** `null` 94 + 95 + ```shell 96 + --argstr outputs 'inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } (inputs.import-tree ./modules)' 97 + ``` 98 + 99 + Instead of the above, some special values are recognized: see [outputs.nix](https://github.com/vic/flake-file/blob/main/modules/options/outputs.nix) 100 + 101 + ```shell 102 + --argstr outputs flake-parts 103 + ```
+23 -14
docs/src/content/docs/tutorials/bootstrap.mdx
··· 1 1 --- 2 - title: Bootstrapping 2 + title: Sandboxed Bootstrapping 3 3 description: Generate a first flake.nix without any existing flake. 4 4 --- 5 5 6 6 ## The Bootstrap Command 7 7 8 + You can try flake-file bootstrap command without having to 9 + change anything in your flake. 10 + 11 + Just create a temporary directory where to experiment safely. 12 + 13 + ```shell "bootstrap" 14 + mkdir bootstrap 15 + cd bootstrap 16 + ``` 17 + 8 18 You can create a `flake.nix` from scratch — without running inside an existing flake — using a one-shot bootstrap command: 9 19 10 - ```shell 11 - # Write a minimal bootstrap module 12 - echo '{ flake-file.inputs.flake-file.url = "github:vic/flake-file"; }' > bootstrap.nix 20 + ```shell "write-flake" "./flake-file.nix" 21 + # Write a minimal flake-file.nix file (or copy a flake.nix of yours) 22 + echo '{ inputs.flake-file.url = "github:vic/flake-file"; }' > flake-file.nix 13 23 14 - # Generate flake.nix 24 + # Generate flake.nix or unflake.nix or npins from flake-file.nix 15 25 nix-shell https://github.com/vic/flake-file/archive/refs/heads/main.zip \ 16 - -A flake-file.sh \ 17 - --run write-flake \ 18 - --arg modules ./bootstrap.nix 26 + -A flake-file.sh --run write-flake --arg modules ./flake-file.nix 19 27 ``` 20 28 29 + > <small>See also: all [bootstrap command args](/reference/bootstrap)</small> 30 + 21 31 Replace `write-flake` with `write-inputs`, `write-unflake`, or `write-npins` to target a different backend. 22 32 33 + 23 34 ## Using a modules directory 24 35 25 - `bootstrap.nix` can also be a directory. All `.nix` files in it will be auto-imported: 36 + `bootstrap.nix` can also be a directory. All `.nix` files in it will be auto-imported using [import-tree](https://github.com/vic/import-tree): 26 37 27 - ```shell 38 + ```shell "./modules" 28 39 nix-shell https://github.com/vic/flake-file/archive/refs/heads/main.zip \ 29 - -A flake-file.sh \ 30 - --run write-flake \ 31 - --arg modules ./modules 40 + -A flake-file.sh --run write-flake --arg modules ./modules 32 41 ``` 33 42 34 43 This is useful when you already have module files and just need the initial `flake.nix` to be generated before Nix can evaluate the flake itself. 35 44 36 45 ## Next Steps 37 46 38 - After generating `flake.nix`, continue with the standard [Quick Start](/tutorials/quick-start) flow. 47 + See the [bootstrap command reference](/reference/bootstrap) for more options.
+120
docs/src/content/docs/tutorials/migrate-flake-parts.mdx
··· 1 + --- 2 + title: With a flake-parts flake 3 + description: Migrate a flake-parts flake to flake-file 4 + --- 5 + 6 + import { Aside } from '@astrojs/starlight/components'; 7 + 8 + 9 + Suppose you have a flake-parts enabled flake that looks like: 10 + 11 + ```nix "(A)" "(B)" 12 + # flake.nix 13 + { 14 + inputs = { # (A) So much inputs 15 + nixpkgs.url = "github:nixos/nixpkgs/unstable"; 16 + flake-parts.url = "github:hercules-ci/flake-parts"; 17 + foo.url = "github:coolguy/foo"; 18 + bar.url = "github:coolguy/bar"; 19 + }; 20 + outputs = inputs: 21 + inputs.flake-parts.lib.mkFlake { inherit inputs; } 22 + # (B) flake-parts entry-point module. 23 + { systems = [ "aarch64-darwin" ]; ... }; 24 + } 25 + ``` 26 + 27 + Your flake is already modular (in this case flake-parts modules), 28 + so your migration path is smoother here. 29 + 30 + ## Split `flake.nix` in two 31 + 32 + First step is moving the <strong>`(B)`</strong> flake-parts entry-point module 33 + outside of the flake.nix file into `modules/default.nix`. 34 + 35 + ```nix "./inputs.nix" 36 + # modules/default.nix 37 + { 38 + imports = [ ./inputs.nix ]; 39 + systems = [ "aarch64-darwin" ]; 40 + 41 + ... # same code as before 42 + } 43 + ``` 44 + 45 + Second is also moving the <strong>`(A)`</strong> inputs into `./modules` 46 + 47 + ```nix "flake-file.inputs" 48 + # modules/inputs.nix 49 + # This is now real Nix code, use let bindings, { lib, ... } etc. 50 + # best practice is to split this inputs.nix into other modules 51 + { 52 + flake-file.inputs = { 53 + nixpkgs.url = "github:nixos/nixpkgs/unstable"; 54 + flake-parts.url = "github:hercules-ci/flake-parts"; 55 + # all your other inputs 56 + }; 57 + } 58 + ``` 59 + 60 + 61 + 62 + ## Boostraping using `./modules` 63 + 64 + And now, lets replace `flake.nix` using bootstrapping magic step: 65 + 66 + ```shell "./modules" "flake-parts" 67 + nix-shell https://github.com/vic/flake-file/archive/main.tar.gz \ 68 + -A flake-file.sh --run write-flake \ 69 + --arg modules ./modules --argstr outputs flake-parts 70 + ``` 71 + 72 + > <small>See also: all [bootstrap command args](/reference/bootstrap)</small> 73 + 74 + 75 + Run the **same** command whenever your input changes and they 76 + will be reflected into the **static** `flake.nix`. 77 + 78 + <Aside title="You are done!"> 79 + You can stop here and enjoy your dynamic inputs at `./modules`. 80 + 81 + Simply run the same bootstrap command whenever inputs change. 82 + </Aside> 83 + 84 + ## Enabling `.#write-flake` app. 85 + 86 + Edit `./modules/inputs.nix` module to add in-flake flake-file. 87 + 88 + ```diff lang="nix" "resolved flake inputs" " inputs =" "flake-file.inputs option" "inputs," " outputs =" "type-checked schema" ins="flake-module" "flake-file.inputs" 89 + # modules/inputs.nix 90 + + { inputs, lib, ... }: # resolved flake inputs as specialArgs 91 + { 92 + # same inputs code as before 93 + flake-file.inputs = { 94 + 95 + # make sure you add flake-file dependency. 96 + + flake-file.url = lib.mkDefault "github:vic/flake-file"; 97 + }; 98 + 99 + imports = [ 100 + # enable inside-flake and say goodbye to bootstrap 101 + + inputs.flake-file.flakeModule 102 + 103 + # start splitting from inputs.nix into other files 104 + ]; 105 + 106 + # generate the same output function we used at bootstrap 107 + + flake-file.outputs = "flake-parts"; 108 + } 109 + ``` 110 + 111 + 112 + ## Your flake is flake-file enabled 113 + 114 + Commands for your daily life: 115 + 116 + ```shell 117 + nix run .#write-flake # whenever you need to regen flake.nix 118 + 119 + nix flake check # will make sure your flake.nix is up-to-date 120 + ```
+128
docs/src/content/docs/tutorials/migrate-no-flakes.mdx
··· 1 + --- 2 + title: With No Flakes 3 + description: Migrate a non-flake to flake-file 4 + --- 5 + 6 + import { Aside } from '@astrojs/starlight/components'; 7 + 8 + 9 + <Aside title="Fetching and locking Nix dependencies"> 10 + flake-file is not a locking/fetching tool, we have plenty 11 + of tools for that in the ecosystem. 12 + 13 + flake-file has support 14 + for [`unflake`](https://codeberg.org/goldstein/unflake) 15 + and [`npins`](https://github.com/andir/npins) 16 + send PR for others. 17 + 18 + This guide shows npins as it is the most popular one. 19 + </Aside> 20 + 21 + 22 + Suppose you have a `default.nix` that looks like: 23 + 24 + ```nix "(A)" "(B)" 25 + # default.nix 26 + let 27 + sources = import ./npins; 28 + in 29 + { 30 + nixosConfigurations.my-laptop = ...; # use sources 31 + } 32 + ``` 33 + 34 + First step is adding flake-like input definitions on it, 35 + or in a separate `./flake-file.nix` file. 36 + 37 + ```nix 38 + # flake-file.nix 39 + { 40 + flake-file.inputs = { 41 + nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; 42 + }; 43 + } 44 + ``` 45 + 46 + ## Boostraping using `./flake-file.nix` 47 + 48 + <Aside type="caution" title="Backup your ./npins"> 49 + The following bootstrap command will write `./npins` so make sure 50 + to rename your existing directory first. 51 + </Aside> 52 + 53 + And now, lets generate `./npins` from `./flake-file.nix`. 54 + 55 + ```shell "./flake-file.nix" "write-npins" 56 + nix-shell https://github.com/vic/flake-file/archive/main.tar.gz \ 57 + -A flake-file.sh --run write-npins --arg modules ./flake-file.nix 58 + ``` 59 + 60 + > <small>See also: all [bootstrap command args](/reference/bootstrap)</small> 61 + 62 + 63 + Run the **same** command whenever your input changes and they 64 + will be reflected into your pins. 65 + 66 + <Aside title="You are done!"> 67 + You can stop here and enjoy your dynamic inputs at `./flake-file.nix`. 68 + 69 + Simply run the same bootstrap command whenever inputs change. 70 + </Aside> 71 + 72 + ## Enabling Modular non-flakes. 73 + 74 + Lets make use of Nix Modules in our non-flake. 75 + 76 + First, create a `./modules` directory and move 77 + our previous `default.nix` and `flake-file.nix` on it. 78 + 79 + ```shell 80 + mkdir modules 81 + mv flake-file.nix modules/inputs.nix 82 + mv default.nix modules/default.nix 83 + ``` 84 + 85 + 86 + ```diff lang="nix" "inputs" "flake." 87 + # modules/default.nix 88 + + { inputs, lib, ... }: 89 + let 90 + - sources = import ./npins; 91 + in 92 + { 93 + + imports = [ ./inputs.nix ]; 94 + 95 + - nixosConfigurations.my-laptop = ...; # use sources 96 + + nixosConfigurations.my-laptop = ...; # use inputs 97 + } 98 + ``` 99 + 100 + Now create a new `defualt.nix` as follows: 101 + 102 + ```nix 103 + # default.nix 104 + let 105 + sources = import ./npins; 106 + nixpkgs = import sources.nixpkgs { }; 107 + outputs = (nixpkgs.lib.evalModules { 108 + modules = ./modules; 109 + specialArgs = { 110 + inputs = sources; # (A) NOTE: Not flake-like inputs. 111 + }; 112 + }).config; 113 + in 114 + outputs 115 + ``` 116 + 117 + To update npins from inputs at ./modules do: 118 + 119 + ```shell "./modules" "write-npins" 120 + nix-shell https://github.com/vic/flake-file/archive/main.tar.gz \ 121 + -A flake-file.sh --run write-npins --arg modules ./modules 122 + ``` 123 + 124 + ### `(A)` flake-like inputs 125 + 126 + If you wish to have flake-like resolved inputs 127 + to use flakes from non-flake world, take a 128 + look at [with-inputs.nix](https://github.com/vic/flake-file/tree/main/templates/npins/with-inputs.nix) used by [templates/npins](https://github.com/vic/flake-file/tree/main/templates/npins/default.nix)
+163
docs/src/content/docs/tutorials/migrate-traditional-flake.mdx
··· 1 + --- 2 + title: With a traditional flake 3 + description: Migrate a traditional flake to flake-file (no flake-parts) 4 + --- 5 + 6 + import { Aside } from '@astrojs/starlight/components'; 7 + 8 + 9 + As always, start a new empty commit so you can always revert to safe state. 10 + 11 + Suppose you have a flake that looks like: 12 + 13 + ```nix 14 + # flake.nix 15 + { 16 + inputs = { # So much inputs 17 + nixpkgs.url = "github:nixos/nixpkgs/unstable"; 18 + foo.url = "github:coolguy/foo"; 19 + bar.url = "github:coolguy/bar"; 20 + }; 21 + outputs = inputs: { ... }; # wow! very outputs 22 + } 23 + ``` 24 + 25 + ## Boostraping flake-file 26 + 27 + First, move your `flake.nix` file as `flake-file.nix`. 28 + 29 + And now, the bootstrapping magic step: 30 + 31 + ```shell 32 + nix-shell https://github.com/vic/flake-file/archive/main.tar.gz \ 33 + -A flake-file.sh --run write-flake \ 34 + --arg modules ./flake-file.nix --argstr outputs flake-file 35 + ``` 36 + 37 + > <small>See also: all [bootstrap command args](/reference/bootstrap)</small> 38 + 39 + 40 + ## The new `flake.nix` (static Nix) 41 + 42 + You will notice your new `flake.nix` looks like this: 43 + 44 + ```diff lang="nix" "(A)" "(B)" "(C)" "(D)" 45 + # flake.nix 46 + # DO-NOT-EDIT. This file was auto-generated using github:vic/flake-file. (A) 47 + # Use `nix run .#write-flake` to regenerate it. (D) 48 + { 49 + outputs = inputs: (import ./flake-file.nix).outputs inputs; # (B) 50 + inputs = { 51 + # (C) all your inputs (static version) 52 + }; 53 + } 54 + ``` 55 + <strong>(A)</strong> The `--arg modules ./flake-file.nix` option indicates 56 + the module entry-point. Your old flake is **already** a module for flake-file. 57 + 58 + <strong>(B)</strong> The `--argstr outputs flake-file` generated 59 + an `outputs` function that just **delegates** to the one in `flake-file.nix`. 60 + 61 + <strong>(C)</strong> Your `inputs` are now the **static** version (Nix subset) 62 + of the **real Nix** inputs at your `flake-file.nix` file. 63 + 64 + ## Edit `flake-file.nix` (real Nix) 65 + 66 + Now that `flake-file.nix` is real Nix code, you can refactor your inputs code 67 + to your heart's content. 68 + 69 + ```nix 70 + # flake-file.nix 71 + # Now with more and **real** Nix 72 + let 73 + # for example purposes 74 + gh = user: repo: branch: "github:${user}/${repo}/${branch}"; 75 + 76 + coolguy = repo: gh "coolguy" repo "main"; 77 + channel = "unstable"; 78 + in { 79 + inputs = { 80 + nixpkgs.url = gh "nixos" "nixpkgs" channel; 81 + foo.url = coolguy "foo"; 82 + bar.url = coolguy "bar"; 83 + }; 84 + 85 + outputs = inputs: { ... }; # keeps the same 86 + } 87 + ``` 88 + 89 + ## Update static from dynamic Nix. 90 + 91 + Run the **same** command again, your input changes will be reflected into 92 + the **static** `flake.nix`. 93 + 94 + ```shell 95 + nix-shell https://github.com/vic/flake-file/archive/main.tar.gz \ 96 + -A flake-file.sh --run write-flake \ 97 + --arg modules ./flake-file.nix --argstr outputs flake-file 98 + ``` 99 + 100 + <Aside title="You are done!"> 101 + You can stop here and enjoy your dynamic inputs at `flake-file.nix`. 102 + 103 + Simply run the same bootstrap command whenever inputs change. 104 + </Aside> 105 + 106 + ## Moving into a module-based flake. 107 + 108 + <strong>(D)</strong> You might have noticed the comment about the `.#write-flake` app. 109 + To include this app as part of your flake and not having use the bootstrap command 110 + and specify all the same options each time, you need: 111 + 112 + Use `flake-module` outputs instead of `flake-file` on the bootstrap command: 113 + 114 + ```shell ins="flake-module" 115 + nix-shell https://github.com/vic/flake-file/archive/main.tar.gz \ 116 + -A flake-file.sh --run write-flake \ 117 + --arg modules ./flake-file.nix --argstr outputs flake-module 118 + ``` 119 + 120 + Add options to your `flake-file.nix` **module**. I told you it was a module already. 121 + 122 + ```diff lang="nix" "resolved flake inputs" " inputs =" "flake-file.inputs option" "inputs," " outputs =" "type-checked schema" ins="flake-module" 123 + # flake-file.nix 124 + + { inputs, lib, ... }: # resolved flake inputs as specialArgs 125 + let 126 + # same helper code as before 127 + in 128 + { 129 + # same inputs code as before 130 + inputs = { # Alias option for flake-file.inputs type-checked schema! 131 + 132 + # make sure you add flake-file dependency. 133 + + flake-file.url = lib.mkDefault "github:vic/flake-file"; 134 + }; 135 + 136 + # same outputs code as before 137 + outputs = inputs: ...; # Now with **extensible** type-checked schema! 138 + 139 + # since this IS a module it can import other modules 140 + imports = [ 141 + # enable inside-flake and say goodbye to bootstrap 142 + + inputs.flake-file.flakeModule 143 + 144 + # start splitting from huge monolithic code to modular nix. 145 + # each input can be defined on their relevant module files. 146 + # maybe move outputs function to ./outputs.nix 147 + ]; 148 + 149 + # generate the same output function we used at bootstrap 150 + + flake-file.outputs = "flake-module"; 151 + } 152 + ``` 153 + 154 + 155 + ## Your flake is flake-file enabled 156 + 157 + Commands for your daily life: 158 + 159 + ```shell 160 + nix run .#write-flake # whenever you need to regen flake.nix 161 + 162 + nix flake check # will make sure your flake.nix is up-to-date 163 + ```
+29 -42
docs/src/content/docs/tutorials/quick-start.mdx
··· 3 3 description: Bootstrap a new project with flake-file in minutes. 4 4 --- 5 5 6 - ## Prerequisites 6 + import { Card, LinkButton, Aside } from '@astrojs/starlight/components'; 7 7 8 - - Nix with flakes enabled. 9 - - An internet connection to fetch the template. 10 8 11 - ## Create a new project 9 + This section will help you get started with `flake-file` in minutes. 12 10 13 - Use the `dendritic` template — it sets up a full [flake-parts](https://flake.parts) + [import-tree](https://github.com/vic/import-tree) environment with flake-file already wired in. 11 + It pretty much depends on your current Nix choices -the library adapts to you- 12 + and what your destination is. 14 13 15 - ```shell 16 - nix flake init -t github:vic/flake-file#dendritic 17 - ``` 14 + ## Choose your path 18 15 19 - ## Generate flake.nix 16 + <Card title="Sandboxed Bootstrap" icon="nix"> 17 + Try flake-file in a temporary directory using your flake inputs. 20 18 21 - ```shell 22 - nix run ".#write-flake" 23 - ``` 19 + <LinkButton variant="secondary" icon="right-arrow" href="/tutorials/bootstrap">Try It Now!</LinkButton> 20 + </Card> 24 21 25 - This evaluates your modules, merges all `flake-file.*` options, and writes `flake.nix`. 22 + <Card title="Brand new project (with or without flakes)" icon="rocket"> 23 + We provide many `templates` providing different features. 26 24 27 - ```shell 28 - cat flake.nix # inspect the generated file 29 - ``` 25 + <LinkButton variant="secondary" href="/guides/templates" icon="right-arrow">Pick one</LinkButton> that suits you more, and run: 30 26 31 - ## Verify 27 + ```shell 28 + nix flake init -t github:vic/flake-file#default 29 + ``` 30 + </Card> 32 31 33 - ```shell 34 - nix flake check 35 - ``` 32 + <Card title="Use with a traditional flake (no flake-parts)" icon="nix"> 33 + You don't need to change your loved flake structure nor adopt a module system. 36 34 37 - This confirms that `flake.nix` is up to date with the current module state. Run this in CI. 35 + Even better, `flake-file` can use your **current** `flake.nix` as a module. 38 36 39 - ## Add your first input 37 + <LinkButton variant="secondary" icon="right-arrow" href="/tutorials/migrate-traditional-flake">Lets Do It!</LinkButton> 38 + </Card> 40 39 41 - Open (or create) a module under `./modules/`. Declare any dependency close to where it is used: 42 40 43 - ```nix 44 - # modules/my-tool.nix 45 - { inputs, lib, ... }: { 46 - flake-file.inputs.my-tool.url = lib.mkDefault "github:owner/my-tool"; 41 + <Card title="Use with a flake-parts flake" icon="nix"> 42 + Nice! You already use flake modules, just add some water and enjoy your cool-inputs. 47 43 48 - # Use the input once it's in flake.nix 49 - imports = lib.optionals (inputs ? my-tool) [ 50 - inputs.my-tool.flakeModule 51 - ]; 52 - } 53 - ``` 44 + <LinkButton variant="secondary" icon="right-arrow" href="/tutorials/migrate-flake-parts">Lets Do It!</LinkButton> 45 + </Card> 54 46 55 - Then regenerate: 56 47 57 - ```shell 58 - nix run ".#write-flake" 59 - ``` 48 + <Card title="Use with no flakes" icon="nix"> 49 + Easy as pie. 60 50 61 - ## Next Steps 62 - 63 - - [Migration Guide](/tutorials/migrate) — adopt flake-file in an existing project. 64 - - [flakeModules](/guides/flake-modules) — explore all built-in modules. 65 - - [Options Reference](/reference/options) — every `flake-file.*` option explained. 51 + <LinkButton variant="secondary" icon="right-arrow" href="/tutorials/migrate-no-flakes">Lets Do It!</LinkButton> 52 + </Card>
+5 -4
modules/bootstrap.nix
··· 1 + { lib, ... }: 1 2 { 2 3 flake-file.inputs = { 3 - import-tree.url = "github:vic/import-tree"; 4 - flake-file.url = "github:vic/flake-file"; 5 - flake-parts.url = "github:hercules-ci/flake-parts"; 6 - nixpkgs.url = "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz"; 4 + import-tree.url = lib.mkDefault "github:vic/import-tree"; 5 + flake-file.url = lib.mkDefault "github:vic/flake-file"; 6 + flake-parts.url = lib.mkDefault "github:hercules-ci/flake-parts"; 7 + nixpkgs.url = lib.mkDefault "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz"; 7 8 }; 8 9 }
+1 -3
modules/dendritic/dendritic.nix
··· 11 11 flake-parts.inputs.nixpkgs-lib.follows = lib.mkDefault "nixpkgs-lib"; 12 12 }; 13 13 14 - flake-file.outputs = lib.mkDefault '' 15 - inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } (inputs.import-tree ./modules) 16 - ''; 14 + flake-file.outputs = lib.mkDefault "dendritic"; 17 15 18 16 flake.modules = { }; 19 17
+16 -7
modules/flake-options.nix
··· 1 - { lib, ... }: 1 + { lib, config, ... }: 2 2 let 3 + outputsOption = lib.mkOption { type = lib.type.functionTo outputsType; }; 3 4 4 - # TODO: Extensible flake output schema! 5 - outputsType = lib.types.submodule { 6 - freeformType = lib.types.lazyAttrsOf lib.types.unspecified; 5 + outputsType = lib.types.submoduleWith { 6 + modules = [ 7 + { freeformType = lib.types.lazyAttrsOf lib.types.unspecified; } 8 + config.flake-file.outputs-schema 9 + ]; 7 10 }; 8 11 12 + # Extensible flake output schema! 13 + outputsSchemaOption = lib.mkOption { 14 + type = lib.types.deferredModule; 15 + default = { }; 16 + }; 9 17 in 10 18 { 11 19 imports = [ 12 20 (lib.mkAliasOptionModule [ "inputs" ] [ "flake-file" "inputs" ]) 21 + (lib.mkAliasOptionModule [ "description" ] [ "flake-file" "description" ]) 22 + (lib.mkAliasOptionModule [ "nixConfig" ] [ "flake-file" "nixConfig" ]) 13 23 ]; 14 24 15 - options.outputs = lib.mkOption { 16 - type = lib.type.functionTo outputsType; 17 - }; 25 + options.outputs = outputsOption; 26 + options.flake-file.outputs-schema = outputsSchemaOption; 18 27 }
+38 -6
modules/options/outputs.nix
··· 1 1 { lib, ... }: 2 + let 3 + easyOutputs = { 4 + default = '' 5 + inputs: import ./outputs.nix inputs 6 + ''; 7 + 8 + flake-file = '' 9 + inputs: (import ./flake-file.nix).outputs inputs 10 + ''; 11 + 12 + flake-module = '' 13 + inputs: 14 + (inputs.nixpkgs.lib.evalModules { 15 + specialArgs = { inherit inputs; inherit (inputs) self; }; 16 + modules = [ ./flake-file.nix ]; 17 + }).config.outputs inputs 18 + ''; 19 + 20 + import-tree = '' 21 + inputs: 22 + (inputs.nixpkgs.lib.evalModules { 23 + specialArgs = { inherit inputs; inherit (inputs) self; }; 24 + modules = [ (import-tree ./modules) ]; 25 + }).config.outputs inputs 26 + ''; 27 + 28 + flake-parts = '' 29 + inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } ./modules 30 + ''; 31 + 32 + dendritic = '' 33 + inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } (inputs.import-tree ./modules) 34 + ''; 35 + }; 36 + in 2 37 { 3 38 options.flake-file.outputs = lib.mkOption { 4 39 description = '' ··· 7 42 We recommend this function code to be short, used only to import a file. 8 43 ''; 9 44 type = lib.types.str; 10 - default = '' 11 - inputs: import ./outputs.nix inputs 12 - ''; 13 - example = lib.literalExample '' 14 - inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } ./modules 15 - ''; 45 + default = "default"; 46 + apply = output: easyOutputs.${output} or output; 47 + example = lib.literalExample easyOutputs.dendritic; 16 48 }; 17 49 }
+1 -1
modules/write-flake.nix
··· 87 87 name = "write-flake"; 88 88 text = '' 89 89 cd ${config.flake-file.intoPath} 90 - cp ${formatted pkgs} flake.nix 90 + cp --no-preserve=mode ${formatted pkgs} flake.nix 91 91 ${hooks} 92 92 ''; 93 93 };