Home Explore Blog Models CI



nixpkgs

1st chunk of `pkgs/by-name/ni/nixos-rebuild-ng/README.md`
062e9c20cdb9c1ae0a5075f9b636b76a4e707e03596562aa0000000100000b02
# nixos-rebuild-ng

Work-in-Progress rewrite of
[`nixos-rebuild`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/os-specific/linux/nixos-rebuild/nixos-rebuild.sh).

## Why the rewrite?

The current state of `nixos-rebuild` is dire: it is one of the most critical
pieces of code we have in NixOS, but it has tons of issues:
- The code is written in Bash, and while this by itself is not necessarily bad,
  it means that it is difficult to do refactorings due to the lack of tooling
  for the language
- The code itself is a hacky mess. Changing even one line of code can cause
  issues that affect dozens of people
- Lack of proper testing (we do have some integration tests, but no unit tests
  and coverage is probably pitiful)
- The code predates some of the improvements `nix` had over the years, e.g., it
  builds Flakes inside a temporary directory and reads the resulting symlink
  since the code seems to predate `--print-out-paths` flag

Given all of the above, improvements in the `nixos-rebuild` are difficult to
do. A full rewrite is probably the easier way to improve the situation since
this can be done in a separate package that will not break anyone. So this is
an attempt of the rewrite.

## Why Python?

- It is the language of choice for many critical things inside `nixpkgs`, like
  the `NixOSTest` and `systemd-boot-builder.py` activation scripts
- It is a language with great tooling, e.g.: `mypy` for type checking, `ruff`
  for linting, `pytest` for unit testing
- It is a scripting language that fits well with the scope of this project
- Python's standard library is great and it means we will need a low number of
  external dependencies for this project. For example, `nixos-rebuild`
  currently depends on `jq` for JSON parsing, while Python has `json` in
  standard library

## Development

Run:

```console
nix-build -A nixos-rebuild-ng -A nixos-rebuild-ng.tests.linters
```

The command above will build, run the unit tests and linters, and also check if
the code is formatted. However, sometimes it's more convenient to run just a few
tests to debug, in this case you can run:

```console
nix-shell -A nixos-rebuild-ng.devShell
```

The command above should automatically put you inside `src` directory, and you
can run:

```console
# run program
python -m nixos_rebuild
# run tests
pytest
# check types
mypy .
# fix lint issues
ruff check --fix .
# format code
ruff format .
```

## Breaking changes

While `nixos-rebuild-ng` tries to be as much of a clone of the original as
possible, there are still some breaking changes that were done in order to
improve the user experience. If they break your workflow in some way that is
not possible to fix, please open an issue and we can discuss a solution.

- For `--build-host` and `--target-host`, `nixos-rebuild-ng` does not allocate

Title: nixos-rebuild-ng: A Python Rewrite of nixos-rebuild
Summary
This document introduces `nixos-rebuild-ng`, a work-in-progress rewrite of the critical NixOS component `nixos-rebuild`. The rewrite is motivated by severe issues with the original Bash script, including its hacky nature, difficulty in refactoring, lack of proper testing, and outdated practices. Python was chosen for the rewrite due to its prevalence in `nixpkgs`, robust tooling (type checking, linting, testing), suitability as a scripting language, and comprehensive standard library. The document also provides instructions for development, testing, and linting, and notes that while `nixos-rebuild-ng` aims for compatibility, some breaking changes have been introduced for improved user experience.