about summary refs log tree commit diff
path: root/scripts/nix-reduce-build.in
blob: 7da368a22cf594ea7c6f762793a78d733025779b (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
#! @shell@

WORKING_DIRECTORY=$(mktemp -d "${TMPDIR:-/tmp}"/nix-reduce-build-XXXXXX);
cd "$WORKING_DIRECTORY";

if test -z "$1" || test "a--help" = "a$1" ; then
	echo 'nix-reduce-build (paths or Nix expressions) -- (package sources)' >&2
	echo As in: >&2
	echo nix-reduce-build /etc/nixos/nixos -- ssh://user@somewhere.nowhere.example.org >&2
	echo nix-reduce-build /etc/nixos/nixos -- \\
	echo "   " \''http://somewhere.nowhere.example.org/nix/nix-http-export.cgi?needed_path='\' >&2
	echo "  store path name will be added into the end of the URL" >&2
	echo nix-reduce-build /etc/nixos/nixos -- file://home/user/nar/ >&2
	echo "  that should be a directory where gzipped 'nix-store --export' ">&2
	echo "  files are located (they should have .nar.gz extension)"  >&2
	echo "        Or all together: " >&2
	echo -e nix-reduce-build /expr.nix /e2.nix -- \\\\\\\n\
	"    ssh://a@b.example.com http://n.example.com/get-nar?q= file://nar/" >&2
	echo "        Also supports best-effort local builds of failing expression set:" >&2
	echo "nix-reduce-build /e.nix -- nix-daemon:// nix-self://" >&2
	echo "  nix-daemon:// builds using daemon"
	echo "  nix-self:// builds directly using nix-store from current installation" >&2
	echo "  nix-daemon-fixed:// and nix-self-fixed:// do the same, but only for" >&2;
	echo "derivations with specified output hash (sha256, sha1 or md5)." >&2
	echo "  nix-daemon-substitute:// and nix-self-substitute:// try to substitute" >&2;
	echo "maximum amount of paths" >&2;
	exit;
fi;

while ! test "$1" = "--" || test "$1" = "" ; do 
	echo "$1" >> initial; >&2
	shift;
done
shift;
echo Will work on $(cat initial | wc -l) targets. >&2

while read ; do
	case "$REPLY" in 
		${NIX_STORE_DIR:-/nix/store}/*)
			echo "$REPLY" >> paths; >&2
			;;
		*)
			(
				IFS=: ;
				nix-instantiate $REPLY >> paths;
			);
			;;
	esac;
done < initial;
echo Proceeding $(cat paths | wc -l) paths. >&2

while read; do
	case "$REPLY" in
		*.drv)
			echo "$REPLY" >> derivers; >&2
			;;
		*)
			nix-store --query --deriver "$REPLY" >>derivers;
			;;
	esac;
done < paths;
echo Found $(cat derivers | wc -l) derivers. >&2

cat derivers | xargs nix-store --query -R > derivers-closure;
echo Proceeding at most $(cat derivers-closure | wc -l) derivers. >&2

cat derivers-closure | egrep '[.]drv$' | xargs nix-store --query --outputs > wanted-paths;
cat derivers-closure | egrep -v '[.]drv$' >> wanted-paths;
echo Prepared $(cat wanted-paths | wc -l) paths to get. >&2

cat wanted-paths | xargs nix-store --check-validity --print-invalid > needed-paths;
echo We need $(cat needed-paths | wc -l) paths. >&2

if test -z "$1" ; then
	cat needed-paths;	
fi;

for i in "$@"; do 
	sshHost="${i#ssh://}";
	httpHost="${i#http://}";
	httpsHost="${i#https://}";
	filePath="${i#file:/}";
	if [ "$i" != "$sshHost" ]; then
		cat needed-paths | while read; do 
			echo "Getting $REPLY and its closure over ssh" >&2
			nix-copy-closure --from "$sshHost" --gzip "$REPLY" </dev/null || true; 
		done;
	elif [ "$i" != "$httpHost" ] || [ "$i" != "$httpsHost" ]; then
		cat needed-paths | while read; do
			echo "Getting $REPLY over http/https" >&2
			curl ${BAD_CERTIFICATE:+-k} -L "$i${REPLY##*/}" | gunzip | nix-store --import;
		done;
	elif [ "$i" != "$filePath" ] ; then
		cat needed-paths | while read; do 
			echo "Installing $REPLY from file" >&2
			gunzip < "$filePath/${REPLY##*/}".nar.gz | nix-store --import;
		done;
	elif [ "$i" = "nix-daemon://" ] ; then
		cat needed-paths | while read ; do 
			echo "Building $REPLY using nix-daemon" >&2
			NIX_REMOTE=daemon @bindir@/nix-store -r "${NIX_STORE_DIR:-/nix/store}/${REPLY##*/}"
		done;
		cat derivers-closure | while read; do 
			echo "Realising $REPLY using nix-daemon" >&2
			NIX_REMOTE=daemon @bindir@/nix-store -r "${REPLY}"
		done;
	elif [ "$i" = "nix-self://" ] ; then
		cat needed-paths | while read ; do 
			echo "Building $REPLY using direct Nix build" >&2
			NIX_REMOTE= @bindir@/nix-store -r "${NIX_STORE_DIR:-/nix/store}/${REPLY##*/}" 
		done;
		cat derivers-closure | while read; do 
			echo "Realising $REPLY using direct Nix build" >&2
			NIX_REMOTE= @bindir@/nix-store -r "${REPLY}"
		done;
	elif [ "$i" = "nix-daemon-fixed://" ] ; then
		cat derivers-closure | while read; do 
			if egrep '"(md5|sha1|sha256)"' "$REPLY" &>/dev/null; then
				echo "Realising $REPLY using nix-daemon" >&2
				NIX_REMOTE=daemon @bindir@/nix-store -r "${REPLY}"
			fi;
		done;
	elif [ "$i" = "nix-self-fixed://" ] ; then
		cat derivers-closure | while read; do 
			if egrep '"(md5|sha1|sha256)"' "$REPLY" &>/dev/null; then
				echo "Realising $REPLY using direct Nix build" >&2
				NIX_REMOTE= @bindir@/nix-store -r "${REPLY}"
			fi;
		done;
	elif [ "$i" = "nix-daemon-substitute://" ] ; then
		cat needed-paths | while read ; do 
			echo "Substituting $REPLY using nix-daemon" >&2
			NIX_REMOTE=daemon @bindir@/nix-store -r "${NIX_STORE_DIR:-/nix/store}/${REPLY##*/}"
		done;
	elif [ "$i" = "nix-self-substitute://" ] ; then
		cat needed-paths | while read ; do 
			echo "Substituting $REPLY using direct Nix build" >&2
			NIX_REMOTE= @bindir@/nix-store -r "${NIX_STORE_DIR:-/nix/store}/${REPLY##*/}" 
		done;
	fi;
	mv needed-paths wanted-paths;
	cat wanted-paths | xargs nix-store --check-validity --print-invalid > needed-paths;
	echo We still need $(cat needed-paths | wc -l) paths. >&2
done;

cd /
rm -r "$WORKING_DIRECTORY"