aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2020-12-23 21:10:32 +0100
committerGitHub <noreply@github.com>2020-12-23 21:10:32 +0100
commita93916b1905cd7b968e92cd94a3e4a595bff2e0f (patch)
tree178e04a23a35b9a4ede224bdcb903e75c188a304
parent8927cba62f5afb33b01016d5c4f7f8b7d0adde3c (diff)
parent5178211e963fa111f84c4881b22cc506d5254fde (diff)
Merge pull request #4336 from NixOS/manpages
Documentation for nix subcommands
-rw-r--r--doc/manual/generate-manpage.nix7
-rw-r--r--src/libutil/args.cc34
-rw-r--r--src/libutil/args.hh20
-rw-r--r--src/nix/build.cc19
-rw-r--r--src/nix/build.md92
-rw-r--r--src/nix/bundle.cc11
-rw-r--r--src/nix/bundle.md36
-rw-r--r--src/nix/cat.cc14
-rw-r--r--src/nix/copy.cc29
-rw-r--r--src/nix/copy.md58
-rw-r--r--src/nix/develop.cc38
-rw-r--r--src/nix/develop.md94
-rw-r--r--src/nix/diff-closures.cc11
-rw-r--r--src/nix/diff-closures.md51
-rw-r--r--src/nix/dump-path.cc22
-rw-r--r--src/nix/edit.cc11
-rw-r--r--src/nix/edit.md31
-rw-r--r--src/nix/eval.cc27
-rw-r--r--src/nix/eval.md74
-rw-r--r--src/nix/flake-archive.md29
-rw-r--r--src/nix/flake-check.md68
-rw-r--r--src/nix/flake-clone.md18
-rw-r--r--src/nix/flake-info.md99
-rw-r--r--src/nix/flake-init.md54
-rw-r--r--src/nix/flake-list-inputs.md23
-rw-r--r--src/nix/flake-new.md34
-rw-r--r--src/nix/flake-show.md38
-rw-r--r--src/nix/flake-update.md53
-rw-r--r--src/nix/flake.cc98
-rw-r--r--src/nix/flake.md566
-rw-r--r--src/nix/help.md17
-rw-r--r--src/nix/log.cc19
-rw-r--r--src/nix/log.md40
-rw-r--r--src/nix/ls.cc28
-rw-r--r--src/nix/main.cc24
-rw-r--r--src/nix/make-content-addressable.cc17
-rw-r--r--src/nix/make-content-addressable.md59
-rw-r--r--src/nix/nar-cat.md19
-rw-r--r--src/nix/nar-dump-path.md17
-rw-r--r--src/nix/nar-ls.md24
-rw-r--r--src/nix/nar.cc9
-rw-r--r--src/nix/nar.md13
-rw-r--r--src/nix/nix.md119
-rw-r--r--src/nix/optimise-store.cc11
-rw-r--r--src/nix/optimise-store.md23
-rw-r--r--src/nix/path-info.cc35
-rw-r--r--src/nix/path-info.md94
-rw-r--r--src/nix/ping-store.cc13
-rw-r--r--src/nix/ping-store.md30
-rw-r--r--src/nix/print-dev-env.md19
-rw-r--r--src/nix/profile-diff-closures.md28
-rw-r--r--src/nix/profile-info.md31
-rw-r--r--src/nix/profile-install.md27
-rw-r--r--src/nix/profile-remove.md32
-rw-r--r--src/nix/profile-upgrade.md41
-rw-r--r--src/nix/profile.cc90
-rw-r--r--src/nix/profile.md107
-rw-r--r--src/nix/registry-add.md33
-rw-r--r--src/nix/registry-list.md29
-rw-r--r--src/nix/registry-pin.md38
-rw-r--r--src/nix/registry-remove.md16
-rw-r--r--src/nix/registry.cc35
-rw-r--r--src/nix/registry.md98
-rw-r--r--src/nix/repl.cc12
-rw-r--r--src/nix/repl.md57
-rw-r--r--src/nix/run.cc42
-rw-r--r--src/nix/run.md87
-rw-r--r--src/nix/search.cc25
-rw-r--r--src/nix/search.md72
-rw-r--r--src/nix/shell.md48
-rw-r--r--src/nix/show-derivation.cc17
-rw-r--r--src/nix/show-derivation.md103
-rw-r--r--src/nix/store-cat.md19
-rw-r--r--src/nix/store-dump-path.md23
-rw-r--r--src/nix/store-ls.md27
-rw-r--r--src/nix/upgrade-nix.cc15
-rw-r--r--src/nix/upgrade-nix.md28
-rw-r--r--src/nix/verify.cc15
-rw-r--r--src/nix/verify.md49
-rw-r--r--src/nix/why-depends.cc19
-rw-r--r--src/nix/why-depends.md80
81 files changed, 3246 insertions, 486 deletions
diff --git a/doc/manual/generate-manpage.nix b/doc/manual/generate-manpage.nix
index fbd7f3e7d..c2c748464 100644
--- a/doc/manual/generate-manpage.nix
+++ b/doc/manual/generate-manpage.nix
@@ -20,11 +20,6 @@ let
(attrNames def.commands))
+ "\n"
else "")
- + (if def.examples or [] != []
- then
- "# Examples\n\n"
- + concatStrings (map ({ description, command }: "${description}\n\n```console\n${command}\n```\n\n") def.examples)
- else "")
+ (if def ? doc
then def.doc + "\n\n"
else "")
@@ -43,7 +38,7 @@ let
if flag.category or "" != "config"
then
" - `--${longName}`"
- + (if flag ? shortName then " / `${flag.shortName}`" else "")
+ + (if flag ? shortName then " / `-${flag.shortName}`" else "")
+ (if flag ? labels then " " + (concatStringsSep " " (map (s: "*${s}*") flag.labels)) else "")
+ " \n"
+ " " + flag.description + "\n\n"
diff --git a/src/libutil/args.cc b/src/libutil/args.cc
index 61f9503ec..fb5cb80fb 100644
--- a/src/libutil/args.cc
+++ b/src/libutil/args.cc
@@ -254,6 +254,8 @@ nlohmann::json Args::toJSON()
res["description"] = description();
res["flags"] = std::move(flags);
res["args"] = std::move(args);
+ auto s = doc();
+ if (s != "") res.emplace("doc", stripIndentation(s));
return res;
}
@@ -351,38 +353,6 @@ void printTable(std::ostream & out, const Table2 & table)
}
}
-void Command::printHelp(const string & programName, std::ostream & out)
-{
- Args::printHelp(programName, out);
-
- auto exs = examples();
- if (!exs.empty()) {
- out << "\n" ANSI_BOLD "Examples:" ANSI_NORMAL "\n";
- for (auto & ex : exs)
- out << "\n"
- << " " << ex.description << "\n" // FIXME: wrap
- << " $ " << ex.command << "\n";
- }
-}
-
-nlohmann::json Command::toJSON()
-{
- auto exs = nlohmann::json::array();
-
- for (auto & example : examples()) {
- auto ex = nlohmann::json::object();
- ex["description"] = example.description;
- ex["command"] = chomp(stripIndentation(example.command));
- exs.push_back(std::move(ex));
- }
-
- auto res = Args::toJSON();
- res["examples"] = std::move(exs);
- auto s = doc();
- if (s != "") res.emplace("doc", stripIndentation(s));
- return res;
-}
-
MultiCommand::MultiCommand(const Commands & commands)
: commands(commands)
{
diff --git a/src/libutil/args.hh b/src/libutil/args.hh
index 8069fd70f..6ed541a32 100644
--- a/src/libutil/args.hh
+++ b/src/libutil/args.hh
@@ -25,6 +25,9 @@ public:
/* Return a short one-line description of the command. */
virtual std::string description() { return ""; }
+ /* Return documentation about this command, in Markdown format. */
+ virtual std::string doc() { return ""; }
+
protected:
static const size_t ArityAny = std::numeric_limits<size_t>::max();
@@ -225,28 +228,11 @@ struct Command : virtual Args
virtual void prepare() { };
virtual void run() = 0;
- /* Return documentation about this command, in Markdown format. */
- virtual std::string doc() { return ""; }
-
- struct Example
- {
- std::string description;
- std::string command;
- };
-
- typedef std::list<Example> Examples;
-
- virtual Examples examples() { return Examples(); }
-
typedef int Category;
static constexpr Category catDefault = 0;
virtual Category category() { return catDefault; }
-
- void printHelp(const string & programName, std::ostream & out) override;
-
- nlohmann::json toJSON() override;
};
typedef std::map<std::string, std::function<ref<Command>()>> Commands;
diff --git a/src/nix/build.cc b/src/nix/build.cc
index 67be4024b..c2974d983 100644
--- a/src/nix/build.cc
+++ b/src/nix/build.cc
@@ -43,22 +43,11 @@ struct CmdBuild : InstallablesCommand, MixDryRun, MixJSON, MixProfile
return "build a derivation or fetch a store path";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To build and run GNU Hello from NixOS 17.03:",
- "nix build -f channel:nixos-17.03 hello; ./result/bin/hello"
- },
- Example{
- "To build the build.x86_64-linux attribute from release.nix:",
- "nix build -f release.nix build.x86_64-linux"
- },
- Example{
- "To make a profile point at GNU Hello:",
- "nix build --profile /tmp/profile nixpkgs#hello"
- },
- };
+ return
+ #include "build.md"
+ ;
}
void run(ref<Store> store) override
diff --git a/src/nix/build.md b/src/nix/build.md
new file mode 100644
index 000000000..c2f3e387a
--- /dev/null
+++ b/src/nix/build.md
@@ -0,0 +1,92 @@
+R""(
+
+# Examples
+
+* Build the default package from the flake in the current directory:
+
+ ```console
+ # nix build
+ ```
+
+* Build and run GNU Hello from the `nixpkgs` flake:
+
+ ```console
+ # nix build nixpkgs#hello
+ # ./result/bin/hello
+ Hello, world!
+ ```
+
+* Build GNU Hello and Cowsay, leaving two result symlinks:
+
+ ```console
+ # nix build nixpkgs#hello nixpkgs#cowsay
+ # ls -l result*
+ lrwxrwxrwx 1 … result -> /nix/store/v5sv61sszx301i0x6xysaqzla09nksnd-hello-2.10
+ lrwxrwxrwx 1 … result-1 -> /nix/store/rkfrm0z6x6jmi7d3gsmma4j53h15mg33-cowsay-3.03+dfsg2
+ ```
+
+* Build a specific output:
+
+ ```console
+ # nix build nixpkgs#glibc.dev
+ # ls -ld ./result-dev
+ lrwxrwxrwx 1 … ./result-dev -> /nix/store/dkm3gwl0xrx0wrw6zi5x3px3lpgjhlw4-glibc-2.32-dev
+ ```
+
+* Build attribute `build.x86_64-linux` from (non-flake) Nix expression
+ `release.nix`:
+
+ ```console
+ # nix build -f release.nix build.x86_64-linux
+ ```
+
+* Build a NixOS system configuration from a flake, and make a profile
+ point to the result:
+
+ ```console
+ # nix build --profile /nix/var/nix/profiles/system \
+ ~/my-configurations#nixosConfigurations.machine.config.system.build.toplevel
+ ```
+
+ (This is essentially what `nixos-rebuild` does.)
+
+* Build an expression specified on the command line:
+
+ ```console
+ # nix build --impure --expr \
+ 'with import <nixpkgs> {};
+ runCommand "foo" {
+ buildInputs = [ hello ];
+ }
+ "hello > $out"'
+ # cat ./result
+ Hello, world!
+ ```
+
+ Note that `--impure` is needed because we're using `<nixpkgs>`,
+ which relies on the `$NIX_PATH` environment variable.
+
+* Fetch a store path from the configured substituters, if it doesn't
+ already exist:
+
+ ```console
+ # nix build /nix/store/rkfrm0z6x6jmi7d3gsmma4j53h15mg33-cowsay-3.03+dfsg2
+ ```
+
+# Description
+
+`nix build` builds the specified *installables*. Installables that
+resolve to derivations are built (or substituted if possible). Store
+path installables are substituted.
+
+Unless `--no-link` is specified, after a successful build, it creates
+symlinks to the store paths of the installables. These symlinks have
+the prefix `./result` by default; this can be overriden using the
+`--out-link` option. Each symlink has a suffix `-<N>-<outname>`, where
+*N* is the index of the installable (with the left-most installable
+having index 0), and *outname* is the symbolic derivation output name
+(e.g. `bin`, `dev` or `lib`). `-<N>` is omitted if *N* = 0, and
+`-<outname>` is omitted if *outname* = `out` (denoting the default
+output).
+
+)""
diff --git a/src/nix/bundle.cc b/src/nix/bundle.cc
index eddd82f40..5f558b01e 100644
--- a/src/nix/bundle.cc
+++ b/src/nix/bundle.cc
@@ -40,14 +40,11 @@ struct CmdBundle : InstallableCommand
return "bundle an application so that it works outside of the Nix store";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To bundle Hello:",
- "nix bundle hello"
- },
- };
+ return
+ #include "bundle.md"
+ ;
}
Category category() override { return catSecondary; }
diff --git a/src/nix/bundle.md b/src/nix/bundle.md
new file mode 100644
index 000000000..5e2298376
--- /dev/null
+++ b/src/nix/bundle.md
@@ -0,0 +1,36 @@
+R""(
+
+# Examples
+
+* Bundle Hello:
+
+ ```console
+ # nix bundle nixpkgs#hello
+ # ./hello
+ Hello, world!
+ ```
+
+* Bundle a specific version of Nix:
+
+ ```console
+ # nix bundle github:NixOS/nix/e3ddffb27e5fc37a209cfd843c6f7f6a9460a8ec
+ # ./nix --version
+ nix (Nix) 2.4pre20201215_e3ddffb
+ ```
+
+# Description
+
+`nix bundle` packs the closure of the [Nix app](./nix3-run.md)
+*installable* into a single self-extracting executable. See the
+[`nix-bundle` homepage](https://github.com/matthewbauer/nix-bundle)
+for more details.
+
+> **Note**
+>
+> This command only works on Linux.
+
+# Bundler definitions
+
+TODO
+
+)""
diff --git a/src/nix/cat.cc b/src/nix/cat.cc
index 2ecffc9a5..e28ee3c50 100644
--- a/src/nix/cat.cc
+++ b/src/nix/cat.cc
@@ -37,6 +37,13 @@ struct CmdCatStore : StoreCommand, MixCat
return "print the contents of a file in the Nix store on stdout";
}
+ std::string doc() override
+ {
+ return
+ #include "store-cat.md"
+ ;
+ }
+
void run(ref<Store> store) override
{
cat(store->getFSAccessor());
@@ -62,6 +69,13 @@ struct CmdCatNar : StoreCommand, MixCat
return "print the contents of a file inside a NAR file on stdout";
}
+ std::string doc() override
+ {
+ return
+ #include "nar-cat.md"
+ ;
+ }
+
void run(ref<Store> store) override
{
cat(makeNarAccessor(make_ref<std::string>(readFile(narPath))));
diff --git a/src/nix/copy.cc b/src/nix/copy.cc
index cb31aac8f..2394eb46d 100644
--- a/src/nix/copy.cc
+++ b/src/nix/copy.cc
@@ -54,32 +54,11 @@ struct CmdCopy : StorePathsCommand
return "copy paths between Nix stores";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To copy Firefox from the local store to a binary cache in file:///tmp/cache:",
- "nix copy --to file:///tmp/cache $(type -p firefox)"
- },
- Example{
- "To copy the entire current NixOS system closure to another machine via SSH:",
- "nix copy --to ssh://server /run/current-system"
- },
- Example{
- "To copy a closure from another machine via SSH:",
- "nix copy --from ssh://server /nix/store/a6cnl93nk1wxnq84brbbwr6hxw9gp2w9-blender-2.79-rc2"
- },
-#ifdef ENABLE_S3
- Example{
- "To copy Hello to an S3 binary cache:",
- "nix copy --to s3://my-bucket?region=eu-west-1 nixpkgs#hello"
- },
- Example{
- "To copy Hello to an S3-compatible binary cache:",
- "nix copy --to s3://my-bucket?region=eu-west-1&endpoint=example.com nixpkgs#hello"
- },
-#endif
- };
+ return
+ #include "copy.md"
+ ;
}
Category category() override { return catSecondary; }
diff --git a/src/nix/copy.md b/src/nix/copy.md
new file mode 100644
index 000000000..25e0ddadc
--- /dev/null
+++ b/src/nix/copy.md
@@ -0,0 +1,58 @@
+R""(
+
+# Examples
+
+* Copy Firefox from the local store to a binary cache in `/tmp/cache`:
+
+ ```console
+ # nix copy --to file:///tmp/cache $(type -p firefox)
+ ```
+
+ Note the `file://` - without this, the destination is a chroot
+ store, not a binary cache.
+
+* Copy the entire current NixOS system closure to another machine via
+ SSH:
+
+ ```console
+ # nix copy -s --to ssh://server /run/current-system
+ ```
+
+ The `-s` flag causes the remote machine to try to substitute missing
+ store paths, which may be faster if the link between the local and
+ remote machines is slower than the link between the remote machine
+ and its substituters (e.g. `https://cache.nixos.org`).
+
+* Copy a closure from another machine via SSH:
+
+ ```console
+ # nix copy --from ssh://server /nix/store/a6cnl93nk1wxnq84brbbwr6hxw9gp2w9-blender-2.79-rc2
+ ```
+
+* Copy Hello to a binary cache in an Amazon S3 bucket:
+
+ ```console
+ # nix copy --to s3://my-bucket?region=eu-west-1 nixpkgs#hello
+ ```
+
+ or to an S3-compatible storage system:
+
+ ```console
+ # nix copy --to s3://my-bucket?region=eu-west-1&endpoint=example.com nixpkgs#hello
+ ```
+
+ Note that this only works if Nix is built with AWS support.
+
+* Copy a closure from `/nix/store` to the chroot store `/tmp/nix/nix/store`:
+
+ ```console
+ # nix copy --to /tmp/nix nixpkgs#hello --no-check-sigs
+ ```
+
+# Description
+
+`nix copy` copies store path closures between two Nix stores. The
+source store is specified using `--from` and the destination using
+`--to`. If one of these is omitted, it defaults to the local store.
+
+)""
diff --git a/src/nix/develop.cc b/src/nix/develop.cc
index 457d94382..edd87f246 100644
--- a/src/nix/develop.cc
+++ b/src/nix/develop.cc
@@ -385,30 +385,11 @@ struct CmdDevelop : Common, MixEnvironment
return "run a bash shell that provides the build environment of a derivation";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To get the build environment of GNU hello:",
- "nix develop nixpkgs#hello"
- },
- Example{
- "To get the build environment of the default package of flake in the current directory:",
- "nix develop"
- },
- Example{
- "To store the build environment in a profile:",
- "nix develop --profile /tmp/my-shell nixpkgs#hello"
- },
- Example{
- "To use a build environment previously recorded in a profile:",
- "nix develop /tmp/my-shell"
- },
- Example{
- "To replace all occurences of a store path with a writable directory:",
- "nix develop --redirect nixpkgs#glibc.dev ~/my-glibc/outputs/dev"
- },
- };
+ return
+ #include "develop.md"
+ ;
}
void run(ref<Store> store) override
@@ -495,14 +476,11 @@ struct CmdPrintDevEnv : Common
return "print shell code that can be sourced by bash to reproduce the build environment of a derivation";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To apply the build environment of GNU hello to the current shell:",
- ". <(nix print-dev-env nixpkgs#hello)"
- },
- };
+ return
+ #include "print-dev-env.md"
+ ;
}
Category category() override { return catUtility; }
diff --git a/src/nix/develop.md b/src/nix/develop.md
new file mode 100644
index 000000000..e71d9f8aa
--- /dev/null
+++ b/src/nix/develop.md
@@ -0,0 +1,94 @@
+R""(
+
+# Examples
+
+* Start a shell with the build environment of the default package of
+ the flake in the current directory:
+
+ ```console
+ # nix develop
+ ```
+
+ Typical commands to run inside this shell are:
+
+ ```console
+ # configurePhase
+ # buildPhase
+ # installPhase
+ ```
+
+ Alternatively, you can run whatever build tools your project uses
+ directly, e.g. for a typical Unix project:
+
+ ```console
+ # ./configure --prefix=$out
+ # make
+ # make install
+ ```
+
+* Run a particular build phase directly:
+
+ ```console
+ # nix develop --configure
+ # nix develop --build
+ # nix develop --check
+ # nix develop --install
+ # nix develop --installcheck
+ ```
+
+* Start a shell with the build environment of GNU Hello:
+
+ ```console
+ # nix develop nixpkgs#hello
+ ```
+
+* Record a build environment in a profile:
+
+ ```console
+ # nix develop --profile /tmp/my-build-env nixpkgs#hello
+ ```
+
+* Use a build environment previously recorded in a profile:
+
+ ```console
+ # nix develop /tmp/my-build-env
+ ```
+
+* Replace all occurences of the store path corresponding to
+ `glibc.dev` with a writable directory:
+
+ ```console
+ # nix develop --redirect nixpkgs#glibc.dev ~/my-glibc/outputs/dev
+ ```
+
+ Note that this is useful if you're running a `nix develop` shell for
+ `nixpkgs#glibc` in `~/my-glibc` and want to compile another package
+ against it.
+
+# Description
+
+`nix develop` starts a `bash` shell that provides an interactive build
+environment nearly identical to what Nix would use to build
+*installable*. Inside this shell, environment variables and shell
+functions are set up so that you can interactively and incrementally
+build your package.
+
+Nix determines the build environment by building a modified version of
+the derivation *installable* that just records the environment
+initialised by `stdenv` and exits. This build environment can be
+recorded into a profile using `--profile`.
+
+The prompt used by the `bash` shell can be customised by setting the
+`bash-prompt` and `bash-prompt-suffix` settings in `nix.conf` or in
+the flake's `nixConfig` attribute.
+
+# Flake output attributes
+
+If no flake output attribute is given, `nix run` tries the following
+flake output attributes:
+
+* `devShell.<system>`
+
+* `defaultPackage.<system>`
+
+)""
diff --git a/src/nix/diff-closures.cc b/src/nix/diff-closures.cc
index f72b5eff7..0c7d531c1 100644
--- a/src/nix/diff-closures.cc
+++ b/src/nix/diff-closures.cc
@@ -121,14 +121,11 @@ struct CmdDiffClosures : SourceExprCommand
return "show what packages and versions were added and removed between two closures";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- {
- "To show what got added and removed between two versions of the NixOS system profile:",
- "nix store diff-closures /nix/var/nix/profiles/system-655-link /nix/var/nix/profiles/system-658-link",
- },
- };
+ return
+ #include "diff-closures.md"
+ ;
}
void run(ref<Store> store) override
diff --git a/src/nix/diff-closures.md b/src/nix/diff-closures.md
new file mode 100644
index 000000000..0294c0d8d
--- /dev/null
+++ b/src/nix/diff-closures.md
@@ -0,0 +1,51 @@
+R""(
+
+# Examples
+
+* Show what got added and removed between two versions of the NixOS
+ system profile:
+
+ ```console
+ # nix store diff-closures /nix/var/nix/profiles/system-655-link /nix/var/nix/profiles/system-658-link
+ acpi-call: 2020-04-07-5.8.16 → 2020-04-07-5.8.18
+ baloo-widgets: 20.08.1 → 20.08.2
+ bluez-qt: +12.6 KiB
+ dolphin: 20.08.1 → 20.08.2, +13.9 KiB
+ kdeconnect: 20.08.2 → ∅, -6597.8 KiB
+ kdeconnect-kde: ∅ → 20.08.2, +6599.7 KiB
+ …
+ ```
+
+# Description
+
+This command shows the differences between the two closures *before*
+and *after* with respect to the addition, removal, or version change
+of packages, as well as changes in store path sizes.
+
+For each package name in the two closures (where a package name is
+defined as the name component of a store path excluding the version),
+if there is a change in the set of versions of the package, or a
+change in the size of the store paths of more than 8 KiB, it prints a
+line like this:
+
+```console
+dolphin: 20.08.1 → 20.08.2, +13.9 KiB
+```
+
+No size change is shown if it's below the threshold. If the package
+does not exist in either the *before* or *after* closures, it is
+represented using `∅` (empty set) on the appropriate side of the
+arrow. If a package has an empty version string, the version is
+rendered as `ε` (epsilon).
+
+There may be multiple versions of a package in each closure. In that
+case, only the changed versions are shown. Thus,
+
+```console
+libfoo: 1.2, 1.3 → 1.4
+```
+
+leaves open the possibility that there are other versions (e.g. `1.1`)
+that exist in both closures.
+
+)""
diff --git a/src/nix/dump-path.cc b/src/nix/dump-path.cc
index 256db64a9..c4edc894b 100644
--- a/src/nix/dump-path.cc
+++ b/src/nix/dump-path.cc
@@ -11,14 +11,11 @@ struct CmdDumpPath : StorePathCommand
return "serialise a store path to stdout in NAR format";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To get a NAR from the binary cache https://cache.nixos.org/:",
- "nix store dump-path --store https://cache.nixos.org/ /nix/store/7crrmih8c52r8fbnqb933dxrsp44md93-glibc-2.25"
- },
- };
+ return
+ #include "store-dump-path.md"
+ ;
}
void run(ref<Store> store, const StorePath & storePath) override
@@ -49,14 +46,11 @@ struct CmdDumpPath2 : Command
return "serialise a path to stdout in NAR format";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To serialise directory 'foo' as a NAR:",
- "nix nar dump-path ./foo"
- },
- };
+ return
+ #include "nar-dump-path.md"
+ ;
}
void run() override
diff --git a/src/nix/edit.cc b/src/nix/edit.cc
index 51c16f5a9..6472dd27a 100644
--- a/src/nix/edit.cc
+++ b/src/nix/edit.cc
@@ -15,14 +15,11 @@ struct CmdEdit : InstallableCommand
return "open the Nix expression of a Nix package in $EDITOR";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To open the Nix expression of the GNU Hello package:",
- "nix edit nixpkgs#hello"
- },
- };
+ return
+ #include "edit.md"
+ ;
}
Category category() override { return catSecondary; }
diff --git a/src/nix/edit.md b/src/nix/edit.md
new file mode 100644
index 000000000..80563d06b
--- /dev/null
+++ b/src/nix/edit.md
@@ -0,0 +1,31 @@
+R""(
+
+# Examples
+
+* Open the Nix expression of the GNU Hello package:
+
+ ```console
+ # nix edit nixpkgs#hello
+ ```
+
+* Get the filename and line number used by `nix edit`:
+
+ ```console
+ # nix eval --raw nixpkgs#hello.meta.position
+ /nix/store/fvafw0gvwayzdan642wrv84pzm5bgpmy-source/pkgs/applications/misc/hello/default.nix:15
+ ```
+
+# Description
+
+This command opens the Nix expression of a derivation in an
+editor. The filename and line number of the derivation are taken from
+its `meta.position` attribute. Nixpkgs' `stdenv.mkDerivation` sets
+this attribute to the location of the definition of the
+`meta.description`, `version` or `name` derivation attributes.
+
+The editor to invoke is specified by the `EDITOR` environment
+variable. It defaults to `cat`. If the editor is `emacs`, `nano` or
+`vim`, it is passed the line number of the derivation using the
+argument `+<lineno>`.
+
+)""
diff --git a/src/nix/eval.cc b/src/nix/eval.cc
index ea82e5300..321df7495 100644
--- a/src/nix/eval.cc
+++ b/src/nix/eval.cc
@@ -40,30 +40,11 @@ struct CmdEval : MixJSON, InstallableCommand
return "evaluate a Nix expression";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- {
- "To evaluate a Nix expression given on the command line:",
- "nix eval --expr '1 + 2'"
- },
- {
- "To evaluate a Nix expression from a file or URI:",
- "nix eval -f ./my-nixpkgs hello.name"
- },
- {
- "To get the current version of Nixpkgs:",
- "nix eval --raw nixpkgs#lib.version"
- },
- {
- "To print the store path of the Hello package:",
- "nix eval --raw nixpkgs#hello"
- },
- {
- "To get a list of checks in the 'nix' flake:",
- "nix eval nix#checks.x86_64-linux --apply builtins.attrNames"
- },
- };
+ return
+ #include "eval.md"
+ ;
}
Category category() override { return catSecondary; }
diff --git a/src/nix/eval.md b/src/nix/eval.md
new file mode 100644
index 000000000..61334cde1
--- /dev/null
+++ b/src/nix/eval.md
@@ -0,0 +1,74 @@
+R""(
+
+# Examples
+
+* Evaluate a Nix expression given on the command line:
+
+ ```console
+ # nix eval --expr '1 + 2'
+ ```
+
+* Evaluate a Nix expression to JSON:
+
+ ```console
+ # nix eval --json --expr '{ x = 1; }'
+ {"x":1}
+ ```
+
+* Evaluate a Nix expression from a file:
+
+ ```console
+ # nix eval -f ./my-nixpkgs hello.name
+ ```
+
+* Get the current version of the `nixpkgs` flake:
+
+ ```console
+ # nix eval --raw nixpkgs#lib.version
+ ```
+
+* Print the store path of the Hello package:
+
+ ```console
+ # nix eval --raw nixpkgs#hello
+ ```
+
+* Get a list of checks in the `nix` flake:
+
+ ```console
+ # nix eval nix#checks.x86_64-linux --apply builtins.attrNames
+ ```
+
+* Generate a directory with the specified contents:
+
+ ```console
+ # nix eval --write-to ./out --expr '{ foo = "bar"; subdir.bla = "123"; }'
+ # cat ./out/foo
+ bar
+ # cat ./out/subdir/bla
+ 123
+
+# Description
+
+This command evaluates the Nix expression *installable* and prints the
+result on standard output.
+
+# Output format
+
+`nix eval` can produce output in several formats:
+
+* By default, the evaluation result is printed as a Nix expression.
+
+* With `--json`, the evaluation result is printed in JSON format. Note
+ that this fails if the result contains values that are not
+ representable as JSON, such as functions.
+
+* With `--raw`, the evaluation result must be a string, which is
+ printed verbatim, without any quoting.
+
+* With `--write-to` *path*, the evaluation result must be a string or
+ a nested attribute set whose leaf values are strings. These strings
+ are written to files named *path*/*attrpath*. *path* must not
+ already exist.
+
+)""
diff --git a/src/nix/flake-archive.md b/src/nix/flake-archive.md
new file mode 100644
index 000000000..85bbeeb16
--- /dev/null
+++ b/src/nix/flake-archive.md
@@ -0,0 +1,29 @@
+R""(
+
+# Examples
+
+* Copy the `dwarffs` flake and its dependencies to a binary cache:
+
+ ```console
+ # nix flake archive --to file:///tmp/my-cache dwarffs
+ ```
+
+* Fetch the `dwarffs` flake and its dependencies to the local Nix
+ store:
+
+ ```console
+ # nix flake archive dwarffs
+ ```
+
+* Print the store paths of the flake sources of NixOps without
+ fetching them:
+
+ ```console
+ # nix flake archive --json --dry-run nixops
+ ```
+
+# Description
+
+FIXME
+
+)""
diff --git a/src/nix/flake-check.md b/src/nix/flake-check.md
new file mode 100644
index 000000000..dc079ba0c
--- /dev/null
+++ b/src/nix/flake-check.md
@@ -0,0 +1,68 @@
+R""(
+
+# Examples
+
+* Evaluate the flake in the current directory, and build its checks:
+
+ ```console
+ # nix flake check
+ ```
+
+* Verify that the `patchelf` flake evaluates, but don't build its
+ checks:
+
+ ```console
+ # nix flake check --no-build github:NixOS/patchelf
+ ```
+
+# Description
+
+This command verifies that the flake specified by flake reference
+*flake-url* can be evaluated successfully (as detailed below), and
+that the derivations specified by the flake's `checks` output can be
+built successfully.
+
+# Evaluation checks
+
+This following flake output attributes must be derivations:
+
+* `checks.`*system*`.`*name*
+* `defaultPackage.`*system*`
+* `devShell.`*system*`
+* `nixosConfigurations.`*name*`.config.system.build.toplevel
+* `packages.`*system*`.`*name*
+
+The following flake output attributes must be [app
+definitions](./nix3-run.md):
+
+* `apps.`*system*`.`*name*
+* `defaultApp.`*system*`
+
+The following flake output attributes must be [template
+definitions](./nix3-flake-init.md):
+
+* `defaultTemplate`
+* `templates`.`*name*
+
+The following flake output attributes must be *Nixpkgs overlays*:
+
+* `overlay`
+* `overlays`.`*name*
+
+The following flake output attributes must be *NixOS modules*:
+
+* `nixosModule`
+* `nixosModules`.`*name*
+
+The following flake output attributes must be
+[bundlers](./nix3-bundle.md):
+
+* `bundlers`.`*name*
+* `defaultBundler`
+
+In addition, the `hydraJobs` output is evaluated in the same way as
+Hydra's `hydra-eval-jobs` (i.e. as a arbitrarily deeply nested
+attribute set of derivations). Similarly, the
+`legacyPackages`.*system* output is evaluated like `nix-env -qa`.
+
+)""
diff --git a/src/nix/flake-clone.md b/src/nix/flake-clone.md
new file mode 100644
index 000000000..36cb96051
--- /dev/null
+++ b/src/nix/flake-clone.md
@@ -0,0 +1,18 @@
+R""(
+
+# Examples
+
+* Check out the source code of the `dwarffs` flake and build it:
+
+ ```console
+ # nix flake clone dwarffs --dest dwarffs
+ # cd dwarffs
+ # nix build
+ ```
+
+# Description
+
+This command performs a Git or Mercurial clone of the repository
+containing the source code of the flake *flake-url*.
+
+)""
diff --git a/src/nix/flake-info.md b/src/nix/flake-info.md
new file mode 100644
index 000000000..fda3171db
--- /dev/null
+++ b/src/nix/flake-info.md
@@ -0,0 +1,99 @@
+R""(
+
+# Examples
+
+* Show what `nixpkgs` resolves to:
+
+ ```console
+ # nix flake info nixpkgs
+ Resolved URL: github:NixOS/nixpkgs
+ Locked URL: github:NixOS/nixpkgs/b67ba0bfcc714453cdeb8d713e35751eb8b4c8f4
+ Description: A collection of packages for the Nix package manager
+ Path: /nix/store/23qapccs6cfmwwrlq8kr41vz5vdmns3r-source
+ Revision: b67ba0bfcc714453cdeb8d713e35751eb8b4c8f4
+ Last modified: 2020-12-23 12:36:12
+ ```
+
+* Show information about `dwarffs` in JSON format:
+
+ ```console
+ # nix flake info dwarffs --json | jq .
+ {
+ "description": "A filesystem that fetches DWARF debug info from the Internet on demand",
+ "lastModified": 1597153508,
+ "locked": {
+ "lastModified": 1597153508,
+ "narHash": "sha256-VHg3MYVgQ12LeRSU2PSoDeKlSPD8PYYEFxxwkVVDRd0=",
+ "owner": "edolstra",
+ "repo": "dwarffs",
+ "rev": "d181d714fd36eb06f4992a1997cd5601e26db8f5",
+ "type": "github"
+ },
+ "original": {
+ "id": "dwarffs",
+ "type": "indirect"
+ },
+ "originalUrl": "flake:dwarffs",
+ "path": "/nix/store/hang3792qwdmm2n0d9nsrs5n6bsws6kv-source",
+ "resolved": {
+ "owner": "edolstra",
+ "repo": "dwarffs",
+ "type": "github"
+ },
+ "resolvedUrl": "github:edolstra/dwarffs",
+ "revision": "d181d714fd36eb06f4992a1997cd5601e26db8f5",
+ "url": "github:edolstra/dwarffs/d181d714fd36eb06f4992a1997cd5601e26db8f5"
+ }
+ ```
+
+# Description
+
+This command shows information about the flake specified by the flake
+reference *flake-url*. It resolves the flake reference using the
+[flake registry](./nix3-registry.md), fetches it, and prints some meta
+data. This includes:
+
+* `Resolved URL`: If *flake-url* is a flake identifier, then this is
+ the flake reference that specifies its actual location, looked up in
+ the flake registry.
+
+* `Locked URL`: A flake reference that contains a commit or content
+ hash and thus uniquely identifies a specific flake version.
+
+* `Description`: A one-line description of the flake, taken from the
+ `description` field in `flake.nix`.
+
+* `Path`: The store path containing the source code of the flake.
+
+* `Revision`: The Git or Mercurial commit hash of the locked flake.
+
+* `Revisions`: The number of ancestors of the Git or Mercurial commit
+ of the locked flake. Note that this is not available for `github`
+ flakes.
+
+* `Last modified`: For Git or Mercurial flakes, this is the commit
+ time of the commit of the locked flake; for tarball flakes, it's the
+ most recent timestamp of any file inside the tarball.
+
+With `--json`, the output is a JSON object with the following fields:
+
+* `original` and `originalUrl`: The flake reference specified by the
+ user (*flake-url*) in attribute set and URL representation.
+
+* `resolved` and `resolvedUrl`: The resolved flake reference (see
+ above) in attribute set and URL representation.
+
+* `locked` and `lockedUrl`: The locked flake reference (see above) in
+ attribute set and URL representation.
+
+* `description`: See `Description` above.
+
+* `path`: See `Path` above.
+
+* `revision`: See `Revision` above.
+
+* `revCount`: See `Revisions` above.
+
+* `lastModified`: See `Last modified` above.
+
+)""
diff --git a/src/nix/flake-init.md b/src/nix/flake-init.md
new file mode 100644
index 000000000..c66154ad5
--- /dev/null
+++ b/src/nix/flake-init.md
@@ -0,0 +1,54 @@
+R""(
+
+# Examples
+
+* Create a flake using the default template:
+
+ ```console
+ # nix flake init
+ ```
+
+* List available templates:
+
+ ```console
+ # nix flake show templates
+ ```
+
+* Create a flake from a specific template:
+
+ ```console
+ # nix flake init -t templates#simpleContainer
+ ```
+
+# Description
+
+This command creates a flake in the current directory by copying the
+files of a template. It will not overwrite existing files. The default
+template is `templates#defaultTemplate`, but this can be overriden
+using `-t`.
+
+# Template definitions
+
+A flake can declare templates through its `templates` and
+`defaultTemplate` output attributes. A template has two attributes:
+
+* `description`: A one-line description of the template, in CommonMark
+ syntax.
+
+* `path`: The path of the directory to be copied.
+
+Here is an example:
+
+```
+outputs = { self }: {
+
+ templates.rust = {
+ path = ./rust;
+ description = "A simple Rust/Cargo project";
+ };
+
+ templates.defaultTemplate = self.templates.rust;
+}
+```
+
+)""
diff --git a/src/nix/flake-list-inputs.md b/src/nix/flake-list-inputs.md
new file mode 100644
index 000000000..250e13be0
--- /dev/null
+++ b/src/nix/flake-list-inputs.md
@@ -0,0 +1,23 @@
+R""(
+
+# Examples
+
+* Show the inputs of the `hydra` flake:
+
+ ```console
+ # nix flake list-inputs github:NixOS/hydra
+ github:NixOS/hydra/bde8d81876dfc02143e5070e42c78d8f0d83d6f7
+ ├───nix: github:NixOS/nix/79aa7d95183cbe6c0d786965f0dbff414fd1aa67
+ │ ├───lowdown-src: github:kristapsdz/lowdown/1705b4a26fbf065d9574dce47a94e8c7c79e052f
+ │ └───nixpkgs: github:NixOS/nixpkgs/ad0d20345219790533ebe06571f82ed6b034db31
+ └───nixpkgs follows input 'nix/nixpkgs'
+ ```
+
+# Description
+
+This command shows the inputs of the flake specified by the flake
+referenced *flake-url*. Since it prints the locked inputs that result
+from generating or updating the lock file, this command essentially
+displays the contents of the flake's lock file in human-readable form.
+
+)""
diff --git a/src/nix/flake-new.md b/src/nix/flake-new.md
new file mode 100644
index 000000000..725695c01
--- /dev/null
+++ b/src/nix/flake-new.md
@@ -0,0 +1,34 @@
+R""(
+
+# Examples
+
+* Create a flake using the default template in the directory `hello`:
+
+ ```console
+ # nix flake new hello
+ ```
+
+* List available templates:
+
+ ```console
+ # nix flake show templates
+ ```
+
+* Create a flake from a specific template in the directory `hello`:
+
+ ```console
+ # nix flake new hello -t templates#trivial
+ ```
+
+# Description
+
+This command creates a flake in the directory `dest-dir`, which must
+not already exist. It's equivalent to:
+
+```console
+# mkdir dest-dir
+# cd dest-dir
+# nix flake init
+```
+
+)""
diff --git a/src/nix/flake-show.md b/src/nix/flake-show.md
new file mode 100644
index 000000000..1a42c44a0
--- /dev/null
+++ b/src/nix/flake-show.md
@@ -0,0 +1,38 @@
+R""(
+
+# Examples
+
+* Show the output attributes provided by the `patchelf` flake:
+
+ ```console
+ github:NixOS/patchelf/f34751b88bd07d7f44f5cd3200fb4122bf916c7e
+ ├───checks
+ │ ├───aarch64-linux
+ │ │ └───build: derivation 'patchelf-0.12.20201207.f34751b'
+ │ ├───i686-linux
+ │ │ └───build: derivation 'patchelf-0.12.20201207.f34751b'
+ │ └───x86_64-linux
+ │ └───build: derivation 'patchelf-0.12.20201207.f34751b'
+ ├───defaultPackage
+ │ ├───aarch64-linux: package 'patchelf-0.12.20201207.f34751b'
+ │ ├───i686-linux: package 'patchelf-0.12.20201207.f34751b'
+ │ └───x86_64-linux: package 'patchelf-0.12.20201207.f34751b'
+ ├───hydraJobs
+ │ ├───build
+ │ │ ├───aarch64-linux: derivation 'patchelf-0.12.20201207.f34751b'
+ │ │ ├───i686-linux: derivation 'patchelf-0.12.20201207.f34751b'
+ │ │ └───x86_64-linux: derivation 'patchelf-0.12.20201207.f34751b'
+ │ ├───coverage: derivation 'patchelf-coverage-0.12.20201207.f34751b'
+ │ ├───release: derivation 'patchelf-0.12.20201207.f34751b'
+ │ └───tarball: derivation 'patchelf-tarball-0.12.20201207.f34751b'
+ └───overlay: Nixpkgs overlay
+ ```
+
+# Description
+
+This command shows the output attributes provided by the flake
+specified by flake reference *flake-url*. These are the top-level
+attributes in the `outputs` of the flake, as well as lower-level
+attributes for some standard outputs (e.g. `packages` or `checks`).
+
+)""
diff --git a/src/nix/flake-update.md b/src/nix/flake-update.md
new file mode 100644
index 000000000..a2ffedd2a
--- /dev/null
+++ b/src/nix/flake-update.md
@@ -0,0 +1,53 @@
+R""(
+
+# Examples
+
+* Update the `nixpkgs` and `nix` inputs of the flake in the current
+ directory:
+
+ ```console
+ # nix flake update --update-input nixpkgs --update-input nix
+ * Updated 'nix': 'github:NixOS/nix/9fab14adbc3810d5cc1f88672fde1eee4358405c' -> 'github:NixOS/nix/8927cba62f5afb33b01016d5c4f7f8b7d0adde3c'
+ * Updated 'nixpkgs': 'github:NixOS/nixpkgs/3d2d8f281a27d466fa54b469b5993f7dde198375' -> 'github:NixOS/nixpkgs/a3a3dda3bacf61e8a39258a0ed9c924eeca8e293'
+ ```
+
+* Recreate the lock file (i.e. update all inputs) and commit the new
+ lock file:
+
+ ```console
+ # nix flake update --recreate-lock-file --commit-lock-file
+ …
+ warning: committed new revision '158bcbd9d6cc08ab859c0810186c1beebc982aad'
+ ```
+
+# Description
+
+This command updates the lock file of a flake (`flake.lock`) so that
+it contains a lock for every flake input specified in
+`flake.nix`. Note that every command that operates on a flake will
+also update the lock file if needed, and supports the same
+flags. Therefore,
+
+```console
+# nix flake update --update-input nixpkgs
+# nix build
+```
+
+is equivalent to:
+
+```console
+# nix build --update-input nixpkgs
+```
+
+Thus, this command is only useful if you want to update the lock file
+separately from any other action such as building.
+
+> **Note**
+>
+> This command does *not* update locks that are already present unless
+> you explicitly ask for it using `--update-input` or
+> `--recreate-lock-file`. Thus, if the lock file already has locks for
+> every input, then `nix flake update` (without arguments) does
+> nothing.
+
+)""
diff --git a/src/nix/flake.cc b/src/nix/flake.cc
index 066430c5d..2b91faa64 100644
--- a/src/nix/flake.cc
+++ b/src/nix/flake.cc
@@ -104,6 +104,13 @@ struct CmdFlakeUpdate : FlakeCommand
return "update flake lock file";
}
+ std::string doc() override
+ {
+ return
+ #include "flake-update.md"
+ ;
+ }
+
void run(nix::ref<nix::Store> store) override
{
/* Use --refresh by default for 'nix flake update'. */
@@ -134,6 +141,13 @@ struct CmdFlakeInfo : FlakeCommand, MixJSON
return "list info about a given flake";
}
+ std::string doc() override
+ {
+ return
+ #include "flake-info.md"
+ ;
+ }
+
void run(nix::ref<nix::Store> store) override
{
auto flake = getFlake();
@@ -153,6 +167,13 @@ struct CmdFlakeListInputs : FlakeCommand, MixJSON
return "list flake inputs";
}
+ std::string doc() override
+ {
+ return
+ #include "flake-list-inputs.md"
+ ;
+ }
+
void run(nix::ref<nix::Store> store) override
{
auto flake = lockFlake();
@@ -211,6 +232,13 @@ struct CmdFlakeCheck : FlakeCommand
return "check whether the flake evaluates and run its tests";
}
+ std::string doc() override
+ {
+ return
+ #include "flake-check.md"
+ ;
+ }
+
void run(nix::ref<nix::Store> store) override
{
settings.readOnlyMode = !build;
@@ -631,22 +659,11 @@ struct CmdFlakeInit : CmdFlakeInitCommon
return "create a flake in the current directory from a template";
}
- Examples examples() override
- {
- return {
- Example{
- "To create a flake using the default template:",
- "nix flake init"
- },
- Example{
- "To see available templates:",
- "nix flake show templates"
- },
- Example{
- "To create a flake from a specific template:",
- "nix flake init -t templates#nixos-container"
- },
- };
+ std::string doc() override
+ {
+ return
+ #include "flake-init.md"
+ ;
}
CmdFlakeInit()
@@ -662,6 +679,13 @@ struct CmdFlakeNew : CmdFlakeInitCommon
return "create a flake in the specified directory from a template";
}
+ std::string doc() override
+ {
+ return
+ #include "flake-new.md"
+ ;
+ }
+
CmdFlakeNew()
{
expectArgs({
@@ -681,6 +705,13 @@ struct CmdFlakeClone : FlakeCommand
return "clone flake repository";
}
+ std::string doc() override
+ {
+ return
+ #include "flake-clone.md"
+ ;
+ }
+
CmdFlakeClone()
{
addFlag({
@@ -720,22 +751,11 @@ struct CmdFlakeArchive : FlakeCommand, MixJSON, MixDryRun
return "copy a flake and all its inputs to a store";
}
- Examples examples() override
- {
- return {
- Example{
- "To copy the dwarffs flake and its dependencies to a binary cache:",
- "nix flake archive --to file:///tmp/my-cache dwarffs"
- },
- Example{
- "To fetch the dwarffs flake and its dependencies to the local Nix store:",
- "nix flake archive dwarffs"
- },
- Example{
- "To print the store paths of the flake sources of NixOps without fetching them:",
- "nix flake archive --json --dry-run nixops"
- },
- };
+ std::string doc() override
+ {
+ return
+ #include "flake-archive.md"
+ ;
}
void run(nix::ref<nix::Store> store) override
@@ -797,6 +817,13 @@ struct CmdFlakeShow : FlakeCommand
return "show the outputs provided by a flake";
}
+ std::string doc() override
+ {
+ return
+ #include "flake-show.md"
+ ;
+ }
+
void run(nix::ref<nix::Store> store) override
{
auto state = getEvalState();
@@ -955,6 +982,13 @@ struct CmdFlake : NixMultiCommand
return "manage Nix flakes";
}
+ std::string doc() override
+ {
+ return
+ #include "flake.md"
+ ;
+ }
+
void run() override
{
if (!command)
diff --git a/src/nix/flake.md b/src/nix/flake.md
new file mode 100644
index 000000000..440c45dd1
--- /dev/null
+++ b/src/nix/flake.md
@@ -0,0 +1,566 @@
+R""(
+
+# Description
+
+`nix flake` provides subcommands for creating, modifying and querying
+*Nix flakes*. Flakes are the unit for packaging Nix code in a
+reproducible and discoverable way. They can have dependencies on other
+flakes, making it possible to have multi-repository Nix projects.
+
+A flake is a filesystem tree (typically fetched from a Git repository
+or a tarball) that contains a file named `flake.nix` in the root
+directory. `flake.nix` specifies some metadata about the flake such as
+dependencies (called *inputs*), as well as its *outputs* (the Nix
+values such as packages or NixOS modules provided by the flake).
+
+# Flake references
+
+Flake references (*flakerefs*) are a way to specify the location of a
+flake. These have two different forms:
+
+* An attribute set representation, e.g.
+
+ ```nix
+ {
+ type = "github";
+ owner = "NixOS";
+ repo = "nixpkgs";
+ }
+ ```
+
+ The only required attribute is `type`. The supported types are
+ listed below.
+
+* A URL-like syntax, e.g.
+
+ ```
+ github:NixOS/nixpkgs
+ ```
+
+ These are used on the command line as a more convenient alternative
+ to the attribute set representation. For instance, in the command
+
+ ```console
+ # nix build github:NixOS/nixpkgs#hello
+ ```
+
+ `github:NixOS/nixpkgs` is a flake reference (while `hello` is an
+ output attribute). They are also allowed in the `inputs` attribute
+ of a flake, e.g.
+
+ ```nix
+ inputs.nixpkgs.url = github:NixOS/nixpkgs;
+ ```
+
+ is equivalent to
+
+ ```nix
+ inputs.nixpkgs = {
+ type = "github";
+ owner = "NixOS";
+ repo = "nixpkgs";
+ };
+ ```
+
+## Examples
+
+Here are some examples of flake references in their URL-like representation:
+
+* `.`: The flake in the current directory.
+* `/home/alice/src/patchelf`: A flake in some other directory.
+* `nixpkgs`: The `nixpkgs` entry in the flake registry.
+* `nixpkgs/a3a3dda3bacf61e8a39258a0ed9c924eeca8e293`: The `nixpkgs`
+ entry in the flake registry, with its Git revision overriden to a
+ specific value.
+* `github:NixOS/nixpkgs`: The `master` branch of the `NixOS/nixpkgs`
+ repository on GitHub.
+* `github:NixOS/nixpkgs/nixos-20.09`: The `nixos-20.09` branch of the
+ `nixpkgs` repository.
+* `github:NixOS/nixpkgs/a3a3dda3bacf61e8a39258a0ed9c924eeca8e293`: A
+ specific revision of the `nixpkgs` repository.
+* `github:edolstra/nix-warez?dir=blender`: A flake in a subdirectory
+ of a GitHub repository.
+* `git+https://github.com/NixOS/patchelf`: A Git repository.
+* `git+https://github.com/NixOS/patchelf?ref=master`: A specific
+ branch of a Git repository.
+* `git+https://github.com/NixOS/patchelf?ref=master&rev=f34751b88bd07d7f44f5cd3200fb4122bf916c7e`:
+ A specific branch *and* revision of a Git repository.
+* `https://github.com/NixOS/patchelf/archive/master.tar.gz`: A tarball
+ flake.
+
+## Flake reference attributes
+
+The following generic flake reference attributes are supported:
+
+* `dir`: The subdirectory of the flake in which `flake.nix` is
+ located. This parameter enables having multiple flakes in a
+ repository or tarball. The default is the root directory of the
+ flake.
+
+* `narHash`: The hash of the NAR serialisation (in SRI format) of the
+ contents of the flake. This is useful for flake types such as
+ tarballs that lack a unique content identifier such as a Git commit
+ hash.
+
+In addition, the following attributes are common to several flake
+reference types:
+
+* `rev`: A Git or Mercurial commit hash.
+
+* `ref`: A Git or Mercurial branch or tag name.
+
+Finally, some attribute are typically not specified by the user, but
+can occur in *locked* flake references and are available to Nix code:
+
+* `revCount`: The number of ancestors of the commit `rev`.
+
+* `lastModified`: The timestamp (in seconds since the Unix epoch) of
+ the last modification of this version of the flake. For
+ Git/Mercurial flakes, this is the commit time of commit *rev*, while
+ for tarball flakes, it's the most recent timestamp of any file
+ inside the tarball.
+
+## Types
+
+Currently the `type` attribute can be one of the following:
+
+* `path`: arbitrary local directories, or local Git trees. The
+ required attribute `path` specifies the path of the flake. The URL
+ form is
+
+ ```
+ [path:]<path>(\?<params)?
+ ```
+
+ where *path* is an absolute path.
+
+ *path* must be a directory in the file system containing a file
+ named `flake.nix`.
+
+ If the directory or any of its parents is a Git repository, then
+ this is essentially equivalent to `git+file://<path>` (see below),
+ except that the `dir` parameter is derived automatically. For
+ example, if `/foo/bar` is a Git repository, then the flake reference
+ `/foo/bar/flake` is equivalent to `/foo/bar?dir=flake`.
+
+ If the directory is not inside a Git repository, then the flake
+ contents is the entire contents of *path*.
+
+ *path* generally must be an absolute path. However, on the command
+ line, it can be a relative path (e.g. `.` or `./foo`) which is
+ interpreted as relative to the current directory. In this case, it
+ must start with `.` to avoid ambiguity with registry lookups
+ (e.g. `nixpkgs` is a registry lookup; `./nixpkgs` is a relative
+ path).
+
+* `git`: Git repositories. The location of the repository is specified
+ by the attribute `url`.
+
+ They have the URL form
+
+ ```
+ git(+http|+https|+ssh|+git|+file|):(//<server>)?<path>(\?<params>)?
+ ```
+
+ The `ref` attribute defaults to `master`.
+
+ The `rev` attribute must denote a commit that exists in the branch
+ or tag specified by the `ref` attribute, since Nix doesn't do a full
+ clone of the remote repository by default (and the Git protocol
+ doesn't allow fetching a `rev` without a known `ref`). The default
+ is the commit currently pointed to by `ref`.
+
+ For example, the following are valid Git flake references:
+
+ * `git+https://example.org/my/repo`
+ * `git+https://example.org/my/repo?dir=flake1`
+ * `git+ssh://git@github.com/NixOS/nix?ref=v1.2.3`
+ * `git://github.com/edolstra/dwarffs?ref=unstable&rev=e486d8d40e626a20e06d792db8cc5ac5aba9a5b4`
+ * `git+file:///home/my-user/some-repo/some-repo`
+
+* `mercurial`: Mercurial repositories. The URL form is similar to the
+ `git` type, except that the URL schema must be one of `hg+http`,
+ `hg+https`, `hg+ssh` or `hg+file`.
+
+* `tarball`: Tarballs. The location of the tarball is specified by the
+ attribute `url`.
+
+ In URL form, the schema must be `http://`, `https://` or `file://`
+ URLs and the extension must be `.zip`, `.tar`, `.tar.gz`, `.tar.xz`
+ or `.tar.bz2`.
+
+* `github`: A more efficient way to fetch repositories from
+ GitHub. The following attributes are required:
+
+ * `owner`: The owner of the repository.
+
+ * `repo`: The name of the repository.
+
+ These are downloaded as tarball archives, rather than
+ through Git. This is often much faster and uses less disk space
+ since it doesn't require fetching the entire history of the
+ repository. On the other hand, it doesn't allow incremental fetching
+ (but full downloads are often faster than incremental fetches!).
+
+ The URL syntax for `github` flakes is:
+
+ ```
+ github:<owner>/<repo>(/<rev-or-ref>)?(\?<params>)?
+ ```
+
+ `<rev-or-ref>` specifies the name of a branch or tag (`ref`), or a
+ commit hash (`rev`). Note that unlike Git, GitHub allows fetching by
+ commit hash without specifying a branch or tag.
+
+ Some examples:
+
+ * `github:edolstra/dwarffs`
+ * `github:edolstra/dwarffs/unstable`
+ * `github:edolstra/dwarffs/d3f2baba8f425779026c6ec04021b2e927f61e31`
+
+* `indirect`: Indirections through the flake registry. These have the
+ form
+
+ ```
+ [flake:]<flake-id>(/<rev-or-ref>(/rev)?)?
+ ```
+
+ These perform a lookup of `<flake-id>` in the flake registry. or
+ example, `nixpkgs` and `nixpkgs/release-20.09` are indirect flake
+ references. The specified `rev` and/or `ref` are merged with the
+ entry in the registry; see [nix registry](./nix3-registry.md) for
+ details.
+
+# Flake format
+
+As an example, here is a simple `flake.nix` that depends on the
+Nixpkgs flake and provides a single package (i.e. an installable
+derivation):
+
+```nix
+{
+ description = "A flake for building Hello World";
+
+ inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-20.03;
+
+ outputs = { self, nixpkgs }: {
+
+ defaultPackage.x86_64-linux =
+ # Notice the reference to nixpkgs here.
+ with import nixpkgs { system = "x86_64-linux"; };
+ stdenv.mkDerivation {
+ name = "hello";
+ src = self;
+ buildPhase = "gcc -o hello ./hello.c";
+ installPhase = "mkdir -p $out/bin; install -t $out/bin hello";
+ };
+
+ };
+}
+```
+
+The following attributes are supported in `flake.nix`:
+
+* `description`: A short, one-line description of the flake.
+
+* `inputs`: An attrset specifying the dependencies of the flake
+ (described below).
+
+* `outputs`: A function that, given an attribute set containing the
+ outputs of each of the input flakes keyed by their identifier,
+ yields the Nix values provided by this flake. Thus, in the example
+ above, `inputs.nixpkgs` contains the result of the call to the
+ `outputs` function of the `nixpkgs` flake.
+
+ In addition to the outputs of each input, each input in `inputs`
+ also contains some metadata about the inputs. These are:
+
+ * `outPath`: The path in the Nix store of the flake's source tree.
+
+ * `rev`: The commit hash of the flake's repository, if applicable.
+
+ * `revCount`: The number of ancestors of the revision `rev`. This is
+ not available for `github` repositories, since they're fetched as
+ tarballs rather than as Git repositories.
+
+ * `lastModifiedDate`: The commit time of the revision `rev`, in the
+ format `%Y%m%d%H%M%S` (e.g. `20181231100934`). Unlike `revCount`,
+ this is available for both Git and GitHub repositories, so it's
+ useful for generating (hopefully) monotonically increasing version
+ strings.
+
+ * `lastModified`: The commit time of the revision `rev` as an integer
+ denoting the number of seconds since 1970.
+
+ * `narHash`: The SHA-256 (in SRI format) of the NAR serialization of
+ the flake's source tree.
+
+ The value returned by the `outputs` function must be an attribute
+ set. The attributes can have arbitrary values; however, various
+ `nix` subcommands require specific attributes to have a specific
+ value (e.g. `packages.x86_64-linux` must be an attribute set of
+ derivations built for the `x86_64-linux` platform).
+
+## Flake inputs
+
+The attribute `inputs` specifies the dependencies of a flake, as an
+attrset mapping input names to flake references. For example, the
+following specifies a dependency on the `nixpkgs` and `import-cargo`
+repositories:
+
+```nix
+# A GitHub repository.
+inputs.import-cargo = {
+ type = "github";
+ owner = "edolstra";
+ repo = "import-cargo";
+};
+
+# An indirection through the flake registry.
+inputs.nixpkgs = {
+ type = "indirect";
+ id = "nixpkgs";
+};
+```
+
+Alternatively, you can use the URL-like syntax:
+
+```nix
+inputs.import-cargo.url = github:edolstra/import-cargo;
+inputs.nixpkgs.url = "nixpkgs";
+```
+
+Each input is fetched, evaluated and passed to the `outputs` function
+as a set of attributes with the same name as the corresponding
+input. The special input named `self` refers to the outputs and source
+tree of *this* flake. Thus, a typical `outputs` function looks like
+this:
+
+```nix
+outputs = { self, nixpkgs, import-cargo }: {
+ ... outputs ...
+};
+```
+
+It is also possible to omit an input entirely and *only* list it as
+expected function argument to `outputs`. Thus,
+
+```nix
+outputs = { self, nixpkgs }: ...;
+```
+
+without an `inputs.nixpkgs` attribute is equivalent to
+
+```nix
+inputs.nixpkgs = {
+ type = "indirect";
+ id = "nixpkgs";
+};
+```
+
+Repositories that don't contain a `flake.nix` can also be used as
+inputs, by setting the input's `flake` attribute to `false`:
+
+```nix
+inputs.grcov = {
+ type = "github";
+ owner = "mozilla";
+ repo = "grcov";
+ flake = false;
+};
+
+outputs = { self, nixpkgs, grcov }: {
+ packages.x86_64-linux.grcov = stdenv.mkDerivation {
+ src = grcov;
+ ...
+ };
+};
+```
+
+Transitive inputs can be overriden from a `flake.nix` file. For
+example, the following overrides the `nixpkgs` input of the `nixops`
+input:
+
+```nix
+inputs.nixops.inputs.nixpkgs = {
+ type = "github";
+ owner = "my-org";
+ repo = "nixpkgs";
+};
+```
+
+It is also possible to "inherit" an input from another input. This is
+useful to minimize flake dependencies. For example, the following sets
+the `nixpkgs` input of the top-level flake to be equal to the
+`nixpkgs` input of the `dwarffs` input of the top-level flake:
+
+```nix
+inputs.nixops.follows = "dwarffs/nixpkgs";
+```
+
+The value of the `follows` attribute is a `/`-separated sequence of
+input names denoting the path of inputs to be followed from the root
+flake.
+
+Overrides and `follows` can be combined, e.g.
+
+```nix
+inputs.nixops.inputs.nixpkgs.follows = "dwarffs/nixpkgs";
+```
+
+sets the `nixpkgs` input of `nixops` to be the same as the `nixpkgs`
+input of `dwarffs`. It is worth noting, however, that it is generally
+not useful to eliminate transitive `nixpkgs` flake inputs in this
+way. Most flakes provide their functionality through Nixpkgs overlays
+or NixOS modules, which are composed into the top-level flake's
+`nixpkgs` input; so their own `nixpkgs` input is usually irrelevant.
+
+# Lock files
+
+Inputs specified in `flake.nix` are typically "unlocked" in the sense
+that they don't specify an exact revision. To ensure reproducibility,
+Nix will automatically generate and use a *lock file* called
+`flake.lock` in the flake's directory. The lock file contains a graph
+structure isomorphic to the graph of dependencies of the root
+flake. Each node in the graph (except the root node) maps the
+(usually) unlocked input specifications in `flake.nix` to locked input
+specifications. Each node also contains some metadata, such as the
+dependencies (outgoing edges) of the node.
+
+For example, if `flake.nix` has the inputs in the example above, then
+the resulting lock file might be:
+
+```json
+{
+ "version": 7,
+ "root": "n1",
+ "nodes": {
+ "n1": {
+ "inputs": {
+ "nixpkgs": "n2",
+ "import-cargo": "n3",
+ "grcov": "n4"
+ }
+ },
+ "n2": {
+ "inputs": {},
+ "locked": {
+ "owner": "edolstra",
+ "repo": "nixpkgs",
+ "rev": "7f8d4b088e2df7fdb6b513bc2d6941f1d422a013",
+ "type": "github",
+ "lastModified": 1580555482,
+ "narHash": "sha256-OnpEWzNxF/AU4KlqBXM2s5PWvfI5/BS6xQrPvkF5tO8="
+ },
+ "original": {
+ "id": "nixpkgs",
+ "type": "indirect"
+ }
+ },
+ "n3": {
+ "inputs": {},
+ "locked": {
+ "owner": "edolstra",
+ "repo": "import-cargo",
+ "rev": "8abf7b3a8cbe1c8a885391f826357a74d382a422",
+ "type": "github",
+ "lastModified": 1567183309,
+ "narHash": "sha256-wIXWOpX9rRjK5NDsL6WzuuBJl2R0kUCnlpZUrASykSc="
+ },
+ "original": {
+ "owner": "edolstra",
+ "repo": "import-cargo",
+ "type": "github"
+ }
+ },
+ "n4": {
+ "inputs": {},
+ "locked": {
+ "owner": "mozilla",
+ "repo": "grcov",
+ "rev": "989a84bb29e95e392589c4e73c29189fd69a1d4e",
+ "type": "github",
+ "lastModified": 1580729070,
+ "narHash": "sha256-235uMxYlHxJ5y92EXZWAYEsEb6mm+b069GAd+BOIOxI="
+ },
+ "original": {
+ "owner": "mozilla",
+ "repo": "grcov",
+ "type": "github"
+ },
+ "flake": false
+ }
+ }
+}
+```
+
+This graph has 4 nodes: the root flake, and its 3 dependencies. The
+nodes have arbitrary labels (e.g. `n1`). The label of the root node of
+the graph is specified by the `root` attribute. Nodes contain the
+following fields:
+
+* `inputs`: The dependencies of this node, as a mapping from input
+ names (e.g. `nixpkgs`) to node labels (e.g. `n2`).
+
+* `original`: The original input specification from `flake.lock`, as a
+ set of `builtins.fetchTree` arguments.
+
+* `locked`: The locked input specification, as a set of
+ `builtins.fetchTree` arguments. Thus, in the example above, when we
+ build this flake, the input `nixpkgs` is mapped to revision
+ `7f8d4b088e2df7fdb6b513bc2d6941f1d422a013` of the `edolstra/nixpkgs`
+ repository on GitHub.
+
+ It also includes the attribute `narHash`, specifying the expected
+ contents of the tree in the Nix store (as computed by `nix
+ hash-path`), and may include input-type-specific attributes such as
+ the `lastModified` or `revCount`. The main reason for these
+ attributes is to allow flake inputs to be substituted from a binary
+ cache: `narHash` allows the store path to be computed, while the
+ other attributes are necessary because they provide information not
+ stored in the store path.
+
+* `flake`: A Boolean denoting whether this is a flake or non-flake
+ dependency. Corresponds to the `flake` attribute in the `inputs`
+ attribute in `flake.nix`.
+
+The `original` and `locked` attributes are omitted for the root
+node. This is because we cannot record the commit hash or content hash
+of the root flake, since modifying `flake.lock` will invalidate these.
+
+The graph representation of lock files allows circular dependencies
+between flakes. For example, here are two flakes that reference each
+other:
+
+```nix
+{
+ inputs.b = ... location of flake B ...;
+ # Tell the 'b' flake not to fetch 'a' again, to ensure its 'a' is
+ # *this* 'a'.
+ inputs.b.inputs.a.follows = "";
+ outputs = { self, b }: {
+ foo = 123 + b.bar;
+ xyzzy = 1000;
+ };
+}
+```
+
+and
+
+```nix
+{
+ inputs.a = ... location of flake A ...;
+ inputs.a.inputs.b.follows = "";
+ outputs = { self, a }: {
+ bar = 456 + a.xyzzy;
+ };
+}
+```
+
+Lock files transitively lock direct as well as indirect
+dependencies. That is, if a lock file exists and is up to date, Nix
+will not look at the lock files of dependencies. However, lock file
+generation itself *does* use the lock files of dependencies by
+default.
+
+)""
diff --git a/src/nix/help.md b/src/nix/help.md
new file mode 100644
index 000000000..734f35028
--- /dev/null
+++ b/src/nix/help.md
@@ -0,0 +1,17 @@
+R""(
+
+# Examples
+
+* Show help about `nix` in general:
+
+ ```console
+ # nix help
+ ```
+
+* Show help about a particular subcommand:
+
+ ```console
+ # nix help flake info
+ ```
+
+)""
diff --git a/src/nix/log.cc b/src/nix/log.cc
index 33a3053f5..67d3742d6 100644
--- a/src/nix/log.cc
+++ b/src/nix/log.cc
@@ -13,22 +13,11 @@ struct CmdLog : InstallableCommand
return "show the build log of the specified packages or paths, if available";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To get the build log of GNU Hello:",
- "nix log nixpkgs#hello"
- },
- Example{
- "To get the build log of a specific path:",
- "nix log /nix/store/lmngj4wcm9rkv3w4dfhzhcyij3195hiq-thunderbird-52.2.1"
- },
- Example{
- "To get a build log from a specific binary cache:",
- "nix log --store https://cache.nixos.org nixpkgs#hello"
- },
- };
+ return
+ #include "log.md"
+ ;
}
Category category() override { return catSecondary; }
diff --git a/src/nix/log.md b/src/nix/log.md
new file mode 100644
index 000000000..1c76226a3
--- /dev/null
+++ b/src/nix/log.md
@@ -0,0 +1,40 @@
+R""(
+
+# Examples
+
+* Get the build log of GNU Hello:
+
+ ```console
+ # nix log nixpkgs#hello
+ ```
+
+* Get the build log of a specific store path:
+
+ ```console
+ # nix log /nix/store/lmngj4wcm9rkv3w4dfhzhcyij3195hiq-thunderbird-52.2.1
+ ```
+
+* Get a build log from a specific binary cache:
+
+ ```console
+ # nix log --store https://cache.nixos.org nixpkgs#hello
+ ```
+
+# Description
+
+This command prints the log of a previous build of the derivation
+*installable* on standard output.
+
+Nix looks for build logs in two places:
+
+* In the directory `/nix/var/log/nix/drvs`, which contains logs for
+ locally built derivations.
+
+* In the binary caches listed in the `substituters` setting. Logs
+ should be named `<cache>/log/<base-name-of-store-path>`, where
+ `store-path` is a derivation,
+ e.g. `https://cache.nixos.org/log/dvmig8jgrdapvbyxb1rprckdmdqx08kv-hello-2.10.drv`.
+ For non-derivation store paths, Nix will first try to determine the
+ deriver by fetching the `.narinfo` file for this store path.
+
+)""
diff --git a/src/nix/ls.cc b/src/nix/ls.cc
index 1f5ed6913..d48287f27 100644
--- a/src/nix/ls.cc
+++ b/src/nix/ls.cc
@@ -75,6 +75,8 @@ struct MixLs : virtual Args, MixJSON
if (json) {
JSONPlaceholder jsonRoot(std::cout);
+ if (showDirectory)
+ throw UsageError("'--directory' is useless with '--json'");
listNar(jsonRoot, accessor, path, recursive);
} else
listText(accessor);
@@ -92,19 +94,16 @@ struct CmdLsStore : StoreCommand, MixLs
});
}
- Examples examples() override
+ std::string description() override
{
- return {
- Example{
- "To list the contents of a store path in a binary cache:",
- "nix store ls --store https://cache.nixos.org/ -lR /nix/store/0i2jd68mp5g6h2sa5k9c85rb80sn8hi9-hello-2.10"
- },
- };
+ return "show information about a path in the Nix store";
}
- std::string description() override
+ std::string doc() override
{
- return "show information about a path in the Nix store";
+ return
+ #include "store-ls.md"
+ ;
}
void run(ref<Store> store) override
@@ -127,14 +126,11 @@ struct CmdLsNar : Command, MixLs
expectArg("path", &path);
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To list a specific file in a NAR:",
- "nix nar ls -l hello.nar /bin/hello"
- },
- };
+ return
+ #include "nar-ls.md"
+ ;
}
std::string description() override
diff --git a/src/nix/main.cc b/src/nix/main.cc
index e7a15dec9..b2406fafe 100644
--- a/src/nix/main.cc
+++ b/src/nix/main.cc
@@ -184,6 +184,13 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs
{
return "a tool for reproducible and declarative configuration management";
}
+
+ std::string doc() override
+ {
+ return
+ #include "nix.md"
+ ;
+ }
};
static void showHelp(std::vector<std::string> subcommand)
@@ -205,21 +212,14 @@ struct CmdHelp : Command
std::string description() override
{
- return "show help about 'nix' or a particular subcommand";
+ return "show help about `nix` or a particular subcommand";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To show help about 'nix' in general:",
- "nix help"
- },
- Example{
- "To show help about a particular subcommand:",
- "nix help run"
- },
- };
+ return
+ #include "help.md"
+ ;
}
void run() override
diff --git a/src/nix/make-content-addressable.cc b/src/nix/make-content-addressable.cc
index 5165c4804..f5bdc7e65 100644
--- a/src/nix/make-content-addressable.cc
+++ b/src/nix/make-content-addressable.cc
@@ -15,21 +15,14 @@ struct CmdMakeContentAddressable : StorePathsCommand, MixJSON
std::string description() override
{
- return "rewrite a path or closure to content-addressable form";
+ return "rewrite a path or closure to content-addressed form";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To create a content-addressable representation of GNU Hello (but not its dependencies):",
- "nix store make-content-addressable nixpkgs#hello"
- },
- Example{
- "To compute a content-addressable representation of the current NixOS system closure:",
- "nix store make-content-addressable -r /run/current-system"
- },
- };
+ return
+ #include "make-content-addressable.md"
+ ;
}
void run(ref<Store> store, StorePaths storePaths) override
diff --git a/src/nix/make-content-addressable.md b/src/nix/make-content-addressable.md
new file mode 100644
index 000000000..3dd847edc
--- /dev/null
+++ b/src/nix/make-content-addressable.md
@@ -0,0 +1,59 @@
+R""(
+
+# Examples
+
+* Create a content-addressed representation of the closure of GNU Hello:
+
+ ```console
+ # nix store make-content-addressable -r nixpkgs#hello
+ …
+ rewrote '/nix/store/v5sv61sszx301i0x6xysaqzla09nksnd-hello-2.10' to '/nix/store/5skmmcb9svys5lj3kbsrjg7vf2irid63-hello-2.10'
+ ```
+
+ Since the resulting paths are content-addressed, they are always
+ trusted and don't need signatures to copied to another store:
+
+ ```console
+ # nix copy --to /tmp/nix --trusted-public-keys '' /nix/store/5skmmcb9svys5lj3kbsrjg7vf2irid63-hello-2.10
+ ```
+
+ By contrast, the original closure is input-addressed, so it does
+ need signatures to be trusted:
+
+ ```console
+ # nix copy --to /tmp/nix --trusted-public-keys '' nixpkgs#hello
+ cannot add path '/nix/store/zy9wbxwcygrwnh8n2w9qbbcr6zk87m26-libunistring-0.9.10' because it lacks a valid signature
+ ```
+
+* Create a content-addressed representation of the current NixOS
+ system closure:
+
+ ```console
+ # nix store make-content-addressable -r /run/current-system
+ ```
+
+# Description
+
+This command converts the closure of the store paths specified by
+*installables* to content-addressed form. Nix store paths are usually
+*input-addressed*, meaning that the hash part of the store path is
+computed from the contents of the derivation (i.e., the build-time
+dependency graph). Input-addressed paths need to be signed by a
+trusted key if you want to import them into a store, because we need
+to trust that the contents of the path were actually built by the
+derivation.
+
+By contrast, in a *content-addressed* path, the hash part is computed
+from the contents of the path. This allows the contents of the path to
+be verified without any additional information such as
+signatures. This means that a command like
+
+```console
+# nix store build /nix/store/5skmmcb9svys5lj3kbsrjg7vf2irid63-hello-2.10 \
+ --substituters https://my-cache.example.org
+```
+
+will succeed even if the binary cache `https://my-cache.example.org`
+doesn't present any signatures.
+
+)""
diff --git a/src/nix/nar-cat.md b/src/nix/nar-cat.md
new file mode 100644
index 000000000..55c481a28
--- /dev/null
+++ b/src/nix/nar-cat.md
@@ -0,0 +1,19 @@
+R""(
+
+# Examples
+
+* List a file in a NAR and pipe it through `gunzip`:
+
+ ```console
+ # nix nar cat ./hello.nar /share/man/man1/hello.1.gz | gunzip
+ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.4.
+ .TH HELLO "1" "November 2014" "hello 2.10" "User Commands"
+ …
+ ```
+
+# Description
+
+This command prints on standard output the contents of the regular
+file *path* inside the NAR file *nar*.
+
+)""
diff --git a/src/nix/nar-dump-path.md b/src/nix/nar-dump-path.md
new file mode 100644
index 000000000..26191ad25
--- /dev/null
+++ b/src/nix/nar-dump-path.md
@@ -0,0 +1,17 @@
+R""(
+
+# Examples
+
+* To serialise directory `foo` as a NAR:
+
+ ```console
+ # nix nar dump-path ./foo > foo.nar
+ ```
+
+# Description
+
+This command generates a NAR file containing the serialisation of
+*path*, which must contain only regular files, directories and
+symbolic links. The NAR is written to standard output.
+
+)""
diff --git a/src/nix/nar-ls.md b/src/nix/nar-ls.md
new file mode 100644
index 000000000..d373f9715
--- /dev/null
+++ b/src/nix/nar-ls.md
@@ -0,0 +1,24 @@
+R""(
+
+# Examples
+
+* To list a specific file in a NAR:
+
+ ```console
+ # nix nar ls -l ./hello.nar /bin/hello
+ -r-xr-xr-x 38184 hello
+ ```
+
+* To recursively list the contents of a directory inside a NAR, in JSON
+ format:
+
+ ```console
+ # nix nar ls --json -R ./hello.nar /bin
+ {"type":"directory","entries":{"hello":{"type":"regular","size":38184,"executable":true,"narOffset":400}}}
+ ```
+
+# Description
+
+This command shows information about a *path* inside NAR file *nar*.
+
+)""
diff --git a/src/nix/nar.cc b/src/nix/nar.cc
index e239ce96a..0775d3c25 100644
--- a/src/nix/nar.cc
+++ b/src/nix/nar.cc
@@ -9,7 +9,14 @@ struct CmdNar : NixMultiCommand
std::string description() override
{
- return "query the contents of NAR files";
+ return "create or inspect NAR files";
+ }
+
+ std::string doc() override
+ {
+ return
+ #include "nar.md"
+ ;
}
Category category() override { return catUtility; }
diff --git a/src/nix/nar.md b/src/nix/nar.md
new file mode 100644
index 000000000..a83b5c764
--- /dev/null
+++ b/src/nix/nar.md
@@ -0,0 +1,13 @@
+R""(
+
+# Description
+
+`nix nar` provides several subcommands for creating and inspecting
+*Nix Archives* (NARs).
+
+# File format
+
+For the definition of the NAR file format, see Figure 5.2 in
+https://edolstra.github.io/pubs/phd-thesis.pdf.
+
+)""
diff --git a/src/nix/nix.md b/src/nix/nix.md
new file mode 100644
index 000000000..d10de7c01
--- /dev/null
+++ b/src/nix/nix.md
@@ -0,0 +1,119 @@
+R""(
+
+# Examples
+
+* Create a new flake:
+
+ ```console
+ # nix flake new hello
+ # cd hello
+ ```
+
+* Build the flake in the current directory:
+
+ ```console
+ # nix build
+ # ./result/bin/hello
+ Hello, world!
+ ```
+
+* Run the flake in the current directory:
+
+ ```console
+ # nix run
+ Hello, world!
+ ```
+
+* Start a development shell for hacking on this flake:
+
+ ```console
+ # nix develop
+ # unpackPhase
+ # cd hello-*
+ # configurePhase
+ # buildPhase
+ # ./hello
+ Hello, world!
+ # installPhase
+ # ../outputs/out/bin/hello
+ Hello, world!
+ ```
+
+# Description
+
+Nix is a tool for building software, configurations and other
+artifacts in a reproducible and declarative way. For more information,
+see the [Nix homepage](https://nixos.org/) or the [Nix
+manual](https://nixos.org/manual/nix/stable/).
+
+# Installables
+
+Many `nix` subcommands operate on one or more *installables*. These are
+command line arguments that represent something that can be built in
+the Nix store. Here are the recognised types of installables:
+
+* **Flake output attributes**: `nixpkgs#hello`
+
+ These have the form *flakeref*[`#`*attrpath*], where *flakeref* is a
+ flake reference and *attrpath* is an optional attribute path. For
+ more information on flakes, see [the `nix flake` manual
+ page](./nix3-flake.md). Flake references are most commonly a flake
+ identifier in the flake registry (e.g. `nixpkgs`) or a path
+ (e.g. `/path/to/my-flake` or `.`).
+
+ If *attrpath* is omitted, Nix tries some default values; for most
+ subcommands, the default is `defaultPackage.`*system*
+ (e.g. `defaultPackage.x86_64-linux`), but some subcommands have
+ other defaults. If *attrpath* *is* specified, *attrpath* is
+ interpreted as relative to one or more prefixes; for most
+ subcommands, these are `packages.`*system*,
+ `legacyPackages.*system*` and the empty prefix. Thus, on
+ `x86_64-linux` `nix build nixpkgs#hello` will try to build the
+ attributes `packages.x86_64-linux.hello`,
+ `legacyPackages.x86_64-linux.hello` and `hello`.
+
+* **Store paths**: `/nix/store/v5sv61sszx301i0x6xysaqzla09nksnd-hello-2.10`
+
+ These are paths inside the Nix store, or symlinks that resolve to a
+ path in the Nix store.
+
+* **Store derivations**: `/nix/store/p7gp6lxdg32h4ka1q398wd9r2zkbbz2v-hello-2.10.drv`
+
+ Store derivations are store paths with extension `.drv` and are a
+ low-level representation of a build-time dependency graph used
+ internally by Nix. By default, if you pass a store derivation to a
+ `nix` subcommand, it will operate on the *output paths* of the
+ derivation. For example, `nix path-info` prints information about
+ the output paths:
+
+ ```console
+ # nix path-info --json /nix/store/p7gp6lxdg32h4ka1q398wd9r2zkbbz2v-hello-2.10.drv
+ [{"path":"/nix/store/v5sv61sszx301i0x6xysaqzla09nksnd-hello-2.10",…}]
+ ```
+
+ If you want to operate on the store derivation itself, pass the
+ `--derivation` flag.
+
+* **Nix attributes**: `--file /path/to/nixpkgs hello`
+
+ When the `-f` / `--file` *path* option is given, installables are
+ interpreted as attribute paths referencing a value returned by
+ evaluating the Nix file *path*.
+
+* **Nix expressions**: `--expr '(import <nixpkgs> {}).hello.overrideDerivation (prev: { name = "my-hello"; })'`.
+
+ When the `--expr` option is given, all installables are interpreted
+ as Nix expressions. You may need to specify `--impure` if the
+ expression references impure inputs (such as `<nixpkgs>`).
+
+For most commands, if no installable is specified, the default is `.`,
+i.e. Nix will operate on the default flake output attribute of the
+flake in the current directory.
+
+# Nix stores
+
+Most `nix` subcommands operate on a *Nix store*.
+
+TODO: list store types, options
+
+)""
diff --git a/src/nix/optimise-store.cc b/src/nix/optimise-store.cc
index bc7f175ac..985006e5a 100644
--- a/src/nix/optimise-store.cc
+++ b/src/nix/optimise-store.cc
@@ -13,14 +13,11 @@ struct CmdOptimiseStore : StoreCommand
return "replace identical files in the store by hard links";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To optimise the Nix store:",
- "nix store optimise"
- },
- };
+ return
+ #include "optimise-store.md"
+ ;
}
void run(ref<Store> store) override
diff --git a/src/nix/optimise-store.md b/src/nix/optimise-store.md
new file mode 100644
index 000000000..f6fb66f97
--- /dev/null
+++ b/src/nix/optimise-store.md
@@ -0,0 +1,23 @@
+R""(
+
+# Examples
+
+* Optimise the Nix store:
+
+ ```console
+ nix store optimise
+ ```
+
+# Description
+
+This command deduplicates the Nix store: it scans the store for
+regular files with identical contents, and replaces them with hard
+links to a single instance.
+
+Note that you can also set `auto-optimise-store` to `true` in
+`nix.conf` to perform this optimisation incrementally whenever a new
+path is added to the Nix store. To make this efficient, Nix maintains
+a content-addressed index of all the files in the Nix store in the
+directory `/nix/store/.links/`.
+
+)""
diff --git a/src/nix/path-info.cc b/src/nix/path-info.cc
index 63cf885f9..30b6a50f8 100644
--- a/src/nix/path-info.cc
+++ b/src/nix/path-info.cc
@@ -29,38 +29,15 @@ struct CmdPathInfo : StorePathsCommand, MixJSON
return "query information about store paths";
}
- Category category() override { return catSecondary; }
-
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To show the closure sizes of every path in the current NixOS system closure, sorted by size:",
- "nix path-info -rS /run/current-system | sort -nk2"
- },
- Example{
- "To show a package's closure size and all its dependencies with human readable sizes:",
- "nix path-info -rsSh nixpkgs#rust"
- },
- Example{
- "To check the existence of a path in a binary cache:",
- "nix path-info -r /nix/store/7qvk5c91...-geeqie-1.1 --store https://cache.nixos.org/"
- },
- Example{
- "To print the 10 most recently added paths (using --json and the jq(1) command):",
- "nix path-info --json --all | jq -r 'sort_by(.registrationTime)[-11:-1][].path'"
- },
- Example{
- "To show the size of the entire Nix store:",
- "nix path-info --json --all | jq 'map(.narSize) | add'"
- },
- Example{
- "To show every path whose closure is bigger than 1 GB, sorted by closure size:",
- "nix path-info --json --all -S | jq 'map(select(.closureSize > 1e9)) | sort_by(.closureSize) | map([.path, .closureSize])'"
- },
- };
+ return
+ #include "path-info.md"
+ ;
}
+ Category category() override { return catSecondary; }
+
void printSize(uint64_t value)
{
if (!humanReadable) {
diff --git a/src/nix/path-info.md b/src/nix/path-info.md
new file mode 100644
index 000000000..76a83e39d
--- /dev/null
+++ b/src/nix/path-info.md
@@ -0,0 +1,94 @@
+R""(
+
+# Examples
+
+* Print the store path produced by `nixpkgs#hello`:
+
+ ```console
+ # nix path-info nixpkgs#hello
+ /nix/store/v5sv61sszx301i0x6xysaqzla09nksnd-hello-2.10
+ ```
+
+* Show the closure sizes of every path in the current NixOS system
+ closure, sorted by size:
+
+ ```console
+ # nix path-info -rS /run/current-system | sort -nk2
+ /nix/store/hl5xwp9kdrd1zkm0idm3kkby9q66z404-empty 96
+ /nix/store/27324qvqhnxj3rncazmxc4mwy79kz8ha-nameservers 112
+ …
+ /nix/store/539jkw9a8dyry7clcv60gk6na816j7y8-etc 5783255504
+ /nix/store/zqamz3cz4dbzfihki2mk7a63mbkxz9xq-nixos-system-machine-20.09.20201112.3090c65 5887562256
+ ```
+
+* Show a package's closure size and all its dependencies with human
+ readable sizes:
+
+ ```console
+ # nix path-info -rsSh nixpkgs#rustc
+ /nix/store/01rrgsg5zk3cds0xgdsq40zpk6g51dz9-ncurses-6.2-dev 386.7K 69.1M
+ /nix/store/0q783wnvixpqz6dxjp16nw296avgczam-libpfm-4.11.0 5.9M 37.4M
+ …
+ ```
+
+* Check the existence of a path in a binary cache:
+
+ ```console
+ # nix path-info -r /nix/store/blzxgyvrk32ki6xga10phr4sby2xf25q-geeqie-1.5.1 --store https://cache.nixos.org/
+ path '/nix/store/blzxgyvrk32ki6xga10phr4sby2xf25q-geeqie-1.5.1' is not valid
+
+ ```
+
+* Print the 10 most recently added paths (using --json and the jq(1)
+ command):
+
+ ```console
+ # nix path-info --json --all | jq -r 'sort_by(.registrationTime)[-11:-1][].path'
+ ```
+
+* Show the size of the entire Nix store:
+
+ ```console
+ # nix path-info --json --all | jq 'map(.narSize) | add'
+ 49812020936
+ ```
+
+* Show every path whose closure is bigger than 1 GB, sorted by closure
+ size:
+
+ ```console
+ # nix path-info --json --all -S \
+ | jq 'map(select(.closureSize > 1e9)) | sort_by(.closureSize) | map([.path, .closureSize])'
+ [
+ …,
+ [
+ "/nix/store/zqamz3cz4dbzfihki2mk7a63mbkxz9xq-nixos-system-machine-20.09.20201112.3090c65",
+ 5887562256
+ ]
+ ]
+ ```
+
+* Print the path of the store derivation produced by `nixpkgs#hello`:
+
+ ```console
+ # nix path-info --derivation nixpkgs#hello
+ /nix/store/s6rn4jz1sin56rf4qj5b5v8jxjm32hlk-hello-2.10.drv
+ ```
+
+# Description
+
+This command shows information about the store paths produced by
+*installables*, or about all paths in the store if you pass `--all`.
+
+By default, this command only prints the store paths. You can get
+additional information by passing flags such as `--closure-size`,
+--size`, `--sigs` or `--json`.
+
+> **Warning**
+>
+> Note that `nix path-info` does not build or substitute the
+> *installables* you specify. Thus, if the corresponding store paths
+> don't already exist, this command will fail. You can use `nix build`
+> to ensure that they exist.
+
+)""
diff --git a/src/nix/ping-store.cc b/src/nix/ping-store.cc
index 19b1a55c8..62b645b06 100644
--- a/src/nix/ping-store.cc
+++ b/src/nix/ping-store.cc
@@ -8,17 +8,14 @@ struct CmdPingStore : StoreCommand
{
std::string description() override
{
- return "test whether a store can be opened";
+ return "test whether a store can be accessed";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To test whether connecting to a remote Nix store via SSH works:",
- "nix store ping --store ssh://mac1"
- },
- };
+ return
+ #include "ping-store.md"
+ ;
}
void run(ref<Store> store) override
diff --git a/src/nix/ping-store.md b/src/nix/ping-store.md
new file mode 100644
index 000000000..322093091
--- /dev/null
+++ b/src/nix/ping-store.md
@@ -0,0 +1,30 @@
+R""(
+
+# Examples
+
+* Test whether connecting to a remote Nix store via SSH works:
+
+ ```console
+ # nix store ping --store ssh://mac1
+ ```
+
+* Test whether a URL is a valid binary cache:
+
+ ```console
+ # nix store ping --store https://cache.nixos.org
+ ```
+
+* Test whether the Nix daemon is up and running:
+
+ ```console
+ # nix store ping --store daemon
+ ```
+
+# Description
+
+This command tests whether a particular Nix store (specified by the
+argument `--store` *url*) can be accessed. What this means is
+dependent on the type of the store. For instance, for an SSH store it
+means that Nix can connect to the specified machine.
+
+)""
diff --git a/src/nix/print-dev-env.md b/src/nix/print-dev-env.md
new file mode 100644
index 000000000..b80252acf
--- /dev/null
+++ b/src/nix/print-dev-env.md
@@ -0,0 +1,19 @@
+R""(
+
+# Examples
+
+* Apply the build environment of GNU hello to the current shell:
+
+ ```console
+ # . <(nix print-dev-env nixpkgs#hello)
+ ```
+
+# Description
+
+This command prints a shell script that can be sourced by `b`ash and
+that sets the environment variables and shell functions defined by the
+build process of *installable*. This allows you to get a similar build
+environment in your current shell rather than in a subshell (as with
+`nix develop`).
+
+)""
diff --git a/src/nix/profile-diff-closures.md b/src/nix/profile-diff-closures.md
new file mode 100644
index 000000000..295d1252b
--- /dev/null
+++ b/src/nix/profile-diff-closures.md
@@ -0,0 +1,28 @@
+R""(
+
+# Examples
+
+* Show what changed between each version of the NixOS system
+ profile:
+
+ ```console
+ # nix profile diff-closures --profile /nix/var/nix/profiles/system
+ Version 13 -> 14:
+ acpi-call: 2020-04-07-5.8.13 → 2020-04-07-5.8.14
+ aws-sdk-cpp: -6723.1 KiB
+ …
+
+ Version 14 -> 15:
+ acpi-call: 2020-04-07-5.8.14 → 2020-04-07-5.8.16
+ attica: -996.2 KiB
+ breeze-icons: -78713.5 KiB
+ brotli: 1.0.7 → 1.0.9, +44.2 KiB
+ ```
+
+# Description
+
+This command shows the difference between the closures of subsequent
+versions of a profile. See [`nix store
+diff-closures`](nix3-store-diff-closures.md) for details.
+
+)""
diff --git a/src/nix/profile-info.md b/src/nix/profile-info.md
new file mode 100644
index 000000000..a0c04fc8c
--- /dev/null
+++ b/src/nix/profile-info.md
@@ -0,0 +1,31 @@
+R""(
+
+# Examples
+
+* Show what packages are installed in the default profile:
+
+ ```console
+ # nix profile info
+ 0 flake:nixpkgs#legacyPackages.x86_64-linux.spotify github:NixOS/nixpkgs/c23db78bbd474c4d0c5c3c551877523b4a50db06#legacyPackages.x86_64-linux.spotify /nix/store/akpdsid105phbbvknjsdh7hl4v3fhjkr-spotify-1.1.46.916.g416cacf1
+ 1 flake:nixpkgs#legacyPackages.x86_64-linux.zoom-us github:NixOS/nixpkgs/c23db78bbd474c4d0c5c3c551877523b4a50db06#legacyPackages.x86_64-linux.zoom-us /nix/store/89pmjmbih5qpi7accgacd17ybpgp4xfm-zoom-us-5.4.53350.1027
+ 2 flake:blender-bin#defaultPackage.x86_64-linux github:edolstra/nix-warez/d09d7eea893dcb162e89bc67f6dc1ced14abfc27?dir=blender#defaultPackage.x86_64-linux /nix/store/zfgralhqjnam662kqsgq6isjw8lhrflz-blender-bin-2.91.0
+ ```
+
+# Description
+
+This command shows what packages are currently installed in a
+profile. The output consists of one line per package, with the
+following fields:
+
+* An integer that can be used to unambiguously identify the package in
+ invocations of `nix profile remove` and `nix profile upgrade`.
+
+* The original ("mutable") flake reference and output attribute path
+ used at installation time.
+
+* The immutable flake reference to which the mutable flake reference
+ was resolved.
+
+* The store path(s) of the package.
+
+)""
diff --git a/src/nix/profile-install.md b/src/nix/profile-install.md
new file mode 100644
index 000000000..e3009491e
--- /dev/null
+++ b/src/nix/profile-install.md
@@ -0,0 +1,27 @@
+R""(
+
+# Examples
+
+* Install a package from Nixpkgs:
+
+ ```console
+ # nix profile install nixpkgs#hello
+ ```
+
+* Install a package from a specific branch of Nixpkgs:
+
+ ```console
+ # nix profile install nixpkgs/release-20.09#hello
+ ```
+
+* Install a package from a specific revision of Nixpkgs:
+
+ ```console
+ # nix profile install nixpkgs/d73407e8e6002646acfdef0e39ace088bacc83da#hello
+ ```
+
+# Description
+
+This command adds *installables* to a Nix profile.
+
+)""
diff --git a/src/nix/profile-remove.md b/src/nix/profile-remove.md
new file mode 100644
index 000000000..dcf825da9
--- /dev/null
+++ b/src/nix/profile-remove.md
@@ -0,0 +1,32 @@
+R""(
+
+# Examples
+
+* Remove a package by position:
+
+ ```console
+ # nix profile remove 3
+ ```
+
+* Remove a package by attribute path:
+
+ ```console
+ # nix profile remove packages.x86_64-linux.hello
+ ```
+
+* Remove all packages:
+ ```console
+ # nix profile remove '.*'
+ ```
+
+* Remove a package by store path:
+
+ ```console
+ # nix profile remove /nix/store/rr3y0c6zyk7kjjl8y19s4lsrhn4aiq1z-hello-2.10
+ ```
+
+# Description
+
+This command removes a package from a profile.
+
+)""
diff --git a/src/nix/profile-upgrade.md b/src/nix/profile-upgrade.md
new file mode 100644
index 000000000..2bd5d256d
--- /dev/null
+++ b/src/nix/profile-upgrade.md
@@ -0,0 +1,41 @@
+R""(
+
+# Examples
+
+* Upgrade all packages that were installed using a mutable flake
+ reference:
+
+ ```console
+ # nix profile upgrade '.*'
+ ```
+
+* Upgrade a specific package:
+
+ ```console
+ # nix profile upgrade packages.x86_64-linux.hello
+ ```
+
+* Upgrade a specific profile element by number:
+
+ ```console
+ # nix profile info
+ 0 flake:nixpkgs#legacyPackages.x86_64-linux.spotify …
+
+ # nix profile upgrade 0
+ ```
+
+# Description
+
+This command upgrades a previously installed package in a Nix profile,
+by fetching and evaluating the latest version of the flake from which
+the package was installed.
+
+> **Warning**
+>
+> This only works if you used a *mutable* flake reference at
+> installation time, e.g. `nixpkgs#hello`. It does not work if you
+> used an *immutable* flake reference
+> (e.g. `github:NixOS/nixpkgs/13d0c311e3ae923a00f734b43fd1d35b47d8943a#hello`),
+> since in that case the "latest version" is always the same.
+
+)""
diff --git a/src/nix/profile.cc b/src/nix/profile.cc
index 8cf5ccd62..d8d2b3a70 100644
--- a/src/nix/profile.cc
+++ b/src/nix/profile.cc
@@ -151,22 +151,11 @@ struct CmdProfileInstall : InstallablesCommand, MixDefaultProfile
return "install a package into a profile";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To install a package from Nixpkgs:",
- "nix profile install nixpkgs#hello"
- },
- Example{
- "To install a package from a specific branch of Nixpkgs:",
- "nix profile install nixpkgs/release-19.09#hello"
- },
- Example{
- "To install a package from a specific revision of Nixpkgs:",
- "nix profile install nixpkgs/1028bb33859f8dfad7f98e1c8d185f3d1aaa7340#hello"
- },
- };
+ return
+ #include "profile-install.md"
+ ;
}
void run(ref<Store> store) override
@@ -257,26 +246,11 @@ struct CmdProfileRemove : virtual EvalCommand, MixDefaultProfile, MixProfileElem
return "remove packages from a profile";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To remove a package by attribute path:",
- "nix profile remove packages.x86_64-linux.hello"
- },
- Example{
- "To remove all packages:",
- "nix profile remove '.*'"
- },
- Example{
- "To remove a package by store path:",
- "nix profile remove /nix/store/rr3y0c6zyk7kjjl8y19s4lsrhn4aiq1z-hello-2.10"
- },
- Example{
- "To remove a package by position:",
- "nix profile remove 3"
- },
- };
+ return
+ #include "profile-remove.md"
+ ;
}
void run(ref<Store> store) override
@@ -310,18 +284,11 @@ struct CmdProfileUpgrade : virtual SourceExprCommand, MixDefaultProfile, MixProf
return "upgrade packages using their most recent flake";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To upgrade all packages that were installed using a mutable flake reference:",
- "nix profile upgrade '.*'"
- },
- Example{
- "To upgrade a specific package:",
- "nix profile upgrade packages.x86_64-linux.hello"
- },
- };
+ return
+ #include "profile-upgrade.md"
+ ;
}
void run(ref<Store> store) override
@@ -377,14 +344,11 @@ struct CmdProfileInfo : virtual EvalCommand, virtual StoreCommand, MixDefaultPro
return "list installed packages";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To show what packages are installed in the default profile:",
- "nix profile info"
- },
- };
+ return
+ #include "profile-info.md"
+ ;
}
void run(ref<Store> store) override
@@ -405,17 +369,14 @@ struct CmdProfileDiffClosures : virtual StoreCommand, MixDefaultProfile
{
std::string description() override
{
- return "show the closure difference between each generation of a profile";
+ return "show the closure difference between each version of a profile";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To show what changed between each generation of the NixOS system profile:",
- "nix profile diff-closures --profile /nix/var/nix/profiles/system"
- },
- };
+ return
+ #include "profile-diff-closures.md"
+ ;
}
void run(ref<Store> store) override
@@ -429,7 +390,7 @@ struct CmdProfileDiffClosures : virtual StoreCommand, MixDefaultProfile
if (prevGen) {
if (!first) std::cout << "\n";
first = false;
- std::cout << fmt("Generation %d -> %d:\n", prevGen->number, gen.number);
+ std::cout << fmt("Version %d -> %d:\n", prevGen->number, gen.number);
printClosureDiff(store,
store->followLinksToStorePath(prevGen->path),
store->followLinksToStorePath(gen.path),
@@ -458,6 +419,13 @@ struct CmdProfile : NixMultiCommand
return "manage Nix profiles";
}
+ std::string doc() override
+ {
+ return
+ #include "profile.md"
+ ;
+ }
+
void run() override
{
if (!command)
diff --git a/src/nix/profile.md b/src/nix/profile.md
new file mode 100644
index 000000000..d3ddcd3d1
--- /dev/null
+++ b/src/nix/profile.md
@@ -0,0 +1,107 @@
+R""(
+
+# Description
+
+`nix profile` allows you to create and manage *Nix profiles*. A Nix
+profile is a set of packages that can be installed and upgraded
+independently from each other. Nix profiles are versioned, allowing
+them to be rolled back easily.
+
+# Default profile
+
+The default profile used by `nix profile` is `$HOME/.nix-profile`,
+which, if it does not exist, is created as a symlink to
+`/nix/var/nix/profiles/per-user/default` if Nix is invoked by the
+`root` user, or `/nix/var/nix/profiles/per-user/`*username* otherwise.
+
+You can specify another profile location using `--profile` *path*.
+
+# Filesystem layout
+
+Profiles are versioned as follows. When using profile *path*, *path*
+is a symlink to *path*`-`*N*, where *N* is the current *version* of
+the profile. In turn, *path*`-`*N* is a symlink to a path in the Nix
+store. For example:
+
+```console
+$ ls -l /nix/var/nix/profiles/per-user/alice/profile*
+lrwxrwxrwx 1 alice users 14 Nov 25 14:35 /nix/var/nix/profiles/per-user/alice/profile -> profile-7-link
+lrwxrwxrwx 1 alice users 51 Oct 28 16:18 /nix/var/nix/profiles/per-user/alice/profile-5-link -> /nix/store/q69xad13ghpf7ir87h0b2gd28lafjj1j-profile
+lrwxrwxrwx 1 alice users 51 Oct 29 13:20 /nix/var/nix/profiles/per-user/alice/profile-6-link -> /nix/store/6bvhpysd7vwz7k3b0pndn7ifi5xr32dg-profile
+lrwxrwxrwx 1 alice users 51 Nov 25 14:35 /nix/var/nix/profiles/per-user/alice/profile-7-link -> /nix/store/mp0x6xnsg0b8qhswy6riqvimai4gm677-profile
+```
+
+Each of these symlinks is a root for the Nix garbage collector.
+
+The contents of the store path corresponding to each version of the
+profile is a tree of symlinks to the files of the installed packages,
+e.g.
+
+```console
+$ ll -R /nix/var/nix/profiles/per-user/eelco/profile-7-link/
+/nix/var/nix/profiles/per-user/eelco/profile-7-link/:
+total 20
+dr-xr-xr-x 2 root root 4096 Jan 1 1970 bin
+-r--r--r-- 2 root root 1402 Jan 1 1970 manifest.json
+dr-xr-xr-x 4 root root 4096 Jan 1 1970 share
+
+/nix/var/nix/profiles/per-user/eelco/profile-7-link/bin:
+total 20
+lrwxrwxrwx 5 root root 79 Jan 1 1970 chromium -> /nix/store/ijm5k0zqisvkdwjkc77mb9qzb35xfi4m-chromium-86.0.4240.111/bin/chromium
+lrwxrwxrwx 7 root root 87 Jan 1 1970 spotify -> /nix/store/w9182874m1bl56smps3m5zjj36jhp3rn-spotify-1.1.26.501.gbe11e53b-15/bin/spotify
+lrwxrwxrwx 3 root root 79 Jan 1 1970 zoom-us -> /nix/store/wbhg2ga8f3h87s9h5k0slxk0m81m4cxl-zoom-us-5.3.469451.0927/bin/zoom-us
+
+/nix/var/nix/profiles/per-user/eelco/profile-7-link/share/applications:
+total 12
+lrwxrwxrwx 4 root root 120 Jan 1 1970 chromium-browser.desktop -> /nix/store/4cf803y4vzfm3gyk3vzhzb2327v0kl8a-chromium-unwrapped-86.0.4240.111/share/applications/chromium-browser.desktop
+lrwxrwxrwx 7 root root 110 Jan 1 1970 spotify.desktop -> /nix/store/w9182874m1bl56smps3m5zjj36jhp3rn-spotify-1.1.26.501.gbe11e53b-15/share/applications/spotify.desktop
+lrwxrwxrwx 3 root root 107 Jan 1 1970 us.zoom.Zoom.desktop -> /nix/store/wbhg2ga8f3h87s9h5k0slxk0m81m4cxl-zoom-us-5.3.469451.0927/share/applications/us.zoom.Zoom.desktop
+
+…
+```
+
+The file `manifest.json` records the provenance of the packages that
+are installed in this version of the profile. It looks like this:
+
+```json
+{
+ "version": 1,
+ "elements": [
+ {
+ "active": true,
+ "attrPath": "legacyPackages.x86_64-linux.zoom-us",
+ "originalUri": "flake:nixpkgs",
+ "storePaths": [
+ "/nix/store/wbhg2ga8f3h87s9h5k0slxk0m81m4cxl-zoom-us-5.3.469451.0927"
+ ],
+ "uri": "github:NixOS/nixpkgs/13d0c311e3ae923a00f734b43fd1d35b47d8943a"
+ },
+ …
+ ]
+}
+```
+
+Each object in the array `elements` denotes an installed package and
+has the following fields:
+
+* `originalUri`: The [flake reference](./nix3-flake.md) specified by
+ the user at the time of installation (e.g. `nixpkgs`). This is also
+ the flake reference that will be used by `nix profile upgrade`.
+
+* `uri`: The immutable flake reference to which `originalUri`
+ resolved.
+
+* `attrPath`: The flake output attribute that provided this
+ package. Note that this is not necessarily the attribute that the
+ user specified, but the one resulting from applying the default
+ attribute paths and prefixes; for instance, `hello` might resolve to
+ `packages.x86_64-linux.hello` and the empty string to
+ `defaultPackage.x86_64-linux`.
+
+* `storePath`: The paths in the Nix store containing the package.
+
+* `active`: Whether the profile contains symlinks to the files of this
+ package. If set to false, the package is kept in the Nix store, but
+ is not "visible" in the profile's symlink tree.
+
+)""
diff --git a/src/nix/registry-add.md b/src/nix/registry-add.md
new file mode 100644
index 000000000..80a31996a
--- /dev/null
+++ b/src/nix/registry-add.md
@@ -0,0 +1,33 @@
+R""(
+
+# Examples
+
+* Set the `nixpkgs` flake identifier to a specific branch of Nixpkgs:
+
+ ```console
+ # nix registry add nixpkgs github:NixOS/nixpkgs/nixos-20.03
+ ```
+
+* Pin `nixpkgs` to a specific revision:
+
+ ```console
+ # nix registry add nixpkgs github:NixOS/nixpkgs/925b70cd964ceaedee26fde9b19cc4c4f081196a
+ ```
+
+* Add an entry that redirects a specific branch of `nixpkgs` to
+ another fork:
+
+ ```console
+ # nix registry add nixpkgs/nixos-20.03 ~/Dev/nixpkgs
+ ```
+
+# Description
+
+This command adds an entry to the user registry that maps flake
+reference *from-url* to flake reference *to-url*. If an entry for
+*from-url* already exists, it is overwritten.
+
+Entries can be removed using [`nix registry
+remove`](./nix3-registry-remove.md).
+
+)""
diff --git a/src/nix/registry-list.md b/src/nix/registry-list.md
new file mode 100644
index 000000000..30b6e29d8
--- /dev/null
+++ b/src/nix/registry-list.md
@@ -0,0 +1,29 @@
+R""(
+
+# Examples
+
+* Show the contents of all registries:
+
+ ```console
+ # nix registry list
+ user flake:dwarffs github:edolstra/dwarffs/d181d714fd36eb06f4992a1997cd5601e26db8f5
+ system flake:nixpkgs path:/nix/store/fxl9mrm5xvzam0lxi9ygdmksskx4qq8s-source?lastModified=1605220118&narHash=sha256-Und10ixH1WuW0XHYMxxuHRohKYb45R%2fT8CwZuLd2D2Q=&rev=3090c65041104931adda7625d37fa874b2b5c124
+ global flake:blender-bin github:edolstra/nix-warez?dir=blender
+ global flake:dwarffs github:edolstra/dwarffs
+ …
+ ```
+
+# Description
+
+This command displays the contents of all registries on standard
+output. Each line represents one registry entry in the format *type*
+*from* *to*, where *type* denotes the registry containing the entry:
+
+* `flags`: entries specified on the command line using `--override-flake`.
+* `user`: the user registry.
+* `system`: the system registry.
+* `global`: the global registry.
+
+See the [`nix registry` manual page](./nix3-registry.md) for more details.
+
+)""
diff --git a/src/nix/registry-pin.md b/src/nix/registry-pin.md
new file mode 100644
index 000000000..6e97e003e
--- /dev/null
+++ b/src/nix/registry-pin.md
@@ -0,0 +1,38 @@
+R""(
+
+# Examples
+
+* Pin `nixpkgs` to its most recent Git revision:
+
+ ```console
+ # nix registry pin nixpkgs
+ ```
+
+ Afterwards the user registry will have an entry like this:
+
+ ```console
+ nix registry list | grep '^user '
+ user flake:nixpkgs github:NixOS/nixpkgs/925b70cd964ceaedee26fde9b19cc4c4f081196a
+ ```
+
+ and `nix flake info` will say:
+
+ ```console
+ # nix flake info nixpkgs
+ Resolved URL: github:NixOS/nixpkgs/925b70cd964ceaedee26fde9b19cc4c4f081196a
+ Locked URL: github:NixOS/nixpkgs/925b70cd964ceaedee26fde9b19cc4c4f081196a
+ …
+ ```
+
+# Description
+
+This command adds an entry to the user registry that maps flake
+reference *url* to the corresponding *locked* flake reference, that
+is, a flake reference that specifies an exact revision or content
+hash. This ensures that until this registry entry is removed, all uses
+of *url* will resolve to exactly the same flake.
+
+Entries can be removed using [`nix registry
+remove`](./nix3-registry-remove.md).
+
+)""
diff --git a/src/nix/registry-remove.md b/src/nix/registry-remove.md
new file mode 100644
index 000000000..4c0eb4947
--- /dev/null
+++ b/src/nix/registry-remove.md
@@ -0,0 +1,16 @@
+R""(
+
+# Examples
+
+* Remove the entry `nixpkgs` from the user registry:
+
+ ```console
+ # nix registry remove nixpkgs
+ ```
+
+# Description
+
+This command removes from the user registry any entry for flake
+reference *url*.
+
+)""
diff --git a/src/nix/registry.cc b/src/nix/registry.cc
index 9352e00a7..f9719600f 100644
--- a/src/nix/registry.cc
+++ b/src/nix/registry.cc
@@ -17,6 +17,13 @@ struct CmdRegistryList : StoreCommand
return "list available Nix flakes";
}
+ std::string doc() override
+ {
+ return
+ #include "registry-list.md"
+ ;
+ }
+
void run(nix::ref<nix::Store> store) override
{
using namespace fetchers;
@@ -47,6 +54,13 @@ struct CmdRegistryAdd : MixEvalArgs, Command
return "add/replace flake in user flake registry";
}
+ std::string doc() override
+ {
+ return
+ #include "registry-add.md"
+ ;
+ }
+
CmdRegistryAdd()
{
expectArg("from-url", &fromUrl);
@@ -75,6 +89,13 @@ struct CmdRegistryRemove : virtual Args, MixEvalArgs, Command
return "remove flake from user flake registry";
}
+ std::string doc() override
+ {
+ return
+ #include "registry-remove.md"
+ ;
+ }
+
CmdRegistryRemove()
{
expectArg("url", &url);
@@ -97,6 +118,13 @@ struct CmdRegistryPin : virtual Args, EvalCommand
return "pin a flake to its current version in user flake registry";
}
+ std::string doc() override
+ {
+ return
+ #include "registry-pin.md"
+ ;
+ }
+
CmdRegistryPin()
{
expectArg("url", &url);
@@ -132,6 +160,13 @@ struct CmdRegistry : virtual NixMultiCommand
return "manage the flake registry";
}
+ std::string doc() override
+ {
+ return
+ #include "registry.md"
+ ;
+ }
+
Category category() override { return catSecondary; }
void run() override
diff --git a/src/nix/registry.md b/src/nix/registry.md
new file mode 100644
index 000000000..557e5795b
--- /dev/null
+++ b/src/nix/registry.md
@@ -0,0 +1,98 @@
+R""(
+
+# Description
+
+`nix flake` provides subcommands for managing *flake
+registries*. Flake registries are a convenience feature that allows
+you to refer to flakes using symbolic identifiers such as `nixpkgs`,
+rather than full URLs such as `git://github.com/NixOS/nixpkgs`. You
+can use these identifiers on the command line (e.g. when you do `nix
+run nixpkgs#hello`) or in flake input specifications in `flake.nix`
+files. The latter are automatically resolved to full URLs and recorded
+in the flake's `flake.lock` file.
+
+In addition, the flake registry allows you to redirect arbitrary flake
+references (e.g. `github:NixOS/patchelf`) to another location, such as
+a local fork.
+
+There are multiple registries. These are, in order from lowest to
+highest precedence:
+
+* The global registry, which is a file downloaded from the URL
+ specified by the setting `flake-registry`. It is cached locally and
+ updated automatically when it's older than `tarball-ttl`
+ seconds. The default global registry is kept in [a GitHub
+ repository](https://github.com/NixOS/flake-registry).
+
+* The system registry, which is shared by all users. The default
+ location is `/etc/nix/registry.json`. On NixOS, the system registry
+ can be specified using the NixOS option `nix.registry`.
+
+* The user registry `~/.config/nix/registry.json`. This registry can
+ be modified by commands such as `nix flake pin`.
+
+* Overrides specified on the command line using the option
+ `--override-flake`.
+
+# Registry format
+
+A registry is a JSON file with the following format:
+
+```json
+{
+ "version": 2,
+ [
+ {
+ "from": {
+ "type": "indirect",
+ "id": "nixpkgs"
+ },
+ "to": {
+ "type": "github",
+ "owner": "NixOS",
+ "repo": "nixpkgs"
+ }
+ },
+ ...
+ ]
+}
+```
+
+That is, it contains a list of objects with attributes `from` and
+`to`, both of which contain a flake reference in attribute
+representation. (For example, `{"type": "indirect", "id": "nixpkgs"}`
+is the attribute representation of `nixpkgs`, while `{"type":
+"github", "owner": "NixOS", "repo": "nixpkgs"}` is the attribute
+representation of `github:NixOS/nixpkgs`.)
+
+Given some flake reference *R*, a registry entry is used if its
+`from` flake reference *matches* *R*. *R* is then replaced by the
+*unification* of the `to` flake reference with *R*.
+
+# Matching
+
+The `from` flake reference in a registry entry *matches* some flake
+reference *R* if the attributes in `from` are the same as the
+attributes in `R`. For example:
+
+* `nixpkgs` matches with `nixpkgs`.
+
+* `nixpkgs` matches with `nixpkgs/nixos-20.09`.
+
+* `nixpkgs/nixos-20.09` does not match with `nixpkgs`.
+
+* `nixpkgs` does not match with `git://github.com/NixOS/patchelf`.
+
+# Unification
+
+The `to` flake reference in a registry entry is *unified* with some flake
+reference *R* by taking `to` and applying the `rev` and `ref`
+attributes from *R*, if specified. For example:
+
+* `github:NixOS/nixpkgs` unified with `nixpkgs` produces `github:NixOS/nixpkgs`.
+
+* `github:NixOS/nixpkgs` unified with `nixpkgs/nixos-20.09` produces `github:NixOS/nixpkgs/nixos-20.09`.
+
+* `github:NixOS/nixpkgs/master` unified with `nixpkgs/nixos-20.09` produces `github:NixOS/nixpkgs/nixos-20.09`.
+
+)""
diff --git a/src/nix/repl.cc b/src/nix/repl.cc
index a992d8732..bce8d31dc 100644
--- a/src/nix/repl.cc
+++ b/src/nix/repl.cc
@@ -405,6 +405,7 @@ bool NixRepl::processLine(string line)
}
if (command == ":?" || command == ":help") {
+ // FIXME: convert to Markdown, include in the 'nix repl' manpage.
std::cout
<< "The following commands are available:\n"
<< "\n"
@@ -801,14 +802,11 @@ struct CmdRepl : StoreCommand, MixEvalArgs
return "start an interactive environment for evaluating Nix expressions";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "Display all special commands within the REPL:",
- "nix repl\nnix-repl> :?"
- }
- };
+ return
+ #include "repl.md"
+ ;
}
void run(ref<Store> store) override
diff --git a/src/nix/repl.md b/src/nix/repl.md
new file mode 100644
index 000000000..bba60f871
--- /dev/null
+++ b/src/nix/repl.md
@@ -0,0 +1,57 @@
+R""(
+
+# Examples
+
+* Display all special commands within the REPL:
+
+ ```console
+ # nix repl
+ nix-repl> :?
+ ```
+
+* Evaluate some simple Nix expressions:
+
+ ```console
+ # nix repl
+
+ nix-repl> 1 + 2
+ 3
+
+ nix-repl> map (x: x * 2) [1 2 3]
+ [ 2 4 6 ]
+ ```
+
+* Interact with Nixpkgs in the REPL:
+
+ ```console
+ # nix repl '<nixpkgs>'
+
+ Loading '<nixpkgs>'...
+ Added 12428 variables.
+
+ nix-repl> emacs.name
+ "emacs-27.1"
+
+ nix-repl> emacs.drvPath
+ "/nix/store/lp0sjrhgg03y2n0l10n70rg0k7hhyz0l-emacs-27.1.drv"
+
+ nix-repl> drv = runCommand "hello" { buildInputs = [ hello ]; } "hello > $out"
+
+ nix-repl> :b x
+ this derivation produced the following outputs:
+ out -> /nix/store/0njwbgwmkwls0w5dv9mpc1pq5fj39q0l-hello
+
+ nix-repl> builtins.readFile drv
+ "Hello, world!\n"
+ ```
+
+# Description
+
+This command provides an interactive environment for evaluating Nix
+expressions. (REPL stands for 'read–eval–print loop'.)
+
+On startup, it loads the Nix expressions named *files* and adds them
+into the lexical scope. You can load addition files using the `:l
+<filename>` command, or reload all files using `:r`.
+
+)""
diff --git a/src/nix/run.cc b/src/nix/run.cc
index ec61fc79a..1340dd46f 100644
--- a/src/nix/run.cc
+++ b/src/nix/run.cc
@@ -86,26 +86,11 @@ struct CmdShell : InstallablesCommand, RunCommon, MixEnvironment
return "run a shell in which the specified packages are available";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To start a shell providing GNU Hello from NixOS 20.03:",
- "nix shell nixpkgs/nixos-20.03#hello"
- },
- Example{
- "To start a shell providing youtube-dl from your 'nixpkgs' channel:",
- "nix shell nixpkgs#youtube-dl"
- },
- Example{
- "To run GNU Hello:",
- "nix shell nixpkgs#hello -c hello --greeting 'Hi everybody!'"
- },
- Example{
- "To run GNU Hello in a chroot store:",
- "nix shell --store ~/my-nix nixpkgs#hello -c hello"
- },
- };
+ return
+ #include "shell.md"
+ ;
}
void run(ref<Store> store) override
@@ -168,22 +153,11 @@ struct CmdRun : InstallableCommand, RunCommon
return "run a Nix application";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To run Blender:",
- "nix run blender-bin"
- },
- Example{
- "To run vim from nixpkgs:",
- "nix run nixpkgs#vim"
- },
- Example{
- "To run vim from nixpkgs with arguments:",
- "nix run nixpkgs#vim -- --help"
- },
- };
+ return
+ #include "run.md"
+ ;
}
Strings getDefaultFlakeAttrPaths() override
diff --git a/src/nix/run.md b/src/nix/run.md
new file mode 100644
index 000000000..c178e8b13
--- /dev/null
+++ b/src/nix/run.md
@@ -0,0 +1,87 @@
+R""(
+
+# Examples
+
+* Run the default app from the `blender-bin` flake:
+
+ ```console
+ # nix run blender-bin
+ ```
+
+* Run a non-default app from the `blender-bin` flake:
+
+ ```console
+ # nix run blender-bin#blender_2_83
+ ```
+
+ Tip: you can find apps provided by this flake by running `nix flake
+ show blender-bin`.
+
+* Run `vim` from the `nixpkgs` flake:
+
+ ```console
+ # nix run nixpkgs#vim
+ ```
+
+ Note that `vim` (as of the time of writing of this page) is not an
+ app but a package. Thus, Nix runs the eponymous file from the `vim`
+ package.
+
+* Run `vim` with arguments:
+
+ ```console
+ # nix run nixpkgs#vim -- --help
+ ```
+
+# Description
+
+`nix run` builds and runs *installable*, which must evaluate to an
+*app* or a regular Nix derivation.
+
+If *installable* evaluates to an *app* (see below), it executes the
+program specified by the app definition.
+
+If *installable* evaluates to a derivation, it will try to execute the
+program `<out>/bin/<name>`, where *out* is the primary output store
+path of the derivation and *name* is the name part of the value of the
+`name` attribute of the derivation (e.g. if `name` is set to
+`hello-1.10`, it will run `$out/bin/hello`).
+
+# Flake output attributes
+
+If no flake output attribute is given, `nix run` tries the following
+flake output attributes:
+
+* `defaultApp.<system>`
+
+* `defaultPackage.<system>`
+
+If an attribute *name* is given, `nix run` tries the following flake
+output attributes:
+
+* `apps.<system>.<name>`
+
+* `packages.<system>.<name>`
+
+* `legacyPackages.<system>.<name>`
+
+# Apps
+
+An app is specified by a flake output attribute named
+`apps.<system>.<name>` or `defaultApp.<system>`. It looks like this:
+
+```nix
+apps.x86_64-linux.blender_2_79 = {
+ type = "app";
+ program = "${self.packages.x86_64-linux.blender_2_79}/bin/blender";
+};
+```
+
+The only supported attributes are:
+
+* `type` (required): Must be set to `app`.
+
+* `program` (required): The full path of the executable to run. It
+ must reside in the Nix store.
+
+)""
diff --git a/src/nix/search.cc b/src/nix/search.cc
index 47770e128..9f864b3a4 100644
--- a/src/nix/search.cc
+++ b/src/nix/search.cc
@@ -41,29 +41,14 @@ struct CmdSearch : InstallableCommand, MixJSON
std::string description() override
{
- return "query available packages";
+ return "search for packages";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To show all packages in the flake in the current directory:",
- "nix search"
- },
- Example{
- "To show packages in the 'nixpkgs' flake containing 'blender' in its name or description:",
- "nix search nixpkgs blender"
- },
- Example{
- "To search for Firefox or Chromium:",
- "nix search nixpkgs 'firefox|chromium'"
- },
- Example{
- "To search for packages containing 'git' and either 'frontend' or 'gui':",
- "nix search nixpkgs git 'frontend|gui'"
- }
- };
+ return
+ #include "search.md"
+ ;
}
Strings getDefaultFlakeAttrPaths() override
diff --git a/src/nix/search.md b/src/nix/search.md
new file mode 100644
index 000000000..d182788a6
--- /dev/null
+++ b/src/nix/search.md
@@ -0,0 +1,72 @@
+R""(
+
+# Examples
+
+* Show all packages in the `nixpkgs` flake:
+
+ ```console
+ # nix search nixpkgs
+ * legacyPackages.x86_64-linux.AMB-plugins (0.8.1)
+ A set of ambisonics ladspa plugins
+
+ * legacyPackages.x86_64-linux.ArchiSteamFarm (4.3.1.0)
+ Application with primary purpose of idling Steam cards from multiple accounts simultaneously
+ …
+ ```
+
+* Show packages in the `nixpkgs` flake containing `blender` in its
+ name or description:
+
+ ```console
+ # nix search nixpkgs blender
+ * legacyPackages.x86_64-linux.blender (2.91.0)
+ 3D Creation/Animation/Publishing System
+ ```
+
+* Search for packages underneath the attribute `gnome3` in Nixpkgs:
+
+ ```console
+ # nix search nixpkgs#gnome3 vala
+ * legacyPackages.x86_64-linux.gnome3.vala (0.48.9)
+ Compiler for GObject type system
+ ```
+
+* Show all packages in the flake in the current directory:
+
+ ```console
+ # nix search
+ ```
+
+* Search for Firefox or Chromium:
+
+ ```console
+ # nix search nixpkgs 'firefox|chromium'
+ ```
+
+* Search for packages containing `git'`and either `frontend` or `gui`:
+
+ ```console
+ # nix search nixpkgs git 'frontend|gui'
+ ```
+
+# Description
+
+`nix search` searches *installable* (which must be evaluatable, e.g. a
+flake) for packages whose name or description matches all of the
+regular expressions *regex*. For each matching package, It prints the
+full attribute name (from the root of the installable), the version
+and the `meta.description` field, highlighting the substrings that
+were matched by the regular expressions. If no regular expressions are
+specified, all packages are shown.
+
+# Flake output attributes
+
+If no flake output attribute is given, `nix search` searches for
+packages:
+
+* Directly underneath `packages.<system>`.
+
+* Underneath `legacyPackages.<system>`, recursing into attribute sets
+ that contain an attribute `recurseForDerivations = true`.
+
+)""
diff --git a/src/nix/shell.md b/src/nix/shell.md
new file mode 100644
index 000000000..2a379e03f
--- /dev/null
+++ b/src/nix/shell.md
@@ -0,0 +1,48 @@
+R""(
+
+# Examples
+
+* Start a shell providing `youtube-dl` from the `nixpkgs` flake:
+
+ ```console
+ # nix shell nixpkgs#youtube-dl
+ # youtube-dl --version
+ 2020.11.01.1
+ ```
+
+* Start a shell providing GNU Hello from NixOS 20.03:
+
+ ```console
+ # nix shell nixpkgs/nixos-20.03#hello
+ ```
+
+* Run GNU Hello:
+
+ ```console
+ # nix shell nixpkgs#hello -c hello --greeting 'Hi everybody!'
+ Hi everybody!
+ ```
+
+* Run GNU Hello in a chroot store:
+
+ ```console
+ # nix shell --store ~/my-nix nixpkgs#hello -c hello
+ ```
+
+* Start a shell providing GNU Hello in a chroot store:
+
+ ```console
+ # nix shell --store ~/my-nix nixpkgs#hello nixpkgs#bashInteractive -c bash
+ ```
+
+ Note that it's necessary to specify `bash` explicitly because your
+ default shell (e.g. `/bin/bash`) generally will not exist in the
+ chroot.
+
+# Description
+
+`nix shell` runs a command in an environment in which the `$PATH`
+variable provides the specified *installables*. If not command is
+specified, it starts the default shell of your user account.
+
+)""
diff --git a/src/nix/show-derivation.cc b/src/nix/show-derivation.cc
index 8e1a58ac2..13f2c8e69 100644
--- a/src/nix/show-derivation.cc
+++ b/src/nix/show-derivation.cc
@@ -29,18 +29,11 @@ struct CmdShowDerivation : InstallablesCommand
return "show the contents of a store derivation";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To show the store derivation that results from evaluating the Hello package:",
- "nix show-derivation nixpkgs#hello"
- },
- Example{
- "To show the full derivation graph (if available) that produced your NixOS system:",
- "nix show-derivation -r /run/current-system"
- },
- };
+ return
+ #include "show-derivation.md"
+ ;
}
Category category() override { return catUtility; }
@@ -103,7 +96,7 @@ struct CmdShowDerivation : InstallablesCommand
}
}
- drvObj.attr("platform", drv.platform);
+ drvObj.attr("system", drv.platform);
drvObj.attr("builder", drv.builder);
{
diff --git a/src/nix/show-derivation.md b/src/nix/show-derivation.md
new file mode 100644
index 000000000..aa863899c
--- /dev/null
+++ b/src/nix/show-derivation.md
@@ -0,0 +1,103 @@
+R""(
+
+# Examples
+
+* Show the store derivation that results from evaluating the Hello
+ package:
+
+ ```console
+ # nix show-derivation nixpkgs#hello
+ {
+ "/nix/store/s6rn4jz1sin56rf4qj5b5v8jxjm32hlk-hello-2.10.drv": {
+ …
+ }
+ }
+ ```
+
+* Show the full derivation graph (if available) that produced your
+ NixOS system:
+
+ ```console
+ # nix show-derivation -r /run/current-system
+ ```
+
+* Print all files fetched using `fetchurl` by Firefox's dependency
+ graph:
+
+ ```console
+ # nix show-derivation -r nixpkgs#firefox \
+ | jq -r '.[] | select(.outputs.out.hash and .env.urls) | .env.urls' \
+ | uniq | sort
+ ```
+
+ Note that `.outputs.out.hash` selects *fixed-output derivations*
+ (derivations that produce output with a specified content hash),
+ while `.env.urls` selects derivations with a `urls` attribute.
+
+# Description
+
+This command prints on standard output a JSON representation of the
+store derivations to which *installables* evaluate. Store derivations
+are used internally by Nix. They are store paths with extension `.drv`
+that represent the build-time dependency graph to which a Nix
+expression evaluates.
+
+By default, this command only shows top-level derivations, but with
+`--recursive`, it also shows their dependencies.
+
+The JSON output is a JSON object whose keys are the store paths of the
+derivations, and whose values are a JSON object with the following
+fields:
+
+* `outputs`: Information about the output paths of the
+ derivation. This is a JSON object with one member per output, where
+ the key is the output name and the value is a JSON object with these
+ fields:
+
+ * `path`: The output path.
+ * `hashAlgo`: For fixed-output derivations, the hashing algorithm
+ (e.g. `sha256`), optionally prefixed by `r:` if `hash` denotes a
+ NAR hash rather than a flat file hash.
+ * `hash`: For fixed-output derivations, the expected content hash in
+ base-16.
+
+ Example:
+
+ ```json
+ "outputs": {
+ "out": {
+ "path": "/nix/store/2543j7c6jn75blc3drf4g5vhb1rhdq29-source",
+ "hashAlgo": "r:sha256",
+ "hash": "6fc80dcc62179dbc12fc0b5881275898f93444833d21b89dfe5f7fbcbb1d0d62"
+ }
+ }
+ ```
+
+* `inputSrcs`: A list of store paths on which this derivation depends.
+
+* `inputDrvs`: A JSON object specifying the derivations on which this
+ derivation depends, and what outputs of those derivations. For
+ example,
+
+ ```json
+ "inputDrvs": {
+ "/nix/store/6lkh5yi7nlb7l6dr8fljlli5zfd9hq58-curl-7.73.0.drv": ["dev"],
+ "/nix/store/fn3kgnfzl5dzym26j8g907gq3kbm8bfh-unzip-6.0.drv": ["out"]
+ }
+ ```
+
+ specifies that this derivation depends on the `dev` output of
+ `curl`, and the `out` output of `unzip`.
+
+* `system`: The system type on which this derivation is to be built
+ (e.g. `x86_64-linux`).
+
+* `builder`: The absolute path of the program to be executed to run
+ the build. Typically this is the `bash` shell
+ (e.g. `/nix/store/r3j288vpmczbl500w6zz89gyfa4nr0b1-bash-4.4-p23/bin/bash`).
+
+* `args`: The command-line arguments passed to the `builder`.
+
+* `env`: The environment passed to the `builder`.
+
+)""
diff --git a/src/nix/store-cat.md b/src/nix/store-cat.md
new file mode 100644
index 000000000..da2073473
--- /dev/null
+++ b/src/nix/store-cat.md
@@ -0,0 +1,19 @@
+R""(
+
+# Examples
+
+* Show the contents of a file in a binary cache:
+
+ ```console
+ # nix store cat --store https://cache.nixos.org/ \
+ /nix/store/0i2jd68mp5g6h2sa5k9c85rb80sn8hi9-hello-2.10/bin/hello | hexdump -C | head -n1
+ 00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
+ ```
+
+# Description
+
+This command prints on standard output the contents of the regular
+file *path* in a Nix store. *path* can be a top-level store path or
+any file inside a store path.
+
+)""
diff --git a/src/nix/store-dump-path.md b/src/nix/store-dump-path.md
new file mode 100644
index 000000000..4ef563526
--- /dev/null
+++ b/src/nix/store-dump-path.md
@@ -0,0 +1,23 @@
+R""(
+
+# Examples
+
+* To get a NAR containing the GNU Hello package:
+
+ ```console
+ # nix store dump-path nixpkgs#hello > hello.nar
+ ```
+
+* To get a NAR from the binary cache https://cache.nixos.org/:
+
+ ```console
+ # nix store dump-path --store https://cache.nixos.org/ \
+ /nix/store/7crrmih8c52r8fbnqb933dxrsp44md93-glibc-2.25 > glibc.nar
+ ```
+
+# Description
+
+This command generates a NAR file containing the serialisation of the
+store path *installable*. The NAR is written to standard output.
+
+)""
diff --git a/src/nix/store-ls.md b/src/nix/store-ls.md
new file mode 100644
index 000000000..836efce42
--- /dev/null
+++ b/src/nix/store-ls.md
@@ -0,0 +1,27 @@
+R""(
+
+# Examples
+
+* To list the contents of a store path in a binary cache:
+
+ ```console
+ # nix store ls --store https://cache.nixos.org/ -lR /nix/store/0i2jd68mp5g6h2sa5k9c85rb80sn8hi9-hello-2.10
+ dr-xr-xr-x 0 ./bin
+ -r-xr-xr-x 38184 ./bin/hello
+ dr-xr-xr-x 0 ./share
+ …
+ ```
+
+* To show information about a specific file in a binary cache:
+
+ ```console
+ # nix store ls --store https://cache.nixos.org/ -l /nix/store/0i2jd68mp5g6h2sa5k9c85rb80sn8hi9-hello-2.10/bin/hello
+ -r-xr-xr-x 38184 hello
+ ```
+
+# Description
+
+This command shows information about *path* in a Nix store. *path* can
+be a top-level store path or any file inside a store path.
+
+)""
diff --git a/src/nix/upgrade-nix.cc b/src/nix/upgrade-nix.cc
index 66ecc5b34..79be31e73 100644
--- a/src/nix/upgrade-nix.cc
+++ b/src/nix/upgrade-nix.cc
@@ -37,18 +37,11 @@ struct CmdUpgradeNix : MixDryRun, StoreCommand
return "upgrade Nix to the latest stable version";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To upgrade Nix to the latest stable version:",
- "nix upgrade-nix"
- },
- Example{
- "To upgrade Nix in a specific profile:",
- "nix upgrade-nix -p /nix/var/nix/profiles/per-user/alice/profile"
- },
- };
+ return
+ #include "upgrade-nix.md"
+ ;
}
Category category() override { return catNixInstallation; }
diff --git a/src/nix/upgrade-nix.md b/src/nix/upgrade-nix.md
new file mode 100644
index 000000000..4d27daad9
--- /dev/null
+++ b/src/nix/upgrade-nix.md
@@ -0,0 +1,28 @@
+R""(
+
+# Examples
+
+* Upgrade Nix to the latest stable version:
+
+ ```console
+ # nix upgrade-nix
+ ```
+
+* Upgrade Nix in a specific profile:
+
+ ```console
+ # nix upgrade-nix -p /nix/var/nix/profiles/per-user/alice/profile
+ ```
+
+# Description
+
+This command upgrades Nix to the latest version. By default, it
+locates the directory containing the `nix` binary in the `$PATH`
+environment variable. If that directory is a Nix profile, it will
+upgrade the `nix` package in that profile to the latest stable binary
+release.
+
+You cannot use this command to upgrade Nix in the system profile of a
+NixOS system (that is, if `nix` is found in `/run/current-system`).
+
+)""
diff --git a/src/nix/verify.cc b/src/nix/verify.cc
index bcf85d7dd..16d42349f 100644
--- a/src/nix/verify.cc
+++ b/src/nix/verify.cc
@@ -35,18 +35,11 @@ struct CmdVerify : StorePathsCommand
return "verify the integrity of store paths";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To verify the entire Nix store:",
- "nix store verify --all"
- },
- Example{
- "To check whether each path in the closure of Firefox has at least 2 signatures:",
- "nix store verify -r -n2 --no-contents $(type -p firefox)"
- },
- };
+ return
+ #include "verify.md"
+ ;
}
void run(ref<Store> store, StorePaths storePaths) override
diff --git a/src/nix/verify.md b/src/nix/verify.md
new file mode 100644
index 000000000..1c43792e7
--- /dev/null
+++ b/src/nix/verify.md
@@ -0,0 +1,49 @@
+R""(
+
+# Examples
+
+* Verify the entire Nix store:
+
+ ```console
+ # nix store verify --all
+ ```
+
+* Check whether each path in the closure of Firefox has at least 2
+ signatures:
+
+ ```console
+ # nix store verify -r -n2 --no-contents $(type -p firefox)
+ ```
+
+* Verify a store path in the binary cache `https://cache.nixos.org/`:
+
+ ```console
+ # nix store verify --store https://cache.nixos.org/ \
+ /nix/store/v5sv61sszx301i0x6xysaqzla09nksnd-hello-2.10
+ ```
+
+# Description
+
+This command verifies the integrity of the store paths *installables*,
+or, if `--all` is given, the entire Nix store. For each path, it
+checks that
+
+* its contents match the NAR hash recorded in the Nix database; and
+
+* it is *trusted*, that is, it is signed by at least one trusted
+ signing key, is content-addressed, or is built locally ("ultimately
+ trusted").
+
+# Exit status
+
+The exit status of this command is the sum of the following values:
+
+* **1** if any path is corrupted (i.e. its contents don't match the
+ recorded NAR hash).
+
+* **2** if any path is untrusted.
+
+* **4** if any path couldn't be verified for any other reason (such as
+ an I/O error).
+
+)""
diff --git a/src/nix/why-depends.cc b/src/nix/why-depends.cc
index 57b9a2208..297b638cc 100644
--- a/src/nix/why-depends.cc
+++ b/src/nix/why-depends.cc
@@ -50,22 +50,11 @@ struct CmdWhyDepends : SourceExprCommand
return "show why a package has another package in its closure";
}
- Examples examples() override
+ std::string doc() override
{
- return {
- Example{
- "To show one path through the dependency graph leading from Hello to Glibc:",
- "nix why-depends nixpkgs#hello nixpkgs#glibc"
- },
- Example{
- "To show all files and paths in the dependency graph leading from Thunderbird to libX11:",
- "nix why-depends --all nixpkgs#thunderbird nixpkgs#xorg.libX11"
- },
- Example{
- "To show why Glibc depends on itself:",
- "nix why-depends nixpkgs#glibc nixpkgs#glibc"
- },
- };
+ return
+ #include "why-depends.md"
+ ;
}
Category category() override { return catSecondary; }
diff --git a/src/nix/why-depends.md b/src/nix/why-depends.md
new file mode 100644
index 000000000..dc13619e1
--- /dev/null
+++ b/src/nix/why-depends.md
@@ -0,0 +1,80 @@
+R""(
+
+# Examples
+
+* Show one path through the dependency graph leading from Hello to
+ Glibc:
+
+ ```console
+ # nix why-depends nixpkgs#hello nixpkgs#glibc
+ /nix/store/v5sv61sszx301i0x6xysaqzla09nksnd-hello-2.10
+ └───bin/hello: …...................../nix/store/9l06v7fc38c1x3r2iydl15ksgz0ysb82-glibc-2.32/lib/ld-linux-x86-64.…
+ → /nix/store/9l06v7fc38c1x3r2iydl15ksgz0ysb82-glibc-2.32
+ ```
+
+* Show all files and paths in the dependency graph leading from
+ Thunderbird to libX11:
+
+ ```console
+ # nix why-depends --all nixpkgs#thunderbird nixpkgs#xorg.libX11
+ /nix/store/qfc8729nzpdln1h0hvi1ziclsl3m84sr-thunderbird-78.5.1
+ ├───lib/thunderbird/libxul.so: …6wrw-libxcb-1.14/lib:/nix/store/adzfjjh8w25vdr0xdx9x16ah4f5rqrw5-libX11-1.7.0/lib:/nix/store/ssf…
+ │ → /nix/store/adzfjjh8w25vdr0xdx9x16ah4f5rqrw5-libX11-1.7.0
+ ├───lib/thunderbird/libxul.so: …pxyc-libXt-1.2.0/lib:/nix/store/1qj29ipxl2fyi2b13l39hdircq17gnk0-libXdamage-1.1.5/lib:/nix/store…
+ │ → /nix/store/1qj29ipxl2fyi2b13l39hdircq17gnk0-libXdamage-1.1.5
+ │ ├───lib/libXdamage.so.1.1.0: …-libXfixes-5.0.3/lib:/nix/store/adzfjjh8w25vdr0xdx9x16ah4f5rqrw5-libX11-1.7.0/lib:/nix/store/9l0…
+ │ │ → /nix/store/adzfjjh8w25vdr0xdx9x16ah4f5rqrw5-libX11-1.7.0
+ …
+ ```
+
+* Show why Glibc depends on itself:
+
+ ```console
+ # nix why-depends nixpkgs#glibc nixpkgs#glibc
+ /nix/store/9df65igwjmf2wbw0gbrrgair6piqjgmi-glibc-2.31
+ └───lib/ld-2.31.so: …che Do not use /nix/store/9df65igwjmf2wbw0gbrrgair6piqjgmi-glibc-2.31/etc/ld.so.cache. --…
+ → /nix/store/9df65igwjmf2wbw0gbrrgair6piqjgmi-glibc-2.31
+ ```
+
+* Show why Geeqie has a build-time dependency on `systemd`:
+
+ ```console
+ # nix why-depends --derivation nixpkgs#geeqie nixpkgs#systemd
+ /nix/store/drrpq2fqlrbj98bmazrnww7hm1in3wgj-geeqie-1.4.drv
+ └───/: …atch.drv",["out"]),("/nix/store/qzh8dyq3lfbk3i1acbp7x9wh3il2imiv-gtk+3-3.24.21.drv",["dev"]),("/…
+ → /nix/store/qzh8dyq3lfbk3i1acbp7x9wh3il2imiv-gtk+3-3.24.21.drv
+ └───/: …16.0.drv",["dev"]),("/nix/store/8kp79fyslf3z4m3dpvlh6w46iaadz5c2-cups-2.3.3.drv",["dev"]),("/nix…
+ → /nix/store/8kp79fyslf3z4m3dpvlh6w46iaadz5c2-cups-2.3.3.drv
+ └───/: ….3.1.drv",["out"]),("/nix/store/yd3ihapyi5wbz1kjacq9dbkaq5v5hqjg-systemd-246.4.drv",["dev"]),("/…
+ → /nix/store/yd3ihapyi5wbz1kjacq9dbkaq5v5hqjg-systemd-246.4.drv
+ ```
+
+# Description
+
+Nix automatically determines potential runtime dependencies between
+store paths by scanning for the *hash parts* of store paths. For
+instance, if there exists a store path
+`/nix/store/9df65igwjmf2wbw0gbrrgair6piqjgmi-glibc-2.31`, and a file
+inside another store path contains the string `9df65igw…`, then the
+latter store path *refers* to the former, and thus might need it at
+runtime. Nix always maintains the existence of the transitive closure
+of a store path under the references relationship; it is therefore not
+possible to install a store path without having all of its references
+present.
+
+Sometimes Nix packages end up with unexpected runtime dependencies;
+for instance, a reference to a compiler might accidentally end up in a
+binary, causing the former to be in the latter's closure. This kind of
+*closure size bloat* is undesirable.
+
+`nix why-depends` allows you to diagnose the cause of such issues. It
+shows why the store path *package* depends on the store path
+*dependency*, by showing a shortest sequence in the references graph
+from the former to the latter. Also, for each node along this path, it
+shows a file fragment containing a reference to the next store path in
+the sequence.
+
+To show why derivation *package* has a build-time rather than runtime
+dependency on derivation *dependency*, use `--derivation`.
+
+)""