Repository: srid/nixos-flake
Branch: master
Commit: d2818c36b863
Files: 37
Total size: 50.5 KB
Directory structure:
gitextract_shy0x3kh/
├── .envrc
├── .github/
│ └── workflows/
│ └── ci.yaml
├── .gitignore
├── .vscode/
│ ├── extensions.json
│ └── settings.json
├── LICENSE
├── README.md
├── activate/
│ ├── activate.nu
│ ├── default.nix
│ └── nu.nix
├── dev/
│ └── flake.nix
├── doc/
│ ├── .gitignore
│ ├── examples.md
│ ├── flake.nix
│ ├── guide/
│ │ ├── activate.md
│ │ ├── autowiring.md
│ │ ├── outputs.md
│ │ ├── specialArgs.md
│ │ └── templates.md
│ ├── guide.md
│ ├── history.md
│ ├── howto.md
│ ├── index.md
│ ├── index.yaml
│ ├── mod.just
│ └── start.md
├── examples/
│ ├── home/
│ │ └── flake.nix
│ ├── linux/
│ │ └── flake.nix
│ └── macos/
│ └── flake.nix
├── flake.nix
├── justfile
├── nix/
│ └── modules/
│ ├── configurations/
│ │ └── default.nix
│ └── flake-parts/
│ ├── autowire.nix
│ ├── default.nix
│ ├── lib.nix
│ └── packages.nix
└── vira.hs
================================================
FILE CONTENTS
================================================
================================================
FILE: .envrc
================================================
watch_file dev/flake.nix
use flake ./dev --override-input nixos-unified .
================================================
FILE: .github/workflows/ci.yaml
================================================
name: "CI"
on:
push:
branches:
- master
jobs:
website-upload:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/master'
steps:
- uses: actions/checkout@v4
- uses: nixbuild/nix-quick-install-action@v33
- name: Build docs
run: |
cd doc && nix build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: doc/result
website-deploy:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/master'
needs: website-upload
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
================================================
FILE: .gitignore
================================================
result
/.direnv
================================================
FILE: .vscode/extensions.json
================================================
{
"recommendations": [
"bbenoist.nix",
"b4dm4n.nixpkgs-fmt",
"jnoortheen.nix-ide",
"mattn.lisp",
"mkhl.direnv",
"thenuprojectcontributors.vscode-nushell-lang"
]
}
================================================
FILE: .vscode/settings.json
================================================
{
"editor.defaultFormatter": "B4dM4n.nixpkgs-fmt",
"editor.formatOnSave": true,
"editor.formatOnType": true
}
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2023 Sridhar Ratnakumar
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
[](https://nixos.zulipchat.com/#narrow/stream/413948-nixos)
[](https://compass.naivete.me/ "This project follows the 'Naiveté Compass of Mood'")
# nixos-unified
[**nixos-unified**](https://github.com/srid/nixos-unified) is a
[flake-parts](https://flake.parts/) module to unify [NixOS] + [nix-darwin] +
[home-manager] configuration in a single flake, while providing a consistent
interface at DX and UX level.
[NixOS]: https://nixos.org/
[nix-darwin]: https://github.com/LnL7/nix-darwin
[home-manager]: https://github.com/nix-community/home-manager
For motivation, see https://nixos-unified.org/#why
[home-manager]: https://github.com/nix-community/home-manager
## Getting Started
https://nixos-unified.org/start.html
## Examples
https://nixos-unified.org/examples.html
## Discussion
To discuss the project, post in [our Zulip](https://nixos.zulipchat.com/#narrow/stream/413948-nixos) or in [Github Discussions](https://github.com/srid/nixos-unified/discussions).
================================================
FILE: activate/activate.nu
================================================
use std log
use std assert
use nixos-unified.nu getData # This module is generated in Nix
let CURRENT_HOSTNAME = (hostname -s | str trim)
let data = getData
# Get all the data associated with a host
#
# Presently, this only deals with nixosConfigurations and darwinConfigurations.
# But we should also incorporate home-manager configurations.
def get_host_data [ host: string ] {
if $host not-in $data.nixos-unified-configs {
log error $"Host '($host)' not found in flake. Available hosts=($data.nixos-unified-configs | columns)"
exit 1
}
$data.nixos-unified-configs
| get $host
| insert "host" $host
| insert "flake" $"($data.cleanFlake)#($host)"
}
# Parse "[srid@]example" into { user: "srid", host: "example" }
#
# localhost hosts are ignored (null'ified)
def parseFlakeOutputRef [ spec: string ] {
let parts = $spec | split row "@"
let handleLocalhost = {|h| if $h == "localhost" { null } else { $h } }
if ($parts | length) == 1 {
{ user: null host: (do $handleLocalhost $parts.0) }
} else {
{ user: $parts.0 host: (do $handleLocalhost $parts.1) }
}
}
# Activate system or home configuration
#
# The ref should match the name of the corresponding nixosConfigurations, darwinConfigurations or homeConfigurations attrkey. "localhost" is an exception, which will use the current host.
def main [
ref: string = "localhost", # Hostname or username (if containing `@`) to activate
--dry-run # Dry run (don't actually activate)
] {
let spec = parseFlakeOutputRef $ref
if $spec.user != null {
activate_home $spec.user $spec.host --dry-run=$dry_run
} else {
let host = if ($spec.host | is-empty) { $CURRENT_HOSTNAME } else { $spec.host }
let hostData = get_host_data $host
activate_system $hostData --dry-run=$dry_run
}
}
def activate_home [ user: string, host: string, --dry-run ] {
if (($host | is-empty) or ($host == $CURRENT_HOSTNAME)) {
activate_home_local $user $host --dry-run=$dry_run
} else {
activate_home_remote_ssh $user $host --dry-run=$dry_run
}
}
def activate_home_local [ user: string, host: string, --dry-run ] {
let name = $"($user)" + (if ($host | is-empty) { "" } else { "@" + $host })
let extraArgs = if $dry_run { ["--dry-run"] } else { [] }
log info $"Activating home configuration ($name) (ansi purple)locally(ansi reset)"
log info $"(ansi blue_bold)>>>(ansi reset) home-manager switch ($extraArgs | str join) --flake ($data.cleanFlake)#($name)"
home-manager switch ...$extraArgs -b (date now | format date "nixos-unified.%Y-%m-%d-%H:%M:%S.bak") --flake $"($data.cleanFlake)#($name)"
}
def activate_home_remote_ssh [ user: string, host: string, --dry-run ] {
let name = $"($user)@($host)"
let sshTarget = $"($user)@($host)"
log info $"Activating home configuration ($name) (ansi purple_reverse)remotely(ansi reset) on ($sshTarget)"
# Copy the flake to the remote host.
nix_copy $data.cleanFlake $"ssh-ng://($sshTarget)"
# We re-run this activation script, but on the remote host (where it will invoke activate_home_local).
log info $'(ansi blue_bold)>>>(ansi reset) ssh -t ($sshTarget) nix --extra-experimental-features '"nix-command flakes"' run $"($data.cleanFlake)#activate" -- ($name) --dry-run=($dry_run)'
ssh -t $sshTarget nix --extra-experimental-features '"nix-command flakes"' run $"($data.cleanFlake)#activate" -- ($name) --dry-run=($dry_run)
}
def activate_system [ hostData: record, --dry-run=false ] {
log info $"(ansi grey)currentSystem=($data.system) currentHost=(ansi green_bold)($CURRENT_HOSTNAME)(ansi grey) targetHost=(ansi green_reverse)($hostData.host)(ansi reset)(ansi grey) hostData=($hostData)(ansi reset)"
if ($CURRENT_HOSTNAME == $hostData.host) {
# Since the user asked to activate current host, do so.
activate_system_local $hostData --dry-run=$dry_run
} else {
# Remote activation request, so copy the flake and the necessary inputs
# and then activate over SSH.
if $hostData.sshTarget == null {
log error $"sshTarget not found in host data for ($hostData.host). Add `nixos-unified.sshTarget = \"user@hostname\";` to your configuration."
exit 1
}
activate_system_remote_ssh $hostData --dry-run=$dry_run
}
}
def activate_system_local [ hostData: record, --dry-run=false ] {
log info $"Activating (ansi purple)locally(ansi reset)"
let darwin = $hostData.outputs.system in ["aarch64-darwin" "x86_64-darwin"]
if $darwin {
let subcommand = if $dry_run { "build" } else { "switch" }
log info $"(ansi blue_bold)>>>(ansi reset) sudo darwin-rebuild ($subcommand) --flake ($hostData.flake) ($hostData.outputs.nixArgs | str join)"
sudo darwin-rebuild $subcommand --flake $hostData.flake ...$hostData.outputs.nixArgs
} else {
let subcommand = if $dry_run { "dry-activate" } else { "switch" }
if $hostData.localPrivilegeMode == "sudo-nixos-rebuild" {
let nixosRebuild = "/run/current-system/sw/bin/nixos-rebuild"
log info $"(ansi blue_bold)>>>(ansi reset) sudo ($nixosRebuild) ($subcommand) --flake ($hostData.flake) ($hostData.outputs.nixArgs | str join)"
sudo $nixosRebuild $subcommand --flake $hostData.flake ...$hostData.outputs.nixArgs
} else {
log info $"(ansi blue_bold)>>>(ansi reset) nixos-rebuild ($subcommand) --flake ($hostData.flake) ($hostData.outputs.nixArgs | str join) --sudo"
nixos-rebuild $subcommand --flake $hostData.flake ...$hostData.outputs.nixArgs --sudo
}
}
}
def activate_system_remote_ssh [ hostData: record, --dry-run=false ] {
log info $"Activating (ansi purple_reverse)remotely(ansi reset) on ($hostData.sshTarget)"
# Copy the flake and the necessary inputs to the remote host.
nix_copy $data.cleanFlake $"ssh-ng://($hostData.sshTarget)"
$hostData.outputs.overrideInputs | transpose key value | each { |input|
nix_copy $input.value $"ssh-ng://($hostData.sshTarget)"
}
# We re-run this activation script, but on the remote host (where it will invoke activate_system_local).
log info $'(ansi blue_bold)>>>(ansi reset) ssh -t ($hostData.sshTarget) nix --extra-experimental-features '"nix-command flakes"' run ($hostData.outputs.nixArgs | str join) $"($data.cleanFlake)#activate" -- ($hostData.host) --dry-run=($dry_run)'
ssh -t $hostData.sshTarget nix --extra-experimental-features '"nix-command flakes"' run ...$hostData.outputs.nixArgs $"($data.cleanFlake)#activate" -- ($hostData.host) --dry-run=($dry_run)
}
def nix_copy [ src: string dst: string ] {
log info $"(ansi blue_bold)>>>(ansi reset) nix --extra-experimental-features \"nix-command flakes\" copy ($src) --to ($dst)"
nix --extra-experimental-features "nix-command flakes" copy $src --to $dst
}
================================================
FILE: activate/default.nix
================================================
{ self, inputs', pkgs, lib, system, ... }:
let
nixosFlakeNuModule =
let
# Workaround https://github.com/NixOS/nix/issues/8752
cleanFlake = lib.cleanSourceWith {
name = "nixos-unified-activate-flake";
src = self;
};
nixos-unified-configs = lib.mapAttrs (name: value: value.config.nixos-unified) (self.nixosConfigurations or { } // self.darwinConfigurations or { });
data = {
nixos-unified-configs = nixos-unified-configs;
system = system;
cleanFlake = cleanFlake;
};
dataFile = pkgs.writeTextFile {
name = "nixos-unified-activate-data";
text = ''
${builtins.toJSON data}
'';
};
in
pkgs.writeTextFile {
name = "nixos-unified.nu";
text = ''
export def getData [] {
open ${dataFile} | from json
}
'';
};
nu = import ./nu.nix { inherit pkgs; };
in
nu.writeNushellApplication {
name = "activate";
scriptDir = ./.;
meta = {
mainProgram = "activate.nu";
description = "Activate NixOS/nix-darwin/home-manager configurations";
};
runtimeInputs =
# TODO: better way to check for nix-darwin availability
lib.optionals (pkgs.stdenv.isDarwin && lib.hasAttr "nix-darwin" inputs') [
inputs'.nix-darwin.packages.default # Provides darwin-rebuild
] ++ lib.optionals (lib.hasAttr "home-manager" inputs') [
inputs'.home-manager.packages.default # Provides home-manager
] ++ [
pkgs.nixos-rebuild
pkgs.hostname
];
extraBuildCommand = ''
cp ${nixosFlakeNuModule} nixos-unified.nu
'';
}
================================================
FILE: activate/nu.nix
================================================
# Nix support for working Nushell scripts
#
# TODO: Migrate to this once merged,
# https://github.com/DeterminateSystems/nuenv/pull/27
{ pkgs, ... }:
{
# Like writeShellApplication but for Nushell scripts
#
# This function likely should be improved for general use.
writeNushellApplication =
{ name
, runtimeInputs ? [ ]
, scriptDir
, extraBuildCommand ? ""
, meta
}:
let
nixNuModule = pkgs.writeTextFile {
name = "nix.nu";
text = ''
use std *
let bins = '${builtins.toJSON (builtins.map (p: "${p}/bin") runtimeInputs)}' | from json
log debug $"Adding runtime inputs to PATH: ($bins)"
if $bins != [] {
path add ...$bins
}
'';
};
in
pkgs.runCommand name
{
inherit meta;
} ''
mkdir -p $out/bin
cp ${scriptDir}/*.nu $out/bin/
chmod -R a+w $out/bin
cd $out/bin
rm -f ${meta.mainProgram}
echo "#!${pkgs.nushell}/bin/nu" >> ${meta.mainProgram}
cat ${nixNuModule} >> ${meta.mainProgram}
cat ${scriptDir}/${meta.mainProgram} >> ${meta.mainProgram}
chmod a+x ${meta.mainProgram}
${extraBuildCommand}
'';
}
================================================
FILE: dev/flake.nix
================================================
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
flake-parts.url = "github:hercules-ci/flake-parts";
flake-root.url = "github:srid/flake-root";
treefmt-nix.url = "github:numtide/treefmt-nix";
nixos-unified.url = "github:srid/nixos-unified";
};
outputs = inputs@{ nixpkgs, flake-parts, ... }:
flake-parts.lib.mkFlake { inherit inputs; } {
systems = nixpkgs.lib.systems.flakeExposed;
imports = [
inputs.flake-root.flakeModule
inputs.treefmt-nix.flakeModule
];
perSystem = { pkgs, lib, config, ... }: {
treefmt.config = {
projectRoot = inputs.haskell-flake;
projectRootFile = "README.md";
programs.nixpkgs-fmt.enable = true;
};
devShells.default = pkgs.mkShell {
# cf. https://community.flake.parts/haskell-flake/devshell#composing-devshells
inputsFrom = [
config.treefmt.build.devShell
];
packages = with pkgs; [
just
nixd
];
shellHook = ''
echo
echo "🍎🍎 Run 'just <recipe>' to get started"
just
'';
};
};
};
}
================================================
FILE: doc/.gitignore
================================================
/book
/result
================================================
FILE: doc/examples.md
================================================
---
order: 10
---
# Examples
- <https://github.com/juspay/nixos-unified-template>
- <https://github.com/srid/nixos-config>
- <https://github.com/nammayatri/ci>
================================================
FILE: doc/flake.nix
================================================
{
inputs = {
emanote.url = "github:srid/emanote";
emanote.inputs.emanote-template.follows = "";
nixpkgs.follows = "emanote/nixpkgs";
flake-parts.follows = "emanote/flake-parts";
};
outputs = inputs@{ self, flake-parts, nixpkgs, ... }:
flake-parts.lib.mkFlake { inherit inputs; } {
systems = [ "x86_64-linux" "aarch64-darwin" ];
imports = [ inputs.emanote.flakeModule ];
perSystem = { self', pkgs, system, ... }: {
emanote = {
sites."default" = {
layers = [{ path = ./.; pathString = "."; }];
extraConfig.template = {
baseUrl = "/";
urlStrategy = "pretty";
};
};
};
};
};
}
================================================
FILE: doc/guide/activate.md
================================================
---
order: 2
---
# Activation
`nixos-unified` provides an `.#activate` flake app that can be used in place of `nixos-rebuild switch` (if using NixOS),`darwin-rebuild switch` (if using `nix-darwin`) or `home-manager switch` (if using home-manager)
In addition, it can remotely activate the system over SSH (see further below).
## Activating NixOS or nix-darwin configurations {#system}
In order to activate a system configuration for the current host (`$HOSTNAME`), run:
```sh
nix run .#activate
```
### Passwordless local NixOS activation {#passwordless-local-nixos}
By default, local NixOS activation runs `nixos-rebuild switch --sudo`, so
`nixos-rebuild` decides when to invoke `sudo` for privileged steps.
If you want sudoers to match a single command, configure the target host to run
`nixos-rebuild` itself through sudo:
```nix
{
nixos-unified.localPrivilegeMode = "sudo-nixos-rebuild";
}
```
This makes the activator run `/run/current-system/sw/bin/nixos-rebuild` via
sudo. Add a narrowly scoped sudoers rule for the user and command you use for
activation:
```nix
{
security.sudo.extraRules = [
{
users = [ "myuser" ];
commands = [
{
command = "/run/current-system/sw/bin/nixos-rebuild switch *";
options = [ "NOPASSWD" ];
}
];
}
];
}
```
> [!TIP]
> Usually, you'd make this your default package, so as to be able to use `nix run`. In `flake.nix`:
>
> ```nix
> # In perSystem
> {
> packages.default = self'.packages.activate
> }
> ```
## Activating home configuration {#home}
If you are on a non-NixOS Linux (or on macOS but you do not use nix-darwin), you will have a home-manager configuration. Suppose, you have it stored in `legacyPackages.homeConfigurations."myuser"` (where `myuser` matches `$USER`), you can activate that by running:
```sh
nix run .#activate $USER@
```
> [!NOTE]
> The activate app will activate the home-manager configuration if the argument contains a `@` (separating user and the optional hostname). The above command has no hostname, indicating that we are activating for the local host.
> [!NOTE]
> The activate app will move your existing dotfiles out of the way with a timestamped backup extension. For example, your existing `~/.zshrc` will be backed up in `~/.zshrc.nixos-unified.2025-01-15-22:29:54.bak`.
### Per-host home configurations {#home-perhost}
You may also have separate home configurations for each machine, such as `legacyPackages.homeConfigurations."myuser@myhost"`. These can be activated using:
```sh
nix run .#activate $USER@$HOSTNAME
```
This will activate the home-manager configuration for the specified host over SSH (see below).
## Remote Activation {#remote}
`nixos-unified` acts as a lightweight alternative to the various deployment tools such as `deploy-rs` and `colmena`. The `.#activate` app takes the hostname as an argument and supports remote activation for both system configurations (NixOS/nix-darwin) and home-manager configurations.
### Remote System Activation {#remote-system}
For NixOS or nix-darwin configurations, set the `nixos-unified.sshTarget` option in your configuration:
```nix
{
nixos-unified.sshTarget = "myuser@myhost";
}
```
Then, you will be able to run the following to deploy to `myhost` from any machine:
```sh
nix run .#activate myhost
```
### Remote Home-Manager Activation {#remote-home}
For home-manager configurations, remote activation works by specifying the user and hostname:
```sh
nix run .#activate myuser@myhost
```
This will:
1. Copy the flake and necessary inputs to the remote host via SSH
2. Run the home-manager activation remotely on the target machine
> [!NOTE]
> Remote home-manager activation uses the `user@host` format for the SSH connection, where the user is extracted from the configuration name and the host is the target machine.
### Non-goals
Remote activation doesn't seek to replace other deployment tools, and as such doesn't provide features like rollbacks. It is meant for simple deployment use cases.
> [!NOTE]
> It is possible however that `nixos-unified` can grow to support more sophisticated deployment capabilities
================================================
FILE: doc/guide/autowiring.md
================================================
---
order: 5
---
# Autowiring
An optional **autowiring** module is provided that will scan the directory structure and wire up the appropriate flake outputs automatically without you having to do it manually.
A ready demonstration is available in [nixos-unified-template](https://github.com/juspay/nixos-unified-template) as well as [srid/nixos-config](https://github.com/srid/nixos-config). In the latter, you will notice the following directory structure:
```
❮ lsd --tree --depth 1 configurations modules overlays packages
📁 configurations
├── 📁 darwin
├── 📁 home
└── 📁 nixos
📁 modules
├── 📁 darwin
├── 📁 flake
├── 📁 home
└── 📁 nixos
📁 overlays
└── ❄️ default.nix
📁 packages
├── ❄️ git-squash.nix
├── ❄️ sshuttle-via.nix
└── 📁 twitter-convert
```
Each of these are wired to the corresponding flake output, as indicated in the below table:
| Directory | Flake Output |
| ----------------------------------------- | ----------------------------------------------------------- |
| `configurations/nixos/foo.nix`[^default] | `nixosConfigurations.foo` |
| `configurations/darwin/foo.nix`[^default] | `darwinConfigurations.foo` |
| `configurations/home/foo.nix`[^default] | `legacyPackages.${system}.homeConfigurations.foo`[^hm-pkgs] |
| `modules/nixos/foo.nix` | `nixosModules.foo` |
| `modules/darwin/foo.nix` | `darwinModules.foo` |
| `modules/flake/foo.nix` | `flakeModules.foo` |
| `overlays/foo.nix` | `overlays.foo` |
| `packages/foo.nix` | `packages.${system}.foo`[^packages] |
## flake-parts
Autowiring is also provided if you use just flake-parts, via the `lib.mkFlake` function. In your top-level flake.nix, you only need to define your `outputs` as follows:
```nix
{
inputs = ...;
outputs = inputs:
inputs.nixos-unified.lib.mkFlake
{ inherit inputs; root = ./.; };
}
```
This will,
- Auto-import flake-parts modules under either `./nix/modules/flake` or `./modules/flake` (whichever exists)
- Use a sensible default for `systems` which can be overriden.
- Pass `root` as top-level module args, as a non-recursive way of referring to the path of the flake (without needing `inputs.self`).
See [srid/haskell-template's flake.nix](https://github.com/srid/haskell-template/blob/master/flake.nix) for a ready example. For another example, see [this emanote PR](https://github.com/srid/emanote/pull/558).
## Package Autowiring Example
The `packages/` directory allows you to define custom packages that will be automatically wired as flake outputs. Here's an example project structure:
```
❮ lsd --tree --depth 2 packages
📁 packages
├── ❄️ hello-world.nix
└── 📁 complex-app
└── ❄️ default.nix
```
Each package file should export a function compatible with `pkgs.callPackage`. Here are two examples:
**packages/hello-world.nix** - Simple shell script package:
```nix
{ lib, writeShellApplication }:
writeShellApplication {
name = "hello-world";
text = ''
echo "Hello from my autowired package!"
echo "Args: $*"
'';
meta = {
description = "A simple hello world script";
license = lib.licenses.mit;
};
}
```
**packages/complex-app/default.nix** - Directory-based package:
```nix
{ lib, stdenv, makeWrapper }:
stdenv.mkDerivation {
pname = "complex-app";
version = "1.0.0";
src = ./.;
nativeBuildInputs = [ makeWrapper ];
installPhase = ''
mkdir -p $out/bin
cp app.sh $out/bin/complex-app
chmod +x $out/bin/complex-app
'';
meta = {
description = "A more complex application";
license = lib.licenses.gpl3;
platforms = lib.platforms.unix;
};
}
```
After defining these packages, they become available in your flake outputs:
```bash
# Build and run packages
nix build .#hello-world
nix run .#complex-app
# List all autowired packages
nix flake show | grep packages
```
The packages will appear as:
- `packages.${system}.hello-world`
- `packages.${system}.complex-app`
[^default]: This path could as well be `configurations/nixos/foo/default.nix`. Likewise for other output types.
[^hm-pkgs]: Why `legacyPackages`? Because, creating a home-manager configuration [requires `pkgs`](https://github.com/srid/nixos-unified/blob/47a26bc9118d17500bbe0c4adb5ebc26f776cc36/nix/modules/flake-parts/lib.nix#L97). See <https://github.com/nix-community/home-manager/issues/3075>
[^packages]: Package files should export a function that can be called with `callPackage`. The autowiring system automatically calls `pkgs.callPackage` on each package file, making them available as `packages.${system}.{name}` in your flake outputs.
================================================
FILE: doc/guide/outputs.md
================================================
---
order: 4
---
# Flake Outputs
Importing the `nixos-unified` flake-parts module will autowire the following flake outputs in your flake:
| Name | Description |
| -------------------------------------- | --------------------------------------------------------------------------------------------- |
| **`nixos-unified.lib`** | Functions `mkLinuxSystem`, `mkMacosSystem` and `mkHomeConfiguration` |
| **`packages.update`** | Flake app to update key flake inputs |
| [**`packages.activate`**](activate.md) | Flake app to build & activate the system (locally or remotely over SSH) or home configuration |
In addition, all of your NixOS/nix-darwin/home-manager modules implicitly receive the following `specialArgs`:
- `flake@{self, inputs, config}` (`config` is from flake-parts)
- `rosettaPkgs` (if on darwin)
================================================
FILE: doc/guide/specialArgs.md
================================================
---
order: 3
---
# Module Arguments
Each of your NixOS, nix-darwin and home-manager modules implicitly receive a [`specialArgs`](https://nixos.asia/en/nix-modules) called `flake`.
The components of this `flake` attrset are:
| Name | Description |
| ---- | ----------- |
| `inputs` | The `inputs` of your flake; `inputs.self` referring to the flake itself |
| `config` | The flake-parts perSystem `config` |
[Here](https://github.com/srid/nixos-config/blob/a420e5f531172aef753b07a411de8e254207f5c6/modules/darwin/default.nix#L2-L5) is an example of how these can be used:
```nix
{ flake, pkgs, lib, ... }:
let
inherit (flake) config inputs;
inherit (inputs) self;
in
{
imports = [
# Reference a flake input directly from a nix-darwin module
inputs.agenix.darwinModules.default
];
# Reference an arbitrary flake-parts config
home-manager.users.${config.me.username} = { };
}
```
While the above example uses a nix-darwin module, you can do the same on NixOS or home-manager modules.
================================================
FILE: doc/guide/templates.md
================================================
---
order: 1
---
# Flake Templates
We provide four templates, depending on your needs:
## Available templates
You can easily initialize one of our templates using [Omnix](https://omnix.page/om/init.html)[^no-omnix]:
[^no-omnix]: If you do not use Omnix, you must use `nix flake init`, and manually change the template values such as username and hostname.
### NixOS only {#nixos}
NixOS configuration only, with [home-manager]
```sh
nix --accept-flake-config run github:juspay/omnix -- \
init -o ~/nix-config github:srid/nixos-unified#linux
```
### macOS only {#macos}
[nix-darwin] configuration only, with [home-manager]
```sh
nix --accept-flake-config run github:juspay/omnix -- \
init -o ~/nix-config github:srid/nixos-unified#macos
```
### Home only {#home}
[home-manager] configuration only (useful if you use other Linux distros or do not have admin access to the machine)
```bash
nix --accept-flake-config run github:juspay/omnix -- \
init -o ~/nix-config github:srid/nixos-unified#home
```
## After initializing the template
Run `nix run .#activate` (`nix run .#activate $USER@` if you are using the last template, "Home only") to activate the configuration.
- on macOS, if you get an error about `/etc/nix/nix.conf`, run:
```sh
sudo mv /etc/nix/nix.conf /etc/nix/nix.conf.before-nix-darwin
nix --extra-experimental-features "nix-command flakes" run .#activate
```
- on macOS, if you had used Determinate Systems nix-installer, you may want to [uninstall that Nix](https://github.com/LnL7/nix-darwin/issues/931#issuecomment-2075596824), such that we use the one provided by nix-darwin,
```sh
sudo -i nix-env --uninstall nix
```
[^intel]: If you are on an Intel Mac, also change `nixpkgs.hostPlatform` accordingly.
[home-manager]: https://github.com/nix-community/home-manager
[nix-darwin]: https://github.com/LnL7/nix-darwin
================================================
FILE: doc/guide.md
================================================
# Guide
- [[templates]]#
- [[activate]]#
- [[specialArgs]]#
- [[outputs]]#
- [[autowiring]]#
================================================
FILE: doc/history.md
================================================
---
order: 100
---
# Release history
## Unreleased
- autoWiring of flake outputs & `mkFlake`
- activate script
- add `--dry-run` (#104)
- Remote activation support for home-manager configurations (#143)
- home-manager
- More unique backup filenames (#97)
- Add a default `home.homeDirectory` based on the user's username (#117)
- Remove use of deprecated alias `--update-input` of `nix flake update`
- Use `sudo` when activating with nix-darwin (#130)
- Add an opt-in local NixOS activation mode that runs `nixos-rebuild` itself through `sudo`
- Fix `nix copy` command for legacy NixOS systems by adding experimental features flag (#138)
- Switch to runCommand since runCommandNoCC is dropped in newer nixpkgs (#147)
## 0.2.0 (2024-10-03)
Initial release, branched from `nixos-flake`
================================================
FILE: doc/howto.md
================================================
# HOWTO
## Creating shared configuration {#config}
You may want to share certain configuration (such as username or email) across multiple modules. Here is how you can do it:
1. Create a flake-parts module to hold the config schema. For example, [`config-module.nix`](https://github.com/juspay/nixos-unified-template/blob/9eeeb6c1ab4287ac0a37a22e72f053a3de82ddbc/modules/flake/config-module.nix)
1. Define your configuration in your config file. For example, [`config.nix`](https://github.com/juspay/nixos-unified-template/blob/9eeeb6c1ab4287ac0a37a22e72f053a3de82ddbc/modules/flake/config.nix).
1. Use your configuration from any of NixOS/ nix-darwin/ home-manager modules through `flake` [[specialArgs|specialArgs]], specifically `flake.config`. For example, see [here](https://github.com/juspay/nixos-unified-template/blob/9eeeb6c1ab4287ac0a37a22e72f053a3de82ddbc/modules/home/git.nix#L3).
================================================
FILE: doc/index.md
================================================
---
short-title: nixos-unified
template:
sidebar:
collapsed: true
emanote:
folder-folgezettel: false
---
# nixos-unified
[**nixos-unified**](https://github.com/srid/nixos-unified) is a [flake-parts](https://flake.parts/) module to unify [NixOS] + [nix-darwin] + [home-manager] configuration in a single flake, while providing a consistent interface at DX and UX level.
[NixOS]: https://nixos.org/
[nix-darwin]: https://github.com/LnL7/nix-darwin
[home-manager]: https://github.com/nix-community/home-manager
## Why?
nixos-unified provides the following features:
- **One-click activation & deployment**
- [[activate]]: An `.#activate` flake app that works uniformly on [NixOS], [nix-darwin] and [home-manager].
- [[activate#remote|Remote Activation]]: `.#activate` can also *remotely* activate machines (be it macOS or NixOS) over SSH, thus acting as a simple alternative to deployment tools like `deploy-rs` and `colmena`.
- Also: an `.#update` flake app to update the primary inputs (which can be overriden)
- **Seamless access to top-level flake**
- All [NixOS]/ [nix-darwin]/ [home-manager] modules receive [[specialArgs|specialArgs]] which includes all the information in the top-level flake.
- This enables those modules to be aware of the flake inputs, for instance.
- **Sensible defaults**
- Sensible defaults for [home-manager]/ [nix-darwin]/ and [NixOS] configurations ([\#75](https://github.com/srid/nixos-unified/pull/75)).
- **Autowiring** of flake outputs
- [[autowiring]]: An optional module that will scan the directory structure and wire up the appropriate flake outputs automatically without you having to do it manually.
## Getting Started
See: [[start]].
================================================
FILE: doc/index.yaml
================================================
# Emanote configuration for nixos-unified documentation
# Ref: https://github.com/srid/emanote/blob/master/emanote/default/index.yaml
template:
editBaseUrl: https://github.com/srid/nixos-unified/edit/master/doc
# List of available colors: https://tailwindcss.com/docs/customizing-colors#default-color-palette
theme: lime
sidebar:
collapsed: false
urlStrategy: pretty
page:
siteTitle: "nixos-unified"
siteUrl: https://nixos-unified.org
================================================
FILE: doc/mod.just
================================================
default:
@just --list doc
# Run mdbook live server
run:
nix run
# Build the static site
build:
nix build
================================================
FILE: doc/start.md
================================================
---
order: -100
---
# Getting Started
Pick your desired operating system and follow the below instructions.
> [!TIP]
> Checkout [nixos-unified-template](https://github.com/juspay/nixos-unified-template) for the quickest way to get started.
## NixOS
1. [Install NixOS w/ Flakes enabled](https://nixos.asia/en/nixos-tutorial)
1. Convert your `flake.nix` to using `nixos-unified` using the [NixOS only template](guide/templates.md) as reference.
## non-NixOS Linux
If you use other Linux distros like Ubuntu, you may use just `home-manager`.
1. [Install Nix](https://nixos.asia/en/install)
1. Use the [HOME only template](guide/templates.md)
## macOS
1. [Install Nix](https://nixos.asia/en/install)
1. Use the [macOS only template](guide/templates.md)
================================================
FILE: examples/home/flake.nix
================================================
{
inputs = {
# Principle inputs (updated by `nix run .#update`)
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
home-manager.url = "github:nix-community/home-manager";
home-manager.inputs.nixpkgs.follows = "nixpkgs";
flake-parts.url = "github:hercules-ci/flake-parts";
nixos-unified.url = "github:srid/nixos-unified";
};
outputs = inputs@{ self, ... }:
inputs.flake-parts.lib.mkFlake { inherit inputs; } {
systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" "x86_64-darwin" ];
imports = [
inputs.nixos-unified.flakeModules.default
];
perSystem = { pkgs, ... }:
let
myUserName = "john";
in
{
legacyPackages.homeConfigurations.${myUserName} =
self.nixos-unified.lib.mkHomeConfiguration
pkgs
({ pkgs, ... }: {
imports = [ self.homeModules.default ];
home.username = myUserName;
home.stateVersion = "24.11";
});
};
flake = {
# All home-manager configurations are kept here.
homeModules.default = { pkgs, ... }: {
imports = [ ];
programs = {
git.enable = true;
starship.enable = true;
bash.enable = true;
};
};
};
};
}
================================================
FILE: examples/linux/flake.nix
================================================
{
inputs = {
# Principle inputs (updated by `nix run .#update`)
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
home-manager.url = "github:nix-community/home-manager";
home-manager.inputs.nixpkgs.follows = "nixpkgs";
flake-parts.url = "github:hercules-ci/flake-parts";
nixos-unified.url = "github:srid/nixos-unified";
};
outputs = inputs@{ self, ... }:
inputs.flake-parts.lib.mkFlake { inherit inputs; } {
systems = [ "x86_64-linux" "aarch64-linux" ];
imports = [ inputs.nixos-unified.flakeModules.default ];
flake =
let
myUserName = "john";
in
{
# Configurations for Linux (NixOS) machines
nixosConfigurations."example1" =
self.nixos-unified.lib.mkLinuxSystem
{ home-manager = true; }
{
nixpkgs.hostPlatform = "x86_64-linux";
imports = [
# Your machine's configuration.nix goes here
({ pkgs, ... }: {
# TODO: Put your /etc/nixos/hardware-configuration.nix here
boot.loader.grub.device = "nodev";
fileSystems."/" = { device = "/dev/disk/by-label/nixos"; fsType = "btrfs"; };
users.users.${myUserName}.isNormalUser = true;
system.stateVersion = "23.05";
})
# Setup home-manager in NixOS config
{
home-manager.users.${myUserName} = {
imports = [ self.homeModules.default ];
home.stateVersion = "24.11";
};
}
];
};
# home-manager configuration goes here.
homeModules.default = { pkgs, ... }: {
imports = [ ];
programs.git.enable = true;
programs.starship.enable = true;
programs.bash.enable = true;
};
};
};
}
================================================
FILE: examples/macos/flake.nix
================================================
{
inputs = {
# Principle inputs (updated by `nix run .#update`)
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
nix-darwin.url = "github:lnl7/nix-darwin/master";
nix-darwin.inputs.nixpkgs.follows = "nixpkgs";
home-manager.url = "github:nix-community/home-manager";
home-manager.inputs.nixpkgs.follows = "nixpkgs";
flake-parts.url = "github:hercules-ci/flake-parts";
nixos-unified.url = "github:srid/nixos-unified";
};
outputs = inputs@{ self, ... }:
inputs.flake-parts.lib.mkFlake { inherit inputs; } {
systems = [ "aarch64-darwin" "x86_64-darwin" ];
imports = [ inputs.nixos-unified.flakeModules.default ];
flake =
let
myUserName = "john";
in
{
# Configurations for macOS machines
darwinConfigurations."example1" =
self.nixos-unified.lib.mkMacosSystem
{ home-manager = true; }
{
nixpkgs.hostPlatform = "aarch64-darwin";
imports = [
# Your nix-darwin configuration goes here
({ pkgs, ... }: {
# https://github.com/nix-community/home-manager/issues/4026#issuecomment-1565487545
users.users.${myUserName}.home = "/Users/${myUserName}";
security.pam.services.sudo_local.touchIdAuth = true;
# Used for backwards compatibility, please read the changelog before changing.
# $ darwin-rebuild changelog
system.stateVersion = 6;
})
# Setup home-manager in nix-darwin config
{
home-manager.users.${myUserName} = {
imports = [ self.homeModules.default ];
home.stateVersion = "24.11";
};
}
];
};
# home-manager configuration goes here.
homeModules.default = { pkgs, ... }: {
imports = [ ];
programs.git.enable = true;
programs.starship.enable = true;
programs.zsh.enable = true;
};
};
};
}
================================================
FILE: flake.nix
================================================
{
outputs = _: rec {
flakeModules = {
default = ./nix/modules/flake-parts;
autoWire = ./nix/modules/flake-parts/autowire.nix;
};
# For backwards compat only
flakeModule = flakeModules.default;
# Like flake-parts mkFlake, but auto-imports modules/flake-parts, consistent with autowiring feature.
#
# Looks under either nix/modules/flake-parts or modules/flake-parts for modules to import. `systems` is set to a default value. `root` is passed as top-level module args (as distinct from `inputs.self` the use of which can lead to infinite recursion).
lib.mkFlake =
{ inputs
, root
, systems ? [ "x86_64-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin" ]
, specialArgs ? { }
}:
inputs.flake-parts.lib.mkFlake { inherit inputs specialArgs; } {
inherit systems;
_module.args = { inherit root; };
imports =
let
# Patterns to search in order
candidates = [
# These correspond to `flakeModules.*`
"nix/modules/flake"
"modules/flake"
# Just for backwards compatbility
"nix/modules/flake-parts"
"modules/flake-parts"
];
getModulesUnderFirst = cs: with builtins;
if cs == [ ] then throw "None of these paths exist: ${toString candidates}"
else if pathExists "${root}/${head cs}"
then
map (fn: "${root}/${head cs}/${fn}") (attrNames (readDir (root + /${head cs})))
else getModulesUnderFirst (tail cs);
in
getModulesUnderFirst candidates;
};
templates =
let
tmplPath = path: builtins.path { inherit path; filter = path: _: baseNameOf path != "test.sh"; };
in
{
linux = {
description = "nixos-unified template for NixOS configuration.nix";
path = tmplPath ./examples/linux;
};
macos = {
description = "nixos-unified template for nix-darwin configuration";
path = tmplPath ./examples/macos;
};
home = {
description = "nixos-unified template for home-manager configuration";
path = tmplPath ./examples/home;
};
};
om = {
templates = rec {
home = {
template = templates.home;
params = [
{
name = "username";
description = "The $USER to apply home-manager configuration on";
placeholder = "john";
}
];
};
macos = {
template = templates.macos;
params = home.params ++ [
{
name = "hostname";
description = "Hostname of the machine";
placeholder = "example1";
}
];
};
linux = {
template = templates.linux;
inherit (macos) params;
};
};
};
};
}
================================================
FILE: justfile
================================================
# Documentation targets
mod doc
default:
@just --list
# Run CI locally
ci:
om ci --extra-access-tokens "github.com=$(gh auth token)"
# Auto-format the Nix files in project tree
fmt:
treefmt
================================================
FILE: nix/modules/configurations/default.nix
================================================
# A NixOS/nix-darwin module to specify nixos-unified metadata for configurations.
#
# FIXME: Using this module in home-manager leads to `error: infinite recursion
# encountered` on `id = x: x`
{ flake, config, lib, ... }:
let
inherit (flake) inputs;
in
{
options = {
nixos-unified = {
sshTarget = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = ''
SSH target for this system configuration.
'';
};
overrideInputs = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = ''
List of flake inputs to override when deploying or activating.
'';
};
localPrivilegeMode = lib.mkOption {
type = lib.types.enum [ "nixos-rebuild-sudo" "sudo-nixos-rebuild" ];
default = "nixos-rebuild-sudo";
description = ''
How local NixOS activation obtains root privileges.
`nixos-rebuild-sudo` runs `nixos-rebuild` as the calling user with
`--sudo`, letting nixos-rebuild invoke sudo for privileged steps.
`sudo-nixos-rebuild` runs `nixos-rebuild` itself via sudo. This is
useful when sudoers should allow passwordless activation by matching a
single `nixos-rebuild` command.
'';
};
outputs = {
system = lib.mkOption {
type = lib.types.str;
readOnly = true;
default = config.nixpkgs.hostPlatform.system;
description = ''
System to activate.
'';
};
overrideInputs = lib.mkOption {
type = lib.types.attrsOf lib.types.path;
readOnly = true;
default = lib.foldl' (acc: x: acc // { "${x}" = inputs.${x}; }) { } config.nixos-unified.overrideInputs;
};
nixArgs = lib.mkOption {
type = lib.types.listOf lib.types.str;
readOnly = true;
default = (builtins.concatMap
(name: [
"--override-input"
"${name}"
"${inputs.${name}}"
])
# TODO: Use `outputs.overrideInputs` instead.
config.nixos-unified.overrideInputs);
description = ''
Arguments to pass to `nix`
'';
};
};
};
};
}
================================================
FILE: nix/modules/flake-parts/autowire.nix
================================================
{ self, lib, ... }:
{
config =
let
# Combine mapAttrs' and filterAttrs
#
# f can return null if the attribute should be filtered out.
mapAttrsMaybe = f: attrs:
lib.pipe attrs [
(lib.mapAttrsToList f)
(builtins.filter (x: x != null))
builtins.listToAttrs
];
forAllNixFiles = dir: f:
if builtins.pathExists dir then
lib.pipe dir [
builtins.readDir
(mapAttrsMaybe (fn: type:
if type == "regular" then
let name = lib.removeSuffix ".nix" fn; in
if name != fn then
lib.nameValuePair name (f "${dir}/${fn}")
else
null
else if type == "directory" && builtins.pathExists "${dir}/${fn}/default.nix" then
lib.nameValuePair fn (f "${dir}/${fn}")
else
null
))
] else { };
in
{
flake = {
darwinConfigurations =
forAllNixFiles "${self}/configurations/darwin"
(fn: self.nixos-unified.lib.mkMacosSystem { home-manager = true; } fn);
nixosConfigurations =
forAllNixFiles "${self}/configurations/nixos"
(fn: self.nixos-unified.lib.mkLinuxSystem { home-manager = true; } fn);
darwinModules =
forAllNixFiles "${self}/modules/darwin"
(fn: fn);
nixosModules =
forAllNixFiles "${self}/modules/nixos"
(fn: fn);
homeModules =
forAllNixFiles "${self}/modules/home"
(fn: fn);
overlays =
forAllNixFiles "${self}/overlays"
(fn: import fn self.nixos-unified.lib.specialArgsFor.common);
};
perSystem = { pkgs, ... }: {
legacyPackages.homeConfigurations =
forAllNixFiles "${self}/configurations/home"
(fn: self.nixos-unified.lib.mkHomeConfiguration pkgs fn);
packages =
forAllNixFiles "${self}/packages"
(fn: pkgs.callPackage fn { });
};
};
}
================================================
FILE: nix/modules/flake-parts/default.nix
================================================
{
imports = [
./packages.nix
./lib.nix
];
}
================================================
FILE: nix/modules/flake-parts/lib.nix
================================================
{ self, inputs, config, lib, ... }:
let
specialArgsFor = rec {
common = {
flake = { inherit self inputs config; };
};
nixos = common;
darwin = common // {
rosettaPkgs = import inputs.nixpkgs { system = "x86_64-darwin"; };
};
};
nixosModules = {
# Linux home-manager module
home-manager = {
imports = [
inputs.home-manager.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.extraSpecialArgs = specialArgsFor.nixos;
home-manager.sharedModules = [ homeModules.common ];
}
];
};
# Common and useful setting across all platforms
common = { lib, ... }: {
nix = {
settings = {
# Use all CPU cores
max-jobs = lib.mkDefault "auto";
# Duh
experimental-features = lib.mkDefault "nix-command flakes";
};
};
};
};
homeModules = {
common = { config, pkgs, ... }: {
# Sensible default for `home.homeDirectory`
home.homeDirectory = lib.mkDefault "/${if pkgs.stdenv.isDarwin then "Users" else "home"}/${config.home.username}";
# For macOS, $PATH must contain these.
home.sessionPath = lib.mkIf pkgs.stdenv.isDarwin [
"/etc/profiles/per-user/$USER/bin" # To access home-manager binaries
"/nix/var/nix/profiles/system/sw/bin" # To access nix-darwin binaries
"/usr/local/bin" # Some macOS GUI programs install here
];
};
};
darwinModules = {
# macOS home-manager module
home-manager = {
imports = [
inputs.home-manager.darwinModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.extraSpecialArgs = specialArgsFor.darwin;
home-manager.sharedModules = [ homeModules.common ];
}
];
};
};
in
{
config = {
flake = {
nixos-unified.lib = {
inherit specialArgsFor;
mkLinuxSystem = { home-manager ? false }: mod: inputs.nixpkgs.lib.nixosSystem {
# Arguments to pass to all modules.
specialArgs = specialArgsFor.nixos;
modules = [
../configurations
nixosModules.common
mod
] ++ lib.optional home-manager nixosModules.home-manager;
};
mkMacosSystem = { home-manager ? false }: mod: inputs.nix-darwin.lib.darwinSystem {
specialArgs = specialArgsFor.darwin;
modules = [
../configurations
nixosModules.common
mod
] ++ lib.optional home-manager darwinModules.home-manager;
};
mkHomeConfiguration = pkgs: mod: inputs.home-manager.lib.homeManagerConfiguration {
inherit pkgs; # cf. https://github.com/nix-community/home-manager/issues/3075
extraSpecialArgs = specialArgsFor.common;
modules = [
homeModules.common
mod
];
};
};
};
};
}
================================================
FILE: nix/modules/flake-parts/packages.nix
================================================
{ self, flake-parts-lib, lib, ... }:
let
inherit (flake-parts-lib)
mkPerSystemOption;
inherit (lib)
types;
in
{
options.perSystem = mkPerSystemOption ({ config, inputs', pkgs, system, ... }: {
options.nixos-unified = lib.mkOption {
default = { };
type = types.submodule {
options = {
primary-inputs = lib.mkOption {
type = types.listOf types.str;
default = [ "nixpkgs" "home-manager" "nix-darwin" ];
description = ''
List of flake inputs to update when running `nix run .#update`.
'';
};
};
};
};
config.packages = lib.filterAttrs (_: v: v != null) {
update =
let
inputs = config.nixos-unified.primary-inputs;
in
pkgs.writeShellApplication {
name = "update-main-flake-inputs";
meta.description = "Update the primary flake inputs";
text = ''
nix flake update${lib.foldl' (acc: x: acc + " " + x) "" inputs}
'';
};
# Activate the given (system or home) configuration
activate = import ../../../activate { inherit self inputs' pkgs lib system; };
};
});
}
================================================
FILE: vira.hs
================================================
-- CI configuration <https://vira.nixos.asia/>
\ctx pipeline ->
let
isMaster = ctx.branch == "master"
nu = [("nixos-unified", ".")]
in pipeline
{ build.systems =
[ "x86_64-linux"
, "aarch64-darwin"
]
, build.flakes =
[ "./doc" { overrideInputs = nu }
, "./examples/macos" { overrideInputs = nu }
, "./examples/home" { overrideInputs = nu }
, "./examples/linux" { overrideInputs = nu }
]
, signoff.enable = True
, cache.url = if isMaster then Just "https://cache.nixos.asia/oss" else Nothing
}
gitextract_shy0x3kh/ ├── .envrc ├── .github/ │ └── workflows/ │ └── ci.yaml ├── .gitignore ├── .vscode/ │ ├── extensions.json │ └── settings.json ├── LICENSE ├── README.md ├── activate/ │ ├── activate.nu │ ├── default.nix │ └── nu.nix ├── dev/ │ └── flake.nix ├── doc/ │ ├── .gitignore │ ├── examples.md │ ├── flake.nix │ ├── guide/ │ │ ├── activate.md │ │ ├── autowiring.md │ │ ├── outputs.md │ │ ├── specialArgs.md │ │ └── templates.md │ ├── guide.md │ ├── history.md │ ├── howto.md │ ├── index.md │ ├── index.yaml │ ├── mod.just │ └── start.md ├── examples/ │ ├── home/ │ │ └── flake.nix │ ├── linux/ │ │ └── flake.nix │ └── macos/ │ └── flake.nix ├── flake.nix ├── justfile ├── nix/ │ └── modules/ │ ├── configurations/ │ │ └── default.nix │ └── flake-parts/ │ ├── autowire.nix │ ├── default.nix │ ├── lib.nix │ └── packages.nix └── vira.hs
Condensed preview — 37 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (56K chars).
[
{
"path": ".envrc",
"chars": 74,
"preview": "watch_file dev/flake.nix\nuse flake ./dev --override-input nixos-unified .\n"
},
{
"path": ".github/workflows/ci.yaml",
"chars": 1195,
"preview": "name: \"CI\"\non:\n push:\n branches:\n - master\njobs:\n website-upload:\n runs-on: ubuntu-latest\n if: github.re"
},
{
"path": ".gitignore",
"chars": 16,
"preview": "result\n/.direnv\n"
},
{
"path": ".vscode/extensions.json",
"chars": 218,
"preview": "{\n \"recommendations\": [\n \"bbenoist.nix\",\n \"b4dm4n.nixpkgs-fmt\",\n \"jnoortheen.nix-ide\",\n \""
},
{
"path": ".vscode/settings.json",
"chars": 121,
"preview": "{\n \"editor.defaultFormatter\": \"B4dM4n.nixpkgs-fmt\",\n \"editor.formatOnSave\": true,\n \"editor.formatOnType\": true\n"
},
{
"path": "LICENSE",
"chars": 1075,
"preview": "MIT License\n\nCopyright (c) 2023 Sridhar Ratnakumar\n\nPermission is hereby granted, free of charge, to any person obtainin"
},
{
"path": "README.md",
"chars": 1120,
"preview": "[](https://nixos.zulipchat.com/#narrow/stre"
},
{
"path": "activate/activate.nu",
"chars": 6938,
"preview": "use std log\nuse std assert\n\nuse nixos-unified.nu getData # This module is generated in Nix\n\nlet CURRENT_HOSTNAME = (hos"
},
{
"path": "activate/default.nix",
"chars": 1620,
"preview": "{ self, inputs', pkgs, lib, system, ... }:\n\nlet\n nixosFlakeNuModule =\n let\n # Workaround https://github.com/Nix"
},
{
"path": "activate/nu.nix",
"chars": 1224,
"preview": "# Nix support for working Nushell scripts\n#\n# TODO: Migrate to this once merged,\n# https://github.com/DeterminateSystems"
},
{
"path": "dev/flake.nix",
"chars": 1212,
"preview": "{\n inputs = {\n nixpkgs.url = \"github:nixos/nixpkgs/nixpkgs-unstable\";\n flake-parts.url = \"github:hercules-ci/flak"
},
{
"path": "doc/.gitignore",
"chars": 14,
"preview": "/book\n/result\n"
},
{
"path": "doc/examples.md",
"chars": 162,
"preview": "---\norder: 10\n---\n\n# Examples\n\n- <https://github.com/juspay/nixos-unified-template>\n- <https://github.com/srid/nixos-con"
},
{
"path": "doc/flake.nix",
"chars": 728,
"preview": "{\n inputs = {\n emanote.url = \"github:srid/emanote\";\n emanote.inputs.emanote-template.follows = \"\";\n nixpkgs.fo"
},
{
"path": "doc/guide/activate.md",
"chars": 4165,
"preview": "---\norder: 2\n---\n\n\n# Activation\n\n`nixos-unified` provides an `.#activate` flake app that can be used in place of `nixos-"
},
{
"path": "doc/guide/autowiring.md",
"chars": 4965,
"preview": "---\norder: 5\n---\n\n# Autowiring\n\nAn optional **autowiring** module is provided that will scan the directory structure and"
},
{
"path": "doc/guide/outputs.md",
"chars": 1045,
"preview": "---\norder: 4\n---\n\n# Flake Outputs\n\nImporting the `nixos-unified` flake-parts module will autowire the following flake ou"
},
{
"path": "doc/guide/specialArgs.md",
"chars": 1009,
"preview": "---\norder: 3\n---\n\n# Module Arguments\n\nEach of your NixOS, nix-darwin and home-manager modules implicitly receive a [`spe"
},
{
"path": "doc/guide/templates.md",
"chars": 1872,
"preview": "---\norder: 1\n---\n\n# Flake Templates\n\nWe provide four templates, depending on your needs:\n\n## Available templates\n\nYou ca"
},
{
"path": "doc/guide.md",
"chars": 94,
"preview": "\n# Guide\n\n- [[templates]]#\n- [[activate]]#\n- [[specialArgs]]#\n- [[outputs]]#\n- [[autowiring]]#"
},
{
"path": "doc/history.md",
"chars": 797,
"preview": "---\norder: 100\n---\n\n# Release history\n\n## Unreleased\n\n- autoWiring of flake outputs & `mkFlake`\n- activate script\n - ad"
},
{
"path": "doc/howto.md",
"chars": 895,
"preview": "# HOWTO\n\n## Creating shared configuration {#config}\n\nYou may want to share certain configuration (such as username or em"
},
{
"path": "doc/index.md",
"chars": 1709,
"preview": "---\nshort-title: nixos-unified\ntemplate:\n sidebar:\n collapsed: true\nemanote:\n folder-folgezettel: false\n---\n\n# nixo"
},
{
"path": "doc/index.yaml",
"chars": 455,
"preview": "# Emanote configuration for nixos-unified documentation\n# Ref: https://github.com/srid/emanote/blob/master/emanote/defau"
},
{
"path": "doc/mod.just",
"chars": 113,
"preview": "default:\n @just --list doc\n\n# Run mdbook live server\nrun:\n nix run\n\n# Build the static site\nbuild:\n nix build\n"
},
{
"path": "doc/start.md",
"chars": 759,
"preview": "---\norder: -100\n---\n\n# Getting Started\n\nPick your desired operating system and follow the below instructions.\n\n> [!TIP]\n"
},
{
"path": "examples/home/flake.nix",
"chars": 1357,
"preview": "{\n inputs = {\n # Principle inputs (updated by `nix run .#update`)\n nixpkgs.url = \"github:nixos/nixpkgs/nixos-unst"
},
{
"path": "examples/linux/flake.nix",
"chars": 2006,
"preview": "{\n inputs = {\n # Principle inputs (updated by `nix run .#update`)\n nixpkgs.url = \"github:nixos/nixpkgs/nixos-unst"
},
{
"path": "examples/macos/flake.nix",
"chars": 2207,
"preview": "{\n inputs = {\n # Principle inputs (updated by `nix run .#update`)\n nixpkgs.url = \"github:nixos/nixpkgs/nixos-unst"
},
{
"path": "flake.nix",
"chars": 3007,
"preview": "{\n outputs = _: rec {\n flakeModules = {\n default = ./nix/modules/flake-parts;\n autoWire = ./nix/modules/fl"
},
{
"path": "justfile",
"chars": 205,
"preview": "# Documentation targets\nmod doc\n\ndefault:\n @just --list\n\n# Run CI locally\nci:\n om ci --extra-access-tokens \"github"
},
{
"path": "nix/modules/configurations/default.nix",
"chars": 2335,
"preview": "# A NixOS/nix-darwin module to specify nixos-unified metadata for configurations.\n#\n# FIXME: Using this module in home-m"
},
{
"path": "nix/modules/flake-parts/autowire.nix",
"chars": 2097,
"preview": "{ self, lib, ... }:\n{\n config =\n let\n # Combine mapAttrs' and filterAttrs\n #\n # f can return null if "
},
{
"path": "nix/modules/flake-parts/default.nix",
"chars": 56,
"preview": "{\n imports = [\n ./packages.nix\n ./lib.nix\n ];\n}\n"
},
{
"path": "nix/modules/flake-parts/lib.nix",
"chars": 3073,
"preview": "{ self, inputs, config, lib, ... }:\nlet\n specialArgsFor = rec {\n common = {\n flake = { inherit self inputs conf"
},
{
"path": "nix/modules/flake-parts/packages.nix",
"chars": 1213,
"preview": "{ self, flake-parts-lib, lib, ... }:\nlet\n inherit (flake-parts-lib)\n mkPerSystemOption;\n inherit (lib)\n types;\ni"
},
{
"path": "vira.hs",
"chars": 599,
"preview": "-- CI configuration <https://vira.nixos.asia/>\n\\ctx pipeline ->\n let\n isMaster = ctx.branch == \"master\"\n nu = [(\""
}
]
About this extraction
This page contains the full source code of the srid/nixos-flake GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 37 files (50.5 KB), approximately 14.1k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.