From 709a8a2ed39b6fbb9a2e9a3cf04130c4c5bc42d3 Mon Sep 17 00:00:00 2001 From: Bryan Gardiner Date: Fri, 9 Apr 2021 21:05:12 -0700 Subject: [PATCH] Docs, packaging, licensing. --- .gitignore | 2 + README.md | 56 ++++++++++ default.nix | 22 ++++ nvd.1 | 64 ----------- nvd => src/nvd | 20 +++- src/nvd.1 | 287 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 386 insertions(+), 65 deletions(-) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 default.nix delete mode 100644 nvd.1 rename nvd => src/nvd (95%) create mode 100644 src/nvd.1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2d11506 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*~ +result diff --git a/README.md b/README.md new file mode 100644 index 0000000..9979c2b --- /dev/null +++ b/README.md @@ -0,0 +1,56 @@ +# nvd - Nix/NixOS package version diff tool + +**nvd** is a tool for diffing the versions of all store paths in the closures of +two Nix store paths, neatly summarizing the differences. This is mainly +intended for comparing two system configurations and is inspired by the output +of `emerge -pv` from Gentoo's Portage package manager. nvd could also be +likened to the output of Debian's `apt upgrade -V`, or any equivalent from other +distributions' package managers. nvd isn't limited to comparing system +configurations though, and can work with any two store paths. + +I wrote nvd as a way to see what is changing on my systems when I run +`nixos-rebuild`. Package rebuilds usually aren't important to me, but I need to +know when versions change. Usually I care most about packages that are included +in `environment.systemPackages`, so packages in this list are highlighted and +coloured specially and changes to this list are reported. + +I recommend wrapping your usual `nixos-rebuild` call in a script that compares +the result to the current system: + + nixos-rebuild build "$@" && nvd /run/current-system result + +Here is an example session. We can see that Nixpkgs updates have been pulled +in, bringing in various package updates. Firefox and cpupower have been +installed explicitly in `systemPackages`, and `bpytop` has been newly added to +the list: + + $ nvd /nix/var/nix/profiles/system-{14,15}-link + <<< /nix/var/nix/profiles/system-14-link + >>> /nix/var/nix/profiles/system-15-link + Version changes: + [U*] #1 cpupower 5.4.87 -> 5.4.88 + [U*] #2 firefox 84.0.1 -> 84.0.2 + [U.] #3 firefox-unwrapped 84.0.1 -> 84.0.2 + [U.] #4 initrd-linux 5.4.87 -> 5.4.88 + [U.] #5 linux 5.4.87 -> 5.4.88 + [U.] #6 nixos-system-unnamed 20.09.git.6ad5c94ed93 -> 20.09.git.9bf1626e7bb + [U.] #7 system76-acpi-module 1.0.1-5.4.87 -> 1.0.1-5.4.88 + [U.] #8 system76-io-module 1.0.1-5.4.87 -> 1.0.1-5.4.88 + [U.] #9 x86_energy_perf_policy 5.4.87 -> 5.4.88 + Added packages: + [A+] #1 bpytop 1.0.50 + Closure size: 2205 -> 2206 (38 paths added, 37 paths removed, delta +1). + +## License + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..cba6da2 --- /dev/null +++ b/default.nix @@ -0,0 +1,22 @@ +{ pkgs ? import {} }: +with pkgs; +stdenv.mkDerivation { + name = "nvd"; + + src = nix-gitignore.gitignoreSourcePure [ ./.gitignore ] ./src; + + buildInputs = [ python3 ]; + + buildPhase = '' + runHook preBuild + gzip nvd.1 + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + install -m555 -Dt $out/bin nvd + install -m444 -Dt $out/share/man/man1 nvd.1.gz + runHook postInstall + ''; +} diff --git a/nvd.1 b/nvd.1 deleted file mode 100644 index 584b21e..0000000 --- a/nvd.1 +++ /dev/null @@ -1,64 +0,0 @@ -.TH nvd 1 2021-04-06 nvd "User Commands" -.SH NAME -nvd \- Nix/NixOS package version diff tool -.SH SYNOPSIS -.P -.B nvd [ -h | --help ] -.P -.B nvd [ --color=(auto|always|never) ] root1 root2 -.SH DESCRIPTION -.P -.B nvd -is a tool for diffing the versions of all store paths in the closures of two Nix -store paths, neatly summarizing the differences. This is mainly intended for -comparing two system configurations and is inspired by the output of -.B emerge -pv -from Gentoo's Portage package manager. -.B nvd -could also be likened to the output of Debian's -.B apt upgrade -V, -or any equivalent from other distributions' package managers. -.B nvd -isn't limited to comparing system configurations though, and can work with any -two store paths. -.P -When given two system configurations, -.B nvd -distinguishes between packages that are explicitly included in -.B environment.systemPackages, -versus the rest of the packages that make up the system. The former packages -are dubbed -.I selected packages. -.B nvd -marks and bolds any selected packages it lists. Additionally, -.B nvd -reports on any changes to packages' selection states between the two -configurations. This is done by looking at all packages that are referenced -directly from the configurations' system paths, within each -.I /sw -subdirectory. When either of the arguments isn't a system configuration, -i.e. when either of the arguments is missing a -.I sw -subdirectory, then -.I selected packages -refer to direct dependencies of each of the arguments instead, and the -comparison is still performed. -.B nvd -doesn't actually know if a Nix package represents a system configuration; it -just uses the existence of a -.I sw -directory as a heuristic. -.SH OPTIONS -.P -.TP --h, --help -Displays a brief help message. -.TP ---color=(auto|always|never) -When to display colour. The default -.B auto -detects whether stdout is a terminal and only uses colour if it is. Passing -.B always -forces colour to always be used, and passing -.B never -forces colour to never be used. diff --git a/nvd b/src/nvd similarity index 95% rename from nvd rename to src/nvd index 64f72cd..5801bcd 100755 --- a/nvd +++ b/src/nvd @@ -1,6 +1,22 @@ #!/usr/bin/env python3 -# TODO Closure disk size change. +# nvd - Nix/NixOS package version diff tool +# +# Copyright 2021 Bryan Gardiner +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# See the nvd(1) man page for user-facing docs. # Package install state (by pname): # A: Added to closure @@ -79,6 +95,8 @@ SEL_SELECTED = "*" SEL_UNSELECTED = "." SEL_NEWLY_SELECTED = "+" SEL_NEWLY_UNSELECTED = "-" +# There's no way to reach these selection states currently, since manifests are +# always computed. SEL_LEFT_ONLY_SELECTED = "L" SEL_LEFT_ONLY_UNSELECTED = "l" SEL_RIGHT_ONLY_SELECTED = "R" diff --git a/src/nvd.1 b/src/nvd.1 new file mode 100644 index 0000000..0a921e2 --- /dev/null +++ b/src/nvd.1 @@ -0,0 +1,287 @@ +.TH nvd 1 2021-04-09 nvd "User Commands" +.SH NAME +nvd \- Nix/NixOS package version diff tool +.SH SYNOPSIS +.P +.B nvd [ -h | --help ] +.P +.B nvd [ --color=(auto|always|never) ] root1 root2 +.SH DESCRIPTION +.P +.B nvd +is a tool for diffing the versions of all store paths in the closures of two Nix +store paths, neatly summarizing the differences. This is mainly intended for +comparing two system configurations and is inspired by the output of +.B emerge -pv +from Gentoo's Portage package manager. +.B nvd +could also be likened to the output of Debian's +.B apt upgrade -V, +or any equivalent from other distributions' package managers. +.B nvd +isn't limited to comparing system configurations though, and can work with any +two store paths. +.P +When given two system configurations, +.B nvd +distinguishes between packages that are explicitly included in +.B environment.systemPackages, +versus the rest of the packages that make up the system. The former packages +are dubbed +.I selected packages. +.B nvd +marks and bolds any selected packages it lists. Additionally, +.B nvd +reports on any changes to packages' selection states between the two +configurations. This is done by looking at all packages that are referenced +directly from the configurations' system paths, within each +.I /sw +subdirectory. When either of the arguments isn't a system configuration, +i.e. when either of the arguments is missing a +.I sw +subdirectory, then +.I selected packages +refer to direct dependencies of each of the arguments instead, and the +comparison is still performed. +.B nvd +doesn't actually know if a Nix package represents a system configuration; it +just uses the existence of a +.I sw +directory as a heuristic. +.P +.B nvd +relies on parsing Nix store paths into (pname, version) pairs, by looking at the +part of the store path after the hash and splitting on the first occurence of +.I /-[0-9]/ +(then also stripping off a suffix of +.I .drv +if that is present). If a version cannot be found from the path, the string +.I +is used instead. Packages are identified by their +.B pnames +this way. This will not properly handle if +.I -[0-9] +occurs within a Nix expression's actual +.B pname. +Another limitation is that this ends up treating multiple outputs from a +derivation as distinct versions of the derivation with the output names appended +to the version strings, although this produces reasonable output. +.P +.B nvd +sorts versions using the same algorithm as +.B builtins.compareVersions +and +.B nix-env -u, +for more details see: +.I https://nixos.org/manual/nix/stable/#versions +.SH OPTIONS +.P +.TP +-h, --help +Displays a brief help message. +.TP +--color=(auto|always|never) +When to display colour. The default +.B auto +detects whether stdout is a terminal and only uses colour if it is. Passing +.B always +forces colour to always be used, and passing +.B never +forces colour to never be used. +.SH OUTPUT +.P +The output of +.B nvd +displays the given names of the two store paths being compared on the first two +lines, then changed packages on subsequent lines, one line per package, grouped +by the type of change. Newly added or removed packages, packages with version +or count changes, and packages with selection state changes are displayed. Hash changes are +.B not +considered important, and will not cause a package to be displayed, however +changes in the number of times a package +.B (pname) +appears will. +.P +The first two lines of output display the paths being compared: +.P +.RS +.EX +<<< /nix/var/nix/profiles/system-1-link +>>> /nix/var/nix/profiles/system-2-link +.EE +.RE +.P +After this, packages are listed. Each package is displayed on a line like the +following. +.P +.RS +.EX +[U.] #1 linux 5.4.99 -> 5.4.100 + ^^ ^ ^ ^ + || | package name package versions + || count of packages within the section + |package selection state + package install state +.EE +.RE +.P +The +.B package install state +is a single character indicating the whether the package is newly being added or +removed, upgraded or downgraded. The possibilities here are: +.P +.RS +.EX +A: Package is newly added to the closure. +R: All versions of the package are being removed the closure. +U: The package is being upgraded. +D: The package is being downgraded. +C: None of the above apply; unspecified changes. +.EE +.RE +.P +Packages can be displayed with +.B C +install state for a few different reasons, including the number of copies of an +existing version in the closure changing, or due to the selection state changing +even if the versions stay the same. Also, upgrades (downgrades) are determined +by checking whether all new versions of the package are strictly higher (lower) +than all old versions of the package, so there are scenarios where a package +will be labelled as +.B C +rather than +.B U +or +.B D +as it perhaps should be. +.P +The +.B package selection state +character indicates the presence of the package in +.B environment.systemPackages, +and changes to that inclusion. The possibilities here are: +.P +.RS +.EX ++: Package is newly selected in environment.systemPackages. +-: Package is newly unselected. +*: Package is selected; state unchanged. +\&.: Package is not selected; it's a dependency. +.EE +.RE +.P +If there are multiple versions of a package, they will be shown separated by +commas. If there are multiple occurences of a single package version, they will be shown with a +.BI x N +suffix for the number of times +.I N +the version is present. Versions are always displayed in ascending order. If +there is any change between the old and new versions of a package, then first +the old versions will be displayed, then +.B ->, +then the new versions. +.P +The displayed version strings can be lengthly for some packages, for example: +.P +.RS +.EX +[C*] #05 glib 2.64.5 x2, 2.64.5-bin x2, 2.64.5-dev, 2.66.4 -> 2.64.6 x2, 2.64.6-bin x2, 2.64.6-dev, 2.66.4 +[C.] #06 gnutls 3.6.15 x3 -> 3.6.15, 3.7.1 x2 +.EE +.RE +.SH EXAMPLES +.P +Here is an example where the games +.B liquidwar6 +and +.B neverball +have been installed. A number of packages have been pulled in as dependencies, +plus additional versions of some existing packages: +.P +.RS +.EX +$ nvd /nix/var/nix/profiles/system-{29,30}-link +<<< /nix/var/nix/profiles/system-29-link +>>> /nix/var/nix/profiles/system-30-link +Version changes: +[C.] #1 SDL2_ttf 2.0.15 -> 2.0.15 x2 +[C.] #2 pkg-config 0.29.2 -> 0.29.2 x2 +[C.] #3 pkg-config-wrapper 0.29.2 -> 0.29.2 x2 +Added packages: +[A.] #1 CUnit 2.1-3 +[A.] #2 SDL_mixer 1.2.12 +[A.] #3 SDL_ttf 2.0.11 +[A+] #4 liquidwar6 0.6.3902 +[A+] #5 neverball 1.6.0 +[A.] #6 physfs 3.0.2 +[A.] #7 smpeg-svn390 +Closure size: 2382 -> 2392 (21 paths added, 11 paths removed, delta +10). +.EE +.RE +.P +Here is another example, where several updates have been pulled in from Nixpkgs, +including in +.B cpupower +(which is using the Linux kernel's version) and +.B xterm +which are on the system path. Additionally, +.B gpsbabel +and +.B gpxsee +have been installed. +.P +.RS +.EX +$ nvd /nix/var/nix/profiles/system-{33,34}-link +<<< /nix/var/nix/profiles/system/system-33-link +>>> /nix/var/nix/profiles/system/system-34-link +Version changes: +[U*] #1 cpupower 5.4.99 -> 5.4.100 +[U.] #2 initrd-linux 5.4.99 -> 5.4.100 +[U.] #3 linux 5.4.99 -> 5.4.100 +[U.] #4 nixos-system-unnamed 20.09.git.d041da76935 -> 20.09.git.872a1ebbb1b +[U.] #5 system76-acpi-module 1.0.1-5.4.99 -> 1.0.1-5.4.100 +[U.] #6 system76-io-module 1.0.1-5.4.99 -> 1.0.1-5.4.100 +[U.] #7 x86_energy_perf_policy 5.4.99 -> 5.4.100 +[U*] #8 xterm 353 -> 366 +Added packages: +[A+] #1 gpsbabel 1.6.0 +[A+] #2 gpxsee 7.31 +[A.] #3 qttranslations 5.15.2 +Closure size: 2480 -> 2483 (44 paths added, 41 paths removed, delta +3). +.EE +.RE +.P +.P +In this next example, a Nixpkgs update was performed that caused some 16 paths +in the system to be rebuilt that don't affect the versions or counts or +selection states of any installed packages. The only visible change is the +changing version of the system derivation itself. Note that it is +.B incorrectly +reported as a downgrade because the new Git revision sorts lower than the old +one, despite this actually being a newer commit than the old one: +.P +.RS +.EX +$ nvd /nix/var/nix/profiles/system-{43,44}-link +<<< /nix/var/nix/profiles/system/system-43-link +>>> /nix/var/nix/profiles/system/system-44-link +Version changes: +[D.] #1 nixos-system-unnamed 20.09.git.61092780ec5 -> 20.09.git.f79caa0b693 +Closure size: 2329 -> 2329 (16 paths added, 16 paths removed, delta +0). +.EE +.RE +.P +It is possible for +.B nvd +to output no packages at all if no versions have changed: +.P +.RS +.EX +$ nvd /nix/var/nix/profiles/system-{23,24}-link +<<< /nix/var/nix/profiles/system/system-23-link +>>> /nix/var/nix/profiles/system/system-24-link +No version or selection state changes. +Closure size: 2191 -> 2191 (3 paths added, 3 paths removed, delta +0). +.EE +.RE