diff --git a/doc/manual/source/command-ref/nix-store/query.md b/doc/manual/source/command-ref/nix-store/query.md index 601f46af6b2..b5ba63adae2 100644 --- a/doc/manual/source/command-ref/nix-store/query.md +++ b/doc/manual/source/command-ref/nix-store/query.md @@ -45,10 +45,19 @@ symlink. [output paths]: @docroot@/glossary.md#gloss-output-path +- `--references` + + Prints the set of [references] of the store paths + *paths*, that is, their immediate dependencies. (For *all* + dependencies, use `--requisites`.) + + [references]: @docroot@/glossary.md#gloss-reference + - `--requisites` / `-R` - Prints out the [closure] of the store path *paths*. + Prints out the set of [*requisites*][requisite] (better known as the [closure]) of the store path *paths*. + [requisite]: @docroot@/glossary.md#gloss-requisite [closure]: @docroot@/glossary.md#gloss-closure This query has one option: @@ -65,29 +74,25 @@ symlink. dependencies) is obtained by distributing the closure of a store derivation and specifying the option `--include-outputs`. -- `--references` - - Prints the set of [references] of the store paths - *paths*, that is, their immediate dependencies. (For *all* - dependencies, use `--requisites`.) - - [references]: @docroot@/glossary.md#gloss-reference - - `--referrers` - Prints the set of *referrers* of the store paths *paths*, that is, + Prints the set of [*referrers*][referrer] of the store paths *paths*, that is, the store paths currently existing in the Nix store that refer to one of *paths*. Note that contrary to the references, the set of referrers is not constant; it can change as store paths are added or removed. + [referrer]: @docroot@/glossary.md#gloss-referrer + - `--referrers-closure` Prints the closure of the set of store paths *paths* under the - referrers relation; that is, all store paths that directly or + [referrers relation][referrer]; that is, all store paths that directly or indirectly refer to one of *paths*. These are all the path currently in the Nix store that are dependent on *paths*. + [referrer]: @docroot@/glossary.md#gloss-referrer + - `--deriver` / `-d` Prints the [deriver] that was used to build the store paths *paths*. If diff --git a/doc/manual/source/development/contributing.md b/doc/manual/source/development/contributing.md index 7de7489dcb7..5c32aeb712a 100644 --- a/doc/manual/source/development/contributing.md +++ b/doc/manual/source/development/contributing.md @@ -20,8 +20,9 @@ prs: 1238 Here's one or more paragraphs that describe the change. - It's markdown -- Add references to the manual using @docroot@ +- Add references to the manual using [links like this](@_at_docroot@/example.md) ``` + Significant changes should add the following header, which moves them to the top. diff --git a/doc/manual/source/glossary.md b/doc/manual/source/glossary.md index f38664a0265..37b1ff6ec59 100644 --- a/doc/manual/source/glossary.md +++ b/doc/manual/source/glossary.md @@ -38,6 +38,13 @@ [store derivation]: #gloss-store-derivation +- [directed acyclic graph]{#gloss-directed-acyclic-graph} + + A [directed acyclic graph](https://en.wikipedia.org/wiki/Directed_acyclic_graph) (DAG) is graph whose edges are given a direction ("a to b" is not the same edge as "b to a"), and for which no possible path (created by joining together edges) forms a cycle. + + DAGs are very important to Nix. + In particular, the non-self-[references][reference] of [store object][store object] form a cycle. + - [derivation path]{#gloss-derivation-path} A [store path] which uniquely identifies a [store derivation]. @@ -156,6 +163,8 @@ non-[fixed-output](#gloss-fixed-output-derivation) derivation. + See [input-addressing derivation outputs](store/derivation/outputs/input-address.md) for details. + - [content-addressed store object]{#gloss-content-addressed-store-object} A [store object] which is [content-addressed](#gloss-content-address), @@ -219,19 +228,21 @@ - [reference]{#gloss-reference} - A [store object] `O` is said to have a *reference* to a store object `P` if a [store path] to `P` appears in the contents of `O`. + An edge from one [store object] to another. - Store objects can refer to both other store objects and themselves. - References from a store object to itself are called *self-references*. - References other than a self-reference must not form a cycle. + See [References](@docroot@/store/store-object.md#references) for details. [reference]: #gloss-reference + See [References](@docroot@/store/store-object.md#references) for details. + - [reachable]{#gloss-reachable} A store path `Q` is reachable from another store path `P` if `Q` is in the *closure* of the *references* relation. + See [References](@docroot@/store/store-object.md#references) for details. + - [closure]{#gloss-closure} The closure of a store path is the set of store paths that are @@ -248,8 +259,21 @@ to a store object at path `Q`, then `Q` is in the closure of `P`. Further, if `Q` references `R` then `R` is also in the closure of `P`. + See [References](@docroot@/store/store-object.md#references) for details. + [closure]: #gloss-closure +- [requisite]{#gloss-requisite} + + A store object [reachable] by a path (chain of references) from a given [store object]. + The [closure] is the set of requisites. + + See [References](@docroot@/store/store-object.md#references) for details. + +- [referrer]{#gloss-reference} + + A reversed edge from one [store object] to another. + - [output]{#gloss-output} A [store object] produced by a [store derivation]. diff --git a/doc/manual/source/language/advanced-attributes.md b/doc/manual/source/language/advanced-attributes.md index 4af255bf34e..a939847e1aa 100644 --- a/doc/manual/source/language/advanced-attributes.md +++ b/doc/manual/source/language/advanced-attributes.md @@ -79,6 +79,8 @@ Derivations can declare some infrequently used optional attributes. ## Output checks +See the [corresponding section in the derivation output page](@docroot@/store/derivation/outputs/index.md). + - [`allowedReferences`]{#adv-attr-allowedReferences}\ The optional attribute `allowedReferences` specifies a list of legal references (dependencies) of the output of the builder. For example, diff --git a/doc/manual/source/language/operators.md b/doc/manual/source/language/operators.md index dbf2441cb7c..ab74e8a9999 100644 --- a/doc/manual/source/language/operators.md +++ b/doc/manual/source/language/operators.md @@ -196,7 +196,7 @@ All comparison operators are implemented in terms of `<`, and the following equi ## Logical implication -Equivalent to `!`*b1* `||` *b2*. +Equivalent to `!`*b1* `||` *b2* (or `if` *b1* `then` *b2* `else true`) [Logical implication]: #logical-implication diff --git a/doc/manual/source/store/store-object.md b/doc/manual/source/store/store-object.md index caf5657d1f0..660d02f2a57 100644 --- a/doc/manual/source/store/store-object.md +++ b/doc/manual/source/store/store-object.md @@ -4,7 +4,64 @@ A Nix store is a collection of *store objects* with *references* between them. A store object consists of - A [file system object](./file-system-object.md) as data - - A set of [store paths](./store-path.md) as references to other store objects + + - A set of [store paths](./store-path.md) as references to store objects + +### References + +Store objects can refer to both other store objects and themselves. +References from a store object to itself are called *self-references*. + +Store objects and their references form a directed graph, where the store objects are the vertices, and the references are the edges. +In particular, the edge corresponding to a reference is from the store object that contains the reference, and to the store object that the store path (which is the reference) refers to. + +References other than a self-reference must not form a cycle. +The graph of references excluding self-references thus forms a [directed acyclic graph]. + +[directed acyclic graph]: @docroot@/glossary.md#gloss-directed acyclic graph + +We can take the [transitive closure] of the references graph, which any pair of store objects have an edge not if there is a single reference from the first to the second, but a path of one or more references from the first to the second. +The *requisites* of a store object are all store objects reachable by paths of references which start with given store object's references. + +[transitive closure]: https://en.wikipedia.org/wiki/Transitive_closure + +We can also take the [transpose graph] ofthe references graph, where we reverse the orientation of all edges. +The *referrers* of a store object are the store objects that reference it. + +[transpose graph]: https://en.wikipedia.org/wiki/Transpose_graph + +One can also combine both concepts: taking the transitive closure of the tranposed references graph. +The *referrers closure* of a store object are the store objects that can reach the given store object via paths of references. + +> **Note** +> +> Care must be taken to distinguish between the intrinsic and extrinsic properties of store objects. +> We can create graphs from the store objects in a store, but the contents of the store is not, in general fixed, and may instead change over time. +> +> - The references of a store object --- the set of store paths called the references --- is a field of a store object, and thus intrinsic by definition. + Regardless of what store contains the store object in question, and what else that store may or may not contain, the references are the same. +> +> - The requisites of a store object are almost intrinsic --- some store paths due not precisely refer to a unique single store object. +> Exactly what store object is being referenced, and what in turn *its* references are, depends on the store in question. +> Different stores that disagree. +> +> - The referrers of a store object are completely extrinsic, and depends solely on the store which contains that store object, not the store object itself. +> Other store objects which refer to the store object in question may be added or removed from the store. + +### Immutability Store objects are [immutable](https://en.wikipedia.org/wiki/Immutable_object): -Once created, they do not change until they are deleted. +Once created, they do not change nor can any store object they reference be changed. + +> **Note** +> +> Stores which support atomically deleting multiple store objects allow more flexibility while still upholding this property. + +### Closure property + +A store can only contain a store object if it also contains all the store objects it refers to. + +> **Note** +> +> The "closure property" isn't meant to prohibit, for example, [lazy loading](https://en.wikipedia.org/wiki/Lazy_loading) of store objects. +> However, the "closure property" and immutability in conjunction imply that any such lazy loading ought to be deterministic. diff --git a/doc/manual/substitute.py b/doc/manual/substitute.py index a8b11d93250..6e27c338818 100644 --- a/doc/manual/substitute.py +++ b/doc/manual/substitute.py @@ -57,6 +57,9 @@ def recursive_replace(data: dict[str, t.Any], book_root: Path, search_path: Path ).replace( '@docroot@', ("../" * len(path_to_chapter.parent.parts) or "./")[:-1] + ).replace( + '@_at_', + '@' ), sub_items = [ recursive_replace(sub_item, book_root, search_path) diff --git a/docker.nix b/docker.nix index d52c317d6b1..2670f8394ca 100644 --- a/docker.nix +++ b/docker.nix @@ -173,7 +173,12 @@ let channel = pkgs.runCommand "channel-nixos" { inherit bundleNixpkgs; } '' mkdir $out if [ "$bundleNixpkgs" ]; then - ln -s ${nixpkgs} $out/nixpkgs + ln -s ${ + builtins.path { + path = nixpkgs; + name = "source"; + } + } $out/nixpkgs echo "[]" > $out/manifest.nix fi ''; diff --git a/scripts/nix-profile-daemon.fish.in b/scripts/nix-profile-daemon.fish.in index 2ecab007766..da4c61bc1c6 100644 --- a/scripts/nix-profile-daemon.fish.in +++ b/scripts/nix-profile-daemon.fish.in @@ -24,7 +24,33 @@ end # Set up the per-user profile. -set --local NIX_LINK $HOME/.nix-profile +set --local NIX_LINK "$HOME/.nix-profile" +set --local NIX_LINK_NEW +if test -n "$XDG_STATE_HOME" + set NIX_LINK_NEW "$XDG_STATE_HOME/nix/profile" +else + set NIX_LINK_NEW "$HOME/.local/state/nix/profile" +end +if test -e "$NIX_LINK_NEW" + if test -t 2; and test -e "$NIX_LINK" + set --local warning "\033[1;35mwarning:\033[0m " + printf "$warning Both %s and legacy %s exist; using the former.\n" "$NIX_LINK_NEW" "$NIX_LINK" 1>&2 + + if test (realpath "$NIX_LINK") = (realpath "$NIX_LINK_NEW") + printf " Since the profiles match, you can safely delete either of them.\n" 1>&2 + else + # This should be an exceptionally rare occasion: the only way to get it would be to + # 1. Update to newer Nix; + # 2. Remove .nix-profile; + # 3. Set the $NIX_LINK_NEW to something other than the default user profile; + # 4. Roll back to older Nix. + # If someone did all that, they can probably figure out how to migrate the profile. + printf "$warning Profiles do not match. You should manually migrate from %s to %s.\n" "$NIX_LINK" "$NIX_LINK_NEW" 1>&2 + end + end + + set NIX_LINK "$NIX_LINK_NEW" +end # Set up environment. # This part should be kept in sync with nixpkgs:nixos/modules/programs/environment.nix diff --git a/scripts/nix-profile.fish.in b/scripts/nix-profile.fish.in index 05d9a187de3..b73b92ad127 100644 --- a/scripts/nix-profile.fish.in +++ b/scripts/nix-profile.fish.in @@ -24,7 +24,38 @@ end # Set up the per-user profile. -set --local NIX_LINK $HOME/.nix-profile +set --local NIX_LINK +if test -n "$NIX_STATE_HOME" + set NIX_LINK "$NIX_STATE_HOME/.nix-profile" +else + set NIX_LINK "$HOME/.nix-profile" + set --local NIX_LINK_NEW + if test -n "$XDG_STATE_HOME" + set NIX_LINK_NEW "$XDG_STATE_HOME/nix/profile" + else + set NIX_LINK_NEW "$HOME/.local/state/nix/profile" + end + if test -e "$NIX_LINK_NEW" + if test -t 2; and test -e "$NIX_LINK" + set --local warning "\033[1;35mwarning:\033[0m " + printf "$warning Both %s and legacy %s exist; using the former.\n" "$NIX_LINK_NEW" "$NIX_LINK" 1>&2 + + if test (realpath "$NIX_LINK") = (realpath "$NIX_LINK_NEW") + printf " Since the profiles match, you can safely delete either of them.\n" 1>&2 + else + # This should be an exceptionally rare occasion: the only way to get it would be to + # 1. Update to newer Nix; + # 2. Remove .nix-profile; + # 3. Set the $NIX_LINK_NEW to something other than the default user profile; + # 4. Roll back to older Nix. + # If someone did all that, they can probably figure out how to migrate the profile. + printf "$warning Profiles do not match. You should manually migrate from %s to %s.\n" "$NIX_LINK" "$NIX_LINK_NEW" 1>&2 + end + end + + set NIX_LINK "$NIX_LINK_NEW" + end +end # Set up environment. # This part should be kept in sync with nixpkgs:nixos/modules/programs/environment.nix