···1-{ pkgs, buildPackages, lib, stdenv, libiconv, mkNugetDeps, mkNugetSource, gixy }:
00000000002let
3 inherit (lib)
4 concatMapStringsSep
···6 escapeShellArg
7 last
8 optionalString
9- stringLength
10 strings
11 types
12 ;
···18 # Examples:
19 # writeBash = makeScriptWriter { interpreter = "${pkgs.bash}/bin/bash"; }
20 # makeScriptWriter { interpreter = "${pkgs.dash}/bin/dash"; } "hello" "echo hello world"
21- makeScriptWriter = { interpreter, check ? "" }: nameOrPath: content:
22 assert lib.or (types.path.check nameOrPath) (builtins.match "([0-9A-Za-z._])[0-9A-Za-z._-]*" nameOrPath != null);
23 assert lib.or (types.path.check content) (types.str.check content);
24 let
025 name = last (builtins.split "/" nameOrPath);
26- in
0000000000000000000000000000002728- pkgs.runCommandLocal name (
29- lib.optionalAttrs (nameOrPath == "/bin/${name}") {
30- meta.mainProgram = name;
31- }
32- // (
33- if (types.str.check content) then {
34- inherit content interpreter;
35- passAsFile = [ "content" ];
36- } else {
37- inherit interpreter;
38- contentPath = content;
39- }
40- )
41- )
42- ''
43- # On darwin a script cannot be used as an interpreter in a shebang but
44- # there doesn't seem to be a limit to the size of shebang and multiple
45- # arguments to the interpreter are allowed.
46- if [[ -n "${toString pkgs.stdenvNoCC.isDarwin}" ]] && isScript $interpreter
47- then
48- wrapperInterpreterLine=$(head -1 "$interpreter" | tail -c+3)
49- # Get first word from the line (note: xargs echo remove leading spaces)
50- wrapperInterpreter=$(echo "$wrapperInterpreterLine" | xargs echo | cut -d " " -f1)
5152- if isScript $wrapperInterpreter
53- then
54- echo "error: passed interpreter ($interpreter) is a script which has another script ($wrapperInterpreter) as an interpreter, which is not supported."
55- exit 1
56- fi
005758- # This should work as long as wrapperInterpreter is a shell, which is
59- # the case for programs wrapped with makeWrapper, like
60- # python3.withPackages etc.
61- interpreterLine="$wrapperInterpreterLine $interpreter"
62- else
63- interpreterLine=$interpreter
64- fi
6566- echo "#! $interpreterLine" > $out
67- cat "$contentPath" >> $out
68- ${optionalString (check != "") ''
69- ${check} $out
70- ''}
71- chmod +x $out
72- ${optionalString (types.path.check nameOrPath) ''
73- mv $out tmp
74- mkdir -p $out/$(dirname "${nameOrPath}")
75- mv tmp $out/${nameOrPath}
76- ''}
77- '';
000000007879 # Base implementation for compiled executables.
80 # Takes a compile script, which in turn takes the name as an argument.
81 #
82 # Examples:
83 # writeSimpleC = makeBinWriter { compileScript = name: "gcc -o $out $contentPath"; }
84- makeBinWriter = { compileScript, strip ? true }: nameOrPath: content:
85 assert lib.or (types.path.check nameOrPath) (builtins.match "([0-9A-Za-z._])[0-9A-Za-z._-]*" nameOrPath != null);
86 assert lib.or (types.path.check content) (types.str.check content);
87 let
088 name = last (builtins.split "/" nameOrPath);
00000000000000000000000000000000000089 in
90- pkgs.runCommand name ((if (types.str.check content) then {
91- inherit content;
92- passAsFile = [ "content" ];
93- } else {
94- contentPath = content;
95- }) // lib.optionalAttrs (nameOrPath == "/bin/${name}") {
96- meta.mainProgram = name;
97- }) ''
98- ${compileScript}
99- ${lib.optionalString strip
100- "${lib.getBin buildPackages.bintools-unwrapped}/bin/${buildPackages.bintools-unwrapped.targetPrefix}strip -S $out"}
101- # Sometimes binaries produced for darwin (e. g. by GHC) won't be valid
102- # mach-o executables from the get-go, but need to be corrected somehow
103- # which is done by fixupPhase.
104- ${lib.optionalString pkgs.stdenvNoCC.hostPlatform.isDarwin "fixupPhase"}
105- ${optionalString (types.path.check nameOrPath) ''
106- mv $out tmp
107- mkdir -p $out/$(dirname "${nameOrPath}")
108- mv tmp $out/${nameOrPath}
109- ''}
110- '';
111112 # Like writeScript but the first line is a shebang to bash
113 #
114- # Example:
00115 # writeBash "example" ''
116 # echo hello world
117 # ''
118- writeBash = makeScriptWriter {
119- interpreter = "${lib.getExe pkgs.bash}";
120- };
000000000000121122 # Like writeScriptBin but the first line is a shebang to bash
000000000000000000123 writeBashBin = name:
124 writeBash "/bin/${name}";
125126 # Like writeScript but the first line is a shebang to dash
127 #
128- # Example:
00129 # writeDash "example" ''
130 # echo hello world
131 # ''
132- writeDash = makeScriptWriter {
133- interpreter = "${lib.getExe pkgs.dash}";
134- };
000000000000135136 # Like writeScriptBin but the first line is a shebang to dash
000000000000000000137 writeDashBin = name:
138 writeDash "/bin/${name}";
139140 # Like writeScript but the first line is a shebang to fish
141 #
142- # Example:
00143 # writeFish "example" ''
144 # echo hello world
145 # ''
146- writeFish = makeScriptWriter {
147- interpreter = "${lib.getExe pkgs.fish} --no-config";
148- check = "${lib.getExe pkgs.fish} --no-config --no-execute"; # syntax check only
149- };
00000000000000000150151 # Like writeScriptBin but the first line is a shebang to fish
000000000000000000152 writeFishBin = name:
153 writeFish "/bin/${name}";
154···162 # main = launchMissiles
163 # '';
164 writeHaskell = name: {
165- libraries ? [],
166 ghc ? pkgs.ghc,
167 ghcArgs ? [],
000168 threadedRuntime ? true,
169- strip ? true
170 }:
171 let
172 appendIfNotSet = el: list: if elem el list then list else list ++ [ el ];
···178 ${(ghc.withPackages (_: libraries ))}/bin/ghc ${lib.escapeShellArgs ghcArgs'} tmp.hs
179 mv tmp $out
180 '';
181- inherit strip;
182 } name;
183184 # writeHaskellBin takes the same arguments as writeHaskell but outputs a directory (like writeScriptBin)
···187188 # Like writeScript but the first line is a shebang to nu
189 #
190- # Example:
00191 # writeNu "example" ''
192 # echo hello world
193 # ''
194- writeNu = makeScriptWriter {
195- interpreter = "${lib.getExe pkgs.nushell} --no-config-file";
196- };
0000000000000197198 # Like writeScriptBin but the first line is a shebang to nu
000000000000000000199 writeNuBin = name:
200 writeNu "/bin/${name}";
201202 # makeRubyWriter takes ruby and compatible rubyPackages and produces ruby script writer,
203 # If any libraries are specified, ruby.withPackages is used as interpreter, otherwise the "bare" ruby is used.
204- makeRubyWriter = ruby: rubyPackages: buildRubyPackages: name: { libraries ? [], }:
205- makeScriptWriter {
206- interpreter =
207- if libraries == []
208- then "${ruby}/bin/ruby"
209- else "${(ruby.withPackages (ps: libraries))}/bin/ruby";
210- # Rubocop doesnt seem to like running in this fashion.
211- #check = (writeDash "rubocop.sh" ''
212- # exec ${lib.getExe buildRubyPackages.rubocop} "$1"
213- #'');
214- } name;
000215216 # Like writeScript but the first line is a shebang to ruby
217 #
218 # Example:
219- # writeRuby "example" ''
220 # puts "hello world"
221 # ''
222 writeRuby = makeRubyWriter pkgs.ruby pkgs.rubyPackages buildPackages.rubyPackages;
···227 # makeLuaWriter takes lua and compatible luaPackages and produces lua script writer,
228 # which validates the script with luacheck at build time. If any libraries are specified,
229 # lua.withPackages is used as interpreter, otherwise the "bare" lua is used.
230- makeLuaWriter = lua: luaPackages: buildLuaPackages: name: { libraries ? [], }:
231- makeScriptWriter {
232- interpreter = lua.interpreter;
233- # if libraries == []
234- # then lua.interpreter
235- # else (lua.withPackages (ps: libraries)).interpreter
236- # This should support packages! I just cant figure out why some dependency collision happens whenever I try to run this.
237- check = (writeDash "luacheck.sh" ''
238- exec ${buildLuaPackages.luacheck}/bin/luacheck "$1"
239- '');
240- } name;
000241242 # writeLua takes a name an attributeset with libraries and some lua source code and
243 # returns an executable (should also work with luajit)
···265 writeLua "/bin/${name}";
266267 writeRust = name: {
268- rustc ? pkgs.rustc,
269- rustcArgs ? [],
270- strip ? true
0271 }:
272 let
273 darwinArgs = lib.optionals stdenv.isDarwin [ "-L${lib.getLib libiconv}/lib" ];
···277 cp "$contentPath" tmp.rs
278 PATH=${lib.makeBinPath [pkgs.gcc]} ${rustc}/bin/rustc ${lib.escapeShellArgs rustcArgs} ${lib.escapeShellArgs darwinArgs} -o "$out" tmp.rs
279 '';
280- inherit strip;
281 } name;
282283 writeRustBin = name:
···337 # use boolean;
338 # print "Howdy!\n" if true;
339 # ''
340- writePerl = name: { libraries ? [] }:
341- makeScriptWriter {
342- interpreter = "${lib.getExe (pkgs.perl.withPackages (p: libraries))}";
343- } name;
000344345 # writePerlBin takes the same arguments as writePerl but outputs a directory (like writeScriptBin)
346 writePerlBin = name:
···349 # makePythonWriter takes python and compatible pythonPackages and produces python script writer,
350 # which validates the script with flake8 at build time. If any libraries are specified,
351 # python.withPackages is used as interpreter, otherwise the "bare" python is used.
352- makePythonWriter = python: pythonPackages: buildPythonPackages: name: { libraries ? [], flakeIgnore ? [] }:
353 let
354 ignoreAttribute = optionalString (flakeIgnore != []) "--ignore ${concatMapStringsSep "," escapeShellArg flakeIgnore}";
355 in
356- makeScriptWriter {
357- interpreter =
358- if pythonPackages != pkgs.pypy2Packages || pythonPackages != pkgs.pypy3Packages then
359- if libraries == []
360- then python.interpreter
361- else (python.withPackages (ps: libraries)).interpreter
362- else python.interpreter
363- ;
364- check = optionalString python.isPy3k (writeDash "pythoncheck.sh" ''
365- exec ${buildPythonPackages.flake8}/bin/flake8 --show-source ${ignoreAttribute} "$1"
366- '');
367- } name;
00000368369 # writePyPy2 takes a name an attributeset with libraries and some pypy2 sourcecode and
370 # returns an executable
···421 writePyPy3 "/bin/${name}";
422423424- makeFSharpWriter = { dotnet-sdk ? pkgs.dotnet-sdk, fsi-flags ? "", libraries ? _: [] }: nameOrPath:
425 let
426 fname = last (builtins.split "/" nameOrPath);
427 path = if strings.hasSuffix ".fsx" nameOrPath then nameOrPath else "${nameOrPath}.fsx";
···442 ${lib.getExe dotnet-sdk} fsi --quiet --nologo --readline- ${fsi-flags} "$@" < "$script"
443 '';
444445- in content: makeScriptWriter {
446- interpreter = fsi;
447- } path
000448 ''
449 #i "nuget: ${nuget-source}/lib"
450 ${ content }
···456457 writeFSharpBin = name:
458 writeFSharp "/bin/${name}";
459-460}
···1+{
2+ buildPackages,
3+ gixy,
4+ lib,
5+ libiconv,
6+ makeBinaryWrapper,
7+ mkNugetDeps,
8+ mkNugetSource,
9+ pkgs,
10+ stdenv,
11+}:
12let
13 inherit (lib)
14 concatMapStringsSep
···16 escapeShellArg
17 last
18 optionalString
019 strings
20 types
21 ;
···27 # Examples:
28 # writeBash = makeScriptWriter { interpreter = "${pkgs.bash}/bin/bash"; }
29 # makeScriptWriter { interpreter = "${pkgs.dash}/bin/dash"; } "hello" "echo hello world"
30+ makeScriptWriter = { interpreter, check ? "", makeWrapperArgs ? [], }: nameOrPath: content:
31 assert lib.or (types.path.check nameOrPath) (builtins.match "([0-9A-Za-z._])[0-9A-Za-z._-]*" nameOrPath != null);
32 assert lib.or (types.path.check content) (types.str.check content);
33 let
34+ nameIsPath = types.path.check nameOrPath;
35 name = last (builtins.split "/" nameOrPath);
36+ path = if nameIsPath then nameOrPath else "/bin/${name}";
37+ # The inner derivation which creates the executable under $out/bin (never at $out directly)
38+ # This is required in order to support wrapping, as wrapped programs consist of at least two files: the executable and the wrapper.
39+ inner =
40+ pkgs.runCommandLocal name (
41+ {
42+ inherit makeWrapperArgs;
43+ nativeBuildInputs = [
44+ makeBinaryWrapper
45+ ];
46+ meta.mainProgram = name;
47+ }
48+ // (
49+ if (types.str.check content) then {
50+ inherit content interpreter;
51+ passAsFile = [ "content" ];
52+ } else {
53+ inherit interpreter;
54+ contentPath = content;
55+ }
56+ )
57+ )
58+ ''
59+ # On darwin a script cannot be used as an interpreter in a shebang but
60+ # there doesn't seem to be a limit to the size of shebang and multiple
61+ # arguments to the interpreter are allowed.
62+ if [[ -n "${toString pkgs.stdenvNoCC.isDarwin}" ]] && isScript $interpreter
63+ then
64+ wrapperInterpreterLine=$(head -1 "$interpreter" | tail -c+3)
65+ # Get first word from the line (note: xargs echo remove leading spaces)
66+ wrapperInterpreter=$(echo "$wrapperInterpreterLine" | xargs echo | cut -d " " -f1)
6768+ if isScript $wrapperInterpreter
69+ then
70+ echo "error: passed interpreter ($interpreter) is a script which has another script ($wrapperInterpreter) as an interpreter, which is not supported."
71+ exit 1
72+ fi
0000000000000000007374+ # This should work as long as wrapperInterpreter is a shell, which is
75+ # the case for programs wrapped with makeWrapper, like
76+ # python3.withPackages etc.
77+ interpreterLine="$wrapperInterpreterLine $interpreter"
78+ else
79+ interpreterLine=$interpreter
80+ fi
8182+ echo "#! $interpreterLine" > $out
83+ cat "$contentPath" >> $out
84+ ${optionalString (check != "") ''
85+ ${check} $out
86+ ''}
87+ chmod +x $out
08889+ # Relocate executable
90+ # Wrap it if makeWrapperArgs are specified
91+ mv $out tmp
92+ mkdir -p $out/$(dirname "${path}")
93+ mv tmp $out/${path}
94+ if [ -n "''${makeWrapperArgs+''${makeWrapperArgs[@]}}" ]; then
95+ wrapProgram $out/${path} ''${makeWrapperArgs[@]}
96+ fi
97+ '';
98+ in
99+ if nameIsPath
100+ then inner
101+ # In case nameOrPath is a name, the user intends the executable to be located at $out.
102+ # This is achieved by creating a separate derivation containing a symlink at $out linking to ${inner}/bin/${name}.
103+ # This breaks the override pattern.
104+ # In case this turns out to be a problem, we can still add more magic
105+ else pkgs.runCommandLocal name {} ''
106+ ln -s ${inner}/bin/${name} $out
107+ '';
108+109110 # Base implementation for compiled executables.
111 # Takes a compile script, which in turn takes the name as an argument.
112 #
113 # Examples:
114 # writeSimpleC = makeBinWriter { compileScript = name: "gcc -o $out $contentPath"; }
115+ makeBinWriter = { compileScript, strip ? true, makeWrapperArgs ? [] }: nameOrPath: content:
116 assert lib.or (types.path.check nameOrPath) (builtins.match "([0-9A-Za-z._])[0-9A-Za-z._-]*" nameOrPath != null);
117 assert lib.or (types.path.check content) (types.str.check content);
118 let
119+ nameIsPath = types.path.check nameOrPath;
120 name = last (builtins.split "/" nameOrPath);
121+ path = if nameIsPath then nameOrPath else "/bin/${name}";
122+ # The inner derivation which creates the executable under $out/bin (never at $out directly)
123+ # This is required in order to support wrapping, as wrapped programs consist of at least two files: the executable and the wrapper.
124+ inner =
125+ pkgs.runCommandLocal name (
126+ {
127+ inherit makeWrapperArgs;
128+ nativeBuildInputs = [
129+ makeBinaryWrapper
130+ ];
131+ meta.mainProgram = name;
132+ }
133+ // (
134+ if (types.str.check content) then {
135+ inherit content;
136+ passAsFile = [ "content" ];
137+ } else {
138+ contentPath = content;
139+ }
140+ )
141+ )
142+ ''
143+ ${compileScript}
144+ ${lib.optionalString strip
145+ "${lib.getBin buildPackages.bintools-unwrapped}/bin/${buildPackages.bintools-unwrapped.targetPrefix}strip -S $out"}
146+ # Sometimes binaries produced for darwin (e. g. by GHC) won't be valid
147+ # mach-o executables from the get-go, but need to be corrected somehow
148+ # which is done by fixupPhase.
149+ ${lib.optionalString pkgs.stdenvNoCC.hostPlatform.isDarwin "fixupPhase"}
150+ mv $out tmp
151+ mkdir -p $out/$(dirname "${path}")
152+ mv tmp $out/${path}
153+ if [ -n "''${makeWrapperArgs+''${makeWrapperArgs[@]}}" ]; then
154+ wrapProgram $out/${path} ''${makeWrapperArgs[@]}
155+ fi
156+ '';
157 in
158+ if nameIsPath
159+ then inner
160+ # In case nameOrPath is a name, the user intends the executable to be located at $out.
161+ # This is achieved by creating a separate derivation containing a symlink at $out linking to ${inner}/bin/${name}.
162+ # This breaks the override pattern.
163+ # In case this turns out to be a problem, we can still add more magic
164+ else pkgs.runCommandLocal name {} ''
165+ ln -s ${inner}/bin/${name} $out
166+ '';
000000000000167168 # Like writeScript but the first line is a shebang to bash
169 #
170+ # Can be called with or without extra arguments.
171+ #
172+ # Example without arguments:
173 # writeBash "example" ''
174 # echo hello world
175 # ''
176+ #
177+ # Example with arguments:
178+ # writeBash "example"
179+ # {
180+ # makeWrapperArgs = [
181+ # "--prefix" "PATH" ":" "${pkgs.hello}/bin"
182+ # ];
183+ # }
184+ # ''
185+ # hello
186+ # ''
187+ writeBash = name: argsOrScript:
188+ if lib.isAttrs argsOrScript && ! lib.isDerivation argsOrScript
189+ then makeScriptWriter (argsOrScript // { interpreter = "${lib.getExe pkgs.bash}"; }) name
190+ else makeScriptWriter { interpreter = "${lib.getExe pkgs.bash}"; } name argsOrScript;
191192 # Like writeScriptBin but the first line is a shebang to bash
193+ #
194+ # Can be called with or without extra arguments.
195+ #
196+ # Example without arguments:
197+ # writeBashBin "example" ''
198+ # echo hello world
199+ # ''
200+ #
201+ # Example with arguments:
202+ # writeBashBin "example"
203+ # {
204+ # makeWrapperArgs = [
205+ # "--prefix", "PATH", ":", "${pkgs.hello}/bin",
206+ # ];
207+ # }
208+ # ''
209+ # hello
210+ # ''
211 writeBashBin = name:
212 writeBash "/bin/${name}";
213214 # Like writeScript but the first line is a shebang to dash
215 #
216+ # Can be called with or without extra arguments.
217+ #
218+ # Example without arguments:
219 # writeDash "example" ''
220 # echo hello world
221 # ''
222+ #
223+ # Example with arguments:
224+ # writeDash "example"
225+ # {
226+ # makeWrapperArgs = [
227+ # "--prefix", "PATH", ":", "${pkgs.hello}/bin",
228+ # ];
229+ # }
230+ # ''
231+ # hello
232+ # ''
233+ writeDash = name: argsOrScript:
234+ if lib.isAttrs argsOrScript && ! lib.isDerivation argsOrScript
235+ then makeScriptWriter (argsOrScript // { interpreter = "${lib.getExe pkgs.dash}"; }) name
236+ else makeScriptWriter { interpreter = "${lib.getExe pkgs.dash}"; } name argsOrScript;
237238 # Like writeScriptBin but the first line is a shebang to dash
239+ #
240+ # Can be called with or without extra arguments.
241+ #
242+ # Example without arguments:
243+ # writeDashBin "example" ''
244+ # echo hello world
245+ # ''
246+ #
247+ # Example with arguments:
248+ # writeDashBin "example"
249+ # {
250+ # makeWrapperArgs = [
251+ # "--prefix", "PATH", ":", "${pkgs.hello}/bin",
252+ # ];
253+ # }
254+ # ''
255+ # hello
256+ # ''
257 writeDashBin = name:
258 writeDash "/bin/${name}";
259260 # Like writeScript but the first line is a shebang to fish
261 #
262+ # Can be called with or without extra arguments.
263+ #
264+ # Example without arguments:
265 # writeFish "example" ''
266 # echo hello world
267 # ''
268+ #
269+ # Example with arguments:
270+ # writeFish "example"
271+ # {
272+ # makeWrapperArgs = [
273+ # "--prefix", "PATH", ":", "${pkgs.hello}/bin",
274+ # ];
275+ # }
276+ # ''
277+ # hello
278+ # ''
279+ writeFish = name: argsOrScript:
280+ if lib.isAttrs argsOrScript && ! lib.isDerivation argsOrScript
281+ then makeScriptWriter (argsOrScript // {
282+ interpreter = "${lib.getExe pkgs.fish} --no-config";
283+ check = "${lib.getExe pkgs.fish} --no-config --no-execute"; # syntax check only
284+ }) name
285+ else makeScriptWriter {
286+ interpreter = "${lib.getExe pkgs.fish} --no-config";
287+ check = "${lib.getExe pkgs.fish} --no-config --no-execute"; # syntax check only
288+ } name argsOrScript;
289290 # Like writeScriptBin but the first line is a shebang to fish
291+ #
292+ # Can be called with or without extra arguments.
293+ #
294+ # Example without arguments:
295+ # writeFishBin "example" ''
296+ # echo hello world
297+ # ''
298+ #
299+ # Example with arguments:
300+ # writeFishBin "example"
301+ # {
302+ # makeWrapperArgs = [
303+ # "--prefix", "PATH", ":", "${pkgs.hello}/bin",
304+ # ];
305+ # }
306+ # ''
307+ # hello
308+ # ''
309 writeFishBin = name:
310 writeFish "/bin/${name}";
311···319 # main = launchMissiles
320 # '';
321 writeHaskell = name: {
0322 ghc ? pkgs.ghc,
323 ghcArgs ? [],
324+ libraries ? [],
325+ makeWrapperArgs ? [],
326+ strip ? true,
327 threadedRuntime ? true,
0328 }:
329 let
330 appendIfNotSet = el: list: if elem el list then list else list ++ [ el ];
···336 ${(ghc.withPackages (_: libraries ))}/bin/ghc ${lib.escapeShellArgs ghcArgs'} tmp.hs
337 mv tmp $out
338 '';
339+ inherit makeWrapperArgs strip;
340 } name;
341342 # writeHaskellBin takes the same arguments as writeHaskell but outputs a directory (like writeScriptBin)
···345346 # Like writeScript but the first line is a shebang to nu
347 #
348+ # Can be called with or without extra arguments.
349+ #
350+ # Example without arguments:
351 # writeNu "example" ''
352 # echo hello world
353 # ''
354+ #
355+ # Example with arguments:
356+ # writeNu "example"
357+ # {
358+ # makeWrapperArgs = [
359+ # "--prefix", "PATH", ":", "${pkgs.hello}/bin",
360+ # ];
361+ # }
362+ # ''
363+ # hello
364+ # ''
365+ writeNu = name: argsOrScript:
366+ if lib.isAttrs argsOrScript && ! lib.isDerivation argsOrScript
367+ then makeScriptWriter (argsOrScript // { interpreter = "${lib.getExe pkgs.nushell} --no-config-file"; }) name
368+ else makeScriptWriter { interpreter = "${lib.getExe pkgs.nushell} --no-config-file"; } name argsOrScript;
369+370371 # Like writeScriptBin but the first line is a shebang to nu
372+ #
373+ # Can be called with or without extra arguments.
374+ #
375+ # Example without arguments:
376+ # writeNuBin "example" ''
377+ # echo hello world
378+ # ''
379+ #
380+ # Example with arguments:
381+ # writeNuBin "example"
382+ # {
383+ # makeWrapperArgs = [
384+ # "--prefix", "PATH", ":", "${pkgs.hello}/bin",
385+ # ];
386+ # }
387+ # ''
388+ # hello
389+ # ''
390 writeNuBin = name:
391 writeNu "/bin/${name}";
392393 # makeRubyWriter takes ruby and compatible rubyPackages and produces ruby script writer,
394 # If any libraries are specified, ruby.withPackages is used as interpreter, otherwise the "bare" ruby is used.
395+ makeRubyWriter = ruby: rubyPackages: buildRubyPackages: name: { libraries ? [], ... } @ args:
396+ makeScriptWriter (
397+ (builtins.removeAttrs args ["libraries"])
398+ // {
399+ interpreter =
400+ if libraries == []
401+ then "${ruby}/bin/ruby"
402+ else "${(ruby.withPackages (ps: libraries))}/bin/ruby";
403+ # Rubocop doesn't seem to like running in this fashion.
404+ #check = (writeDash "rubocop.sh" ''
405+ # exec ${lib.getExe buildRubyPackages.rubocop} "$1"
406+ #'');
407+ }
408+ ) name;
409410 # Like writeScript but the first line is a shebang to ruby
411 #
412 # Example:
413+ # writeRuby "example" { libraries = [ pkgs.rubyPackages.git ]; } ''
414 # puts "hello world"
415 # ''
416 writeRuby = makeRubyWriter pkgs.ruby pkgs.rubyPackages buildPackages.rubyPackages;
···421 # makeLuaWriter takes lua and compatible luaPackages and produces lua script writer,
422 # which validates the script with luacheck at build time. If any libraries are specified,
423 # lua.withPackages is used as interpreter, otherwise the "bare" lua is used.
424+ makeLuaWriter = lua: luaPackages: buildLuaPackages: name: { libraries ? [], ... } @ args:
425+ makeScriptWriter (
426+ (builtins.removeAttrs args ["libraries"])
427+ // {
428+ interpreter = lua.interpreter;
429+ # if libraries == []
430+ # then lua.interpreter
431+ # else (lua.withPackages (ps: libraries)).interpreter
432+ # This should support packages! I just cant figure out why some dependency collision happens whenever I try to run this.
433+ check = (writeDash "luacheck.sh" ''
434+ exec ${buildLuaPackages.luacheck}/bin/luacheck "$1"
435+ '');
436+ }
437+ ) name;
438439 # writeLua takes a name an attributeset with libraries and some lua source code and
440 # returns an executable (should also work with luajit)
···462 writeLua "/bin/${name}";
463464 writeRust = name: {
465+ makeWrapperArgs ? [],
466+ rustc ? pkgs.rustc,
467+ rustcArgs ? [],
468+ strip ? true,
469 }:
470 let
471 darwinArgs = lib.optionals stdenv.isDarwin [ "-L${lib.getLib libiconv}/lib" ];
···475 cp "$contentPath" tmp.rs
476 PATH=${lib.makeBinPath [pkgs.gcc]} ${rustc}/bin/rustc ${lib.escapeShellArgs rustcArgs} ${lib.escapeShellArgs darwinArgs} -o "$out" tmp.rs
477 '';
478+ inherit makeWrapperArgs strip;
479 } name;
480481 writeRustBin = name:
···535 # use boolean;
536 # print "Howdy!\n" if true;
537 # ''
538+ writePerl = name: { libraries ? [], ... } @ args:
539+ makeScriptWriter (
540+ (builtins.removeAttrs args ["libraries"])
541+ // {
542+ interpreter = "${lib.getExe (pkgs.perl.withPackages (p: libraries))}";
543+ }
544+ ) name;
545546 # writePerlBin takes the same arguments as writePerl but outputs a directory (like writeScriptBin)
547 writePerlBin = name:
···550 # makePythonWriter takes python and compatible pythonPackages and produces python script writer,
551 # which validates the script with flake8 at build time. If any libraries are specified,
552 # python.withPackages is used as interpreter, otherwise the "bare" python is used.
553+ makePythonWriter = python: pythonPackages: buildPythonPackages: name: { libraries ? [], flakeIgnore ? [], ... } @ args:
554 let
555 ignoreAttribute = optionalString (flakeIgnore != []) "--ignore ${concatMapStringsSep "," escapeShellArg flakeIgnore}";
556 in
557+ makeScriptWriter
558+ (
559+ (builtins.removeAttrs args ["libraries" "flakeIgnore"])
560+ // {
561+ interpreter =
562+ if pythonPackages != pkgs.pypy2Packages || pythonPackages != pkgs.pypy3Packages then
563+ if libraries == []
564+ then python.interpreter
565+ else (python.withPackages (ps: libraries)).interpreter
566+ else python.interpreter
567+ ;
568+ check = optionalString python.isPy3k (writeDash "pythoncheck.sh" ''
569+ exec ${buildPythonPackages.flake8}/bin/flake8 --show-source ${ignoreAttribute} "$1"
570+ '');
571+ }
572+ )
573+ name;
574575 # writePyPy2 takes a name an attributeset with libraries and some pypy2 sourcecode and
576 # returns an executable
···627 writePyPy3 "/bin/${name}";
628629630+ makeFSharpWriter = { dotnet-sdk ? pkgs.dotnet-sdk, fsi-flags ? "", libraries ? _: [], ... } @ args: nameOrPath:
631 let
632 fname = last (builtins.split "/" nameOrPath);
633 path = if strings.hasSuffix ".fsx" nameOrPath then nameOrPath else "${nameOrPath}.fsx";
···648 ${lib.getExe dotnet-sdk} fsi --quiet --nologo --readline- ${fsi-flags} "$@" < "$script"
649 '';
650651+ in content: makeScriptWriter (
652+ (builtins.removeAttrs args ["dotnet-sdk" "fsi-flags" "libraries"])
653+ // {
654+ interpreter = fsi;
655+ }
656+ ) path
657 ''
658 #i "nuget: ${nuget-source}/lib"
659 ${ content }
···665666 writeFSharpBin = name:
667 writeFSharp "/bin/${name}";
0668}