1# This function downloads and unpacks an archive file, such as a zip
2# or tar file. This is primarily useful for dynamically generated
3# archives, such as GitHub's /archive URLs, where the unpacked content
4# of the zip file doesn't change, but the zip file itself may
5# (e.g. due to minor changes in the compression algorithm, or changes
6# in timestamps).
7
8{
9 lib,
10 repoRevToNameMaybe,
11 fetchurl,
12 withUnzip ? true,
13 unzip,
14 glibcLocalesUtf8,
15}:
16
17{
18 url ? "",
19 urls ? [ ],
20 name ? repoRevToNameMaybe (if url != "" then url else builtins.head urls) null "unpacked",
21 nativeBuildInputs ? [ ],
22 postFetch ? "",
23 extraPostFetch ? "",
24
25 # Optionally move the contents of the unpacked tree up one level.
26 stripRoot ? true,
27 # Allows to set the extension for the intermediate downloaded
28 # file. This can be used as a hint for the unpackCmdHooks to select
29 # an appropriate unpacking tool.
30 extension ? null,
31
32 # the rest are given to fetchurl as is
33 ...
34}@args:
35
36assert
37 (extraPostFetch != "")
38 -> lib.warn "use 'postFetch' instead of 'extraPostFetch' with 'fetchzip' and 'fetchFromGitHub' or 'fetchFromGitLab'." true;
39
40let
41 tmpFilename =
42 if extension != null then
43 "download.${extension}"
44 else
45 baseNameOf (if url != "" then url else builtins.head urls);
46in
47
48fetchurl (
49 {
50 inherit name;
51 recursiveHash = true;
52
53 downloadToTemp = true;
54
55 # Have to pull in glibcLocalesUtf8 for unzip in setup-hook.sh to handle
56 # UTF-8 aware locale:
57 # https://github.com/NixOS/nixpkgs/issues/176225#issuecomment-1146617263
58 nativeBuildInputs =
59 lib.optionals withUnzip [
60 unzip
61 glibcLocalesUtf8
62 ]
63 ++ nativeBuildInputs;
64
65 postFetch = ''
66 unpackDir="$TMPDIR/unpack"
67 mkdir "$unpackDir"
68 cd "$unpackDir"
69
70 renamed="$TMPDIR/${tmpFilename}"
71 mv "$downloadedFile" "$renamed"
72 unpackFile "$renamed"
73 chmod -R +w "$unpackDir"
74 ''
75 + (
76 if stripRoot then
77 ''
78 if [ $(ls -A "$unpackDir" | wc -l) != 1 ]; then
79 echo "error: zip file must contain a single file or directory."
80 echo "hint: Pass stripRoot=false; to fetchzip to assume flat list of files."
81 exit 1
82 fi
83 fn=$(cd "$unpackDir" && ls -A)
84 if [ -f "$unpackDir/$fn" ]; then
85 mkdir $out
86 fi
87 mv "$unpackDir/$fn" "$out"
88 ''
89 else
90 ''
91 mv "$unpackDir" "$out"
92 ''
93 )
94 + ''
95 ${postFetch}
96 ${extraPostFetch}
97 chmod 755 "$out"
98 '';
99 # ^ Remove non-owner write permissions
100 # Fixes https://github.com/NixOS/nixpkgs/issues/38649
101 }
102 // removeAttrs args [
103 "stripRoot"
104 "extraPostFetch"
105 "postFetch"
106 "extension"
107 "nativeBuildInputs"
108 ]
109)