nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1# This setup hook modifies a Perl script so that any "-I" flags in its shebang
2# line are rewritten into a "use lib ..." statement on the next line. This gets
3# around a limitation in Darwin, which will not properly handle a script whose
4# shebang line exceeds 511 characters.
5#
6# Each occurrence of "-I /path/to/lib1" or "-I/path/to/lib2" is removed from
7# the shebang line, along with the single space that preceded it. These library
8# paths are placed into a new line of the form
9#
10# use lib "/path/to/lib1", "/path/to/lib2";
11#
12# immediately following the shebang line. If a library appeared in the original
13# list more than once, only its first occurrence will appear in the output
14# list. In other words, the libraries are deduplicated, but the ordering of the
15# first appearance of each one is preserved.
16#
17# Any flags other than "-I" in the shebang line are left as-is, and the
18# interpreter is also left alone (although the script will abort if the
19# interpreter does not seem to be either "perl" or else "env" with "perl" as
20# its argument). Each line after the shebang line is left unchanged. Each file
21# is modified in place.
22#
23# Usage:
24# shortenPerlShebang SCRIPT...
25
26shortenPerlShebang() {
27 while [ $# -gt 0 ]; do
28 _shortenPerlShebang "$1"
29 shift
30 done
31}
32
33_shortenPerlShebang() {
34 local program="$1"
35
36 echo "shortenPerlShebang: rewriting shebang line in $program"
37
38 if ! isScript "$program"; then
39 die "shortenPerlShebang: refusing to modify $program because it is not a script"
40 fi
41
42 local temp="$(mktemp)"
43
44 gawk '
45 (NR == 1) {
46 if (!($0 ~ /\/(perl|env +perl)\>/)) {
47 print "shortenPerlShebang: script does not seem to be a Perl script" > "/dev/stderr"
48 exit 1
49 }
50 idx = 0
51 while (match($0, / -I ?([^ ]+)/, pieces)) {
52 matches[idx] = pieces[1]
53 idx++
54 $0 = gensub(/ -I ?[^ ]+/, "", 1, $0)
55 }
56 print $0
57 if (idx > 0) {
58 prefix = "use lib "
59 for (idx in matches) {
60 path = matches[idx]
61 if (!(path in seen)) {
62 printf "%s\"%s\"", prefix, path
63 seen[path] = 1
64 prefix = ", "
65 }
66 }
67 print ";"
68 }
69 }
70 (NR > 1 ) {
71 print
72 }
73 ' "$program" > "$temp" || die
74 # Preserve the mode of the original file
75 cp --preserve=mode --attributes-only "$program" "$temp"
76 mv "$temp" "$program"
77
78 # Measure the new shebang line length and make sure it's okay. We subtract
79 # one to account for the trailing newline that "head" included in its
80 # output.
81 local new_length=$(( $(head -n 1 "$program" | wc -c) - 1 ))
82
83 # Darwin is okay when the shebang line contains 511 characters, but not
84 # when it contains 512 characters.
85 if [ $new_length -ge 512 ]; then
86 die "shortenPerlShebang: shebang line is $new_length characters--still too long for Darwin!"
87 fi
88}