nixpkgs/maintainers/scripts/rebuild-amount.sh
Nicolas Pierron 342de508d4 Add a script to check the number of packages to rebuild after a modification.
svn path=/nixpkgs/trunk/; revision=17731
2009-10-08 19:00:48 +00:00

260 lines
5.5 KiB
Bash
Executable file

#!/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