forked from magnetophon/nixos-scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnix-script-diff-generations.sh
executable file
·128 lines (100 loc) · 3.05 KB
/
nix-script-diff-generations.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/usr/bin/env bash
source $(dirname ${BASH_SOURCE[0]})/nix-utils.sh
usage() {
cat <<EOS
$(help_synopsis "${BASH_SOURCE[0]}" "[-s | -u] [-n <a..b>] [-h]")
-s Use system generation for diffing
-u Use system generation for diffing
-n a..b Diff these generations
-h Show this help and exit
Show the diff between two generations, so the installed and removed
packages.
Example usage:
# To show the diff of the system generation 123 to 145
# with verbosity on
nix-script -v diff-generations -s -n 123..145
$(help_end "${BASH_SOURCE[0]}")
EOS
}
__SYSTEM=0
__USER=0
GEN_A=
GEN_B=
while getopts "sun:h" OPTION
do
case $OPTION in
s)
stdout "Setting profile: system"
__SYSTEM=1
__USER=0
;;
u)
stdout "Setting profile: user ($USER)"
__SYSTEM=0
__USER=1
;;
n)
GEN_A=$(echo $OPTARG | cut -d "." -f 1)
GEN_B=$(echo $OPTARG | cut -d "." -f 3)
dbg "Parsing generations: $OPTARG"
dbg "Parsing generations: GEN_A: $GEN_A"
dbg "Parsing generations: GEN_B: $GEN_B"
[[ -z "$GEN_A" || -z "$GEN_B" ]] && \
stderr "Parsing error for '$OPTARG'" && usage && exit 1
;;
h)
usage
exit 1
;;
esac
done
#
# Helper to generate a path for the profile we want to diff with
#
gen_path() {
[[ $__SYSTEM -eq 1 ]] && echo "/nix/var/nix/profiles/system-${1}-link"
[[ $__USER -eq 1 ]] && echo "/nix/var/nix/profiles/per-user/$USER/profile-${1}-link"
}
DIR_A=$(gen_path $GEN_A)
DIR_B=$(gen_path $GEN_B)
dbg "VERBOSE : $VERBOSE"
dbg "SYSTEM : $__SYSTEM"
dbg "USER : $__USER"
dbg "Generation A : $GEN_A"
dbg "from directory : $DIR_A"
dbg "Generation B : $GEN_B"
dbg "from directory : $DIR_B"
#
# Error checking whether the generations exist.
#
[[ -z "$GEN_A" || -z "$GEN_B" ]] && stderr "No generations" && exit 1
[[ ! -e $DIR_A ]] && stderr "Generation $GEN_A does not exist." && exit 1
[[ ! -e $DIR_B ]] && stderr "Generation $GEN_B does not exist." && exit 1
#
# Querying the store for the stuff in a generation A
#
versA=$(mktemp)
stdout "TMP file '$versA' created"
nix-store -qR $DIR_A | sort -t'-' -k 2 > $versA
stdout "Generation packages written for $GEN_A"
#
# Querying the store for the stuff in a generation B
#
versB=$(mktemp)
stdout "TMP file '$versB' created"
nix-store -qR $DIR_B | sort -t'-' -k 2 > $versB
stdout "Generation packages written for $GEN_B"
stdout "Diffing now..."
diff -u $versA $versB | \
# Select only lines that differ.
# (no context, no file name, no line number, etc.)
grep '^[+-]/nix/store' | \
# Remove the "/nix/store/<hash>" garbage.
# Add a space instead, to separate the [+-] from the name.
sed 's:/nix/store/[^-]*-: :' | \
# sort by name, then prefer '+' over '-'.
sort -k 2 -k 1,1r
stdout "Removing tmp directories"
rm $versA
rm $versB
stdout "Ready"