summary refs log tree commit diff
path: root/maintainers/scripts/rebuild-amount.sh
blob: ebc5dc3b87ec799b589cd31faaca06092f4901f5 (plain) (blame)
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
#!/bin/sh

usage () {
  echo 1>&2 "
usage:
  $0
    [--git commit..commit | --git commit]
    [--svn rev:rev | --svn rev]
    [--path path[:path]*]
    [--help]

This program is used to investigate how any changes inside your nixpkgs
repository may hurt.  With these kind of information you may choose wisely
where you should commit your changes.

This program adapts it-self to your versionning system to avoid too much
effort on your Internet bandwidth.  If you need to check more than one
commits / revisions, you may use the following commands:

  --git remotes/trunk..master
  --svn 17670:17677

    Check the differences between each commit separating the first and the
    last commit.

  --path /etc/nixos/nixpkgs:/tmp/nixpkgs_1:/tmp/nixpkgs_2

    Check the differences between multiple directories containing different
    versions of nixpkgs.

All these options exist with one commit / revision argument.  Such options
are used to compare your \$NIXPKGS path with the specified version.

If you omit to mention any other commit / revision, then your \$NIXPKGS path
is compared with its last update.  This command is useful to test code from
a dirty repository.

"

  exit 1;
}

#####################
# Process Arguments #
#####################

: ${NIXPKGS=/etc/nixos/nixpkgs/}

vcs=""
gitCommits=""
svnRevisions=""
pathLocations=""
verbose=false

argfun=""
for arg; do
  if test -z "$argfun"; then
    case $arg in
      --git) vcs="git"; argfun="set_gitCommits";;
      --svn) vcs="svn"; argfun="set_svnRevisions";;
      --path) vcs="path"; argfun="set_pathLocations";;
      --verbose) verbose=true;;
      --help) usage;;
      *) usage;;
    esac
  else
    case $argfun in
      set_*)
        var=$(echo $argfun | sed 's,^set_,,')
        eval $var=$arg
        ;;
    esac
    argfun=""
  fi
done

if $verbose; then
  set -x
else
  set +x
fi

############################
# Find the repository type #
############################

if test -z "$vcs"; then
  if test -x "$NIXPKGS/.git"; then
    if git --git-dir="$NIXPKGS/.git" branch > /dev/null 2>&1; then
      vcs="git"
      gitCommits=$(git --git-dir="$NIXPKGS/.git" log -n 1 --pretty=format:%H 2> /dev/null)
    fi
  elif test -x "$NIXPKGS/.svn"; then
    cd "$NIXPKGS"
    if svn info > /dev/null 2>&1; then
      vcs="svn";
      svnRevisions=$(svn info | sed -n 's,Revision: ,,p')
    fi
    cd -
  else
    usage
  fi
fi

###############################
# Define a storage directory. #
###############################

pkgListDir=""
exitCode=1
cleanup(){
  test -e "$pkgListDir" && rm -rf "$pkgListDir"
  exit $exitCode;
}

trap cleanup EXIT SIGINT SIGQUIT ERR

pkgListDir=$(mktemp --tmpdir -d rebuild-amount-XXXXXXXX)
vcsDir="$pkgListDir/.vcs"

###########################
# Versionning for Dummies #
###########################

path_init() {
  if test "${pathLocations#*:}" = "$pathLocations"; then
    pathLocations="$NIXPKGS:$pathLocations"
  fi
  pathLocations="${pathLocations}:"
}

path_getNext() {
  pathLoc="${pathLocations%%:*}"
  pathLocations="${pathLocations#*:}"
}

path_setPath() {
  path="$pathLoc"
}

path_setName() {
  name=$(echo "$pathLoc" | tr '/' '_')
}

################
# Git Commands #
################

git_init() {
  git clone "$NIXPKGS/.git" "$vcsDir" > /dev/null 2>&1
  if echo "gitCommits" | grep -c "\.\." > /dev/null 2>&1; then
    gitCommits=$(git --git-dir="$vcsDir/.git" log --reverse --pretty=format:%H $gitCommits 2> /dev/null)
  else
    pathLocations="$vcsDir:$NIXPKGS"
    vcs="path"
    path_init
  fi
}

git_getNext() {
  git --git-dir="$vcsDir/.git" checkout $(echo "$gitCommits" | head -n 1) > /dev/null 2>&1
  gitCommits=$(echo "$gitCommits" | sed '1 d')
}

git_setPath() {
  path="$vcsDir"
}

git_setName() {
  name=$(git --git-dir="$vcsDir/.git" log -n 1 --pretty=format:%H  2> /dev/null)
}

#######################
# Subversion Commands #
#######################

svn_init() {
  cp -r "$NIXPKGS" "$vcsDir" > /dev/null 2>&1
  if echo "svnRevisions" | grep -c ":" > /dev/null 2>&1; then
    svnRevisions=$(seq ${svnRevisions%:*} ${svnRevisions#*:})
  else
    pathLocations="$vcsDir:$NIXPKGS"
    vcs="path"
    path_init
  fi
}

svn_getNext() {
  cd "$vcsDir"
  svn checkout $(echo "$svnRevisions" | head -n 1) > /dev/null 2>&1
  cd -
  svnRevisions=$(echo "$svnRevisions" | sed '1 d')
}

svn_setPath() {
  path="$vcsDir"
}

svn_setName() {
  name=$(svn info  2> /dev/null | sed -n 's,Revision: ,,p')
}

####################
# Logical Commands #
####################

init    () { ${vcs}_init; }
getNext () { ${vcs}_getNext; }
setPath () { ${vcs}_setPath; }
setName () { ${vcs}_setName; }


#####################
# Check for Rebuild #
#####################

# Generate the list of all derivations that could be build from a nixpkgs
# respository.  This list of derivation hashes is compared with previous
# lists and a brief summary is produced on the output.

compareNames () {
    nb=$(diff -y --suppress-common-lines --speed-large-files "$pkgListDir/$1.drvs" "$pkgListDir/$2.drvs" 2> /dev/null | wc -l)
    echo "$1 -> $2: $nb"
}

echo "Please wait, this may take some minutes ..."

init
first=""
oldPrev=""

prev=""
curr=""

while true; do
  getNext
  setPath # set path=...
  setName # set name=...
  curr="$name"

  test -z "$curr" && break || true

  nix-instantiate "$path" > "$pkgListDir/$curr.drvs" > /dev/null 2>&1 || true

  if test -n "$prev"; then
    compareNames "$prev" "$curr"
  else
    echo "Number of package to rebuild:"
    first="$curr"
  fi
  oldPrev="$prev"
  prev="$curr"
done

if test "$first" != "$oldPrev"; then
  echo "Number of package to rebuild (first -> last):"
  compareNames "$first" "$curr"
fi

exitCode=0