Loading pkgs/build-support/writers/scripts.nix +145 −353 Original line number Diff line number Diff line { buildPackages, gixy, lib, libiconv, makeBinaryWrapper, mkNugetDeps, mkNugetSource, pkgs, stdenv, }: { pkgs, buildPackages, lib, stdenv, libiconv, mkNugetDeps, mkNugetSource, gixy }: let inherit (lib) concatMapStringsSep Loading @@ -16,6 +6,7 @@ let escapeShellArg last optionalString stringLength strings types ; Loading @@ -27,22 +18,15 @@ rec { # Examples: # writeBash = makeScriptWriter { interpreter = "${pkgs.bash}/bin/bash"; } # makeScriptWriter { interpreter = "${pkgs.dash}/bin/dash"; } "hello" "echo hello world" makeScriptWriter = { interpreter, check ? "", makeWrapperArgs ? [], }: nameOrPath: content: makeScriptWriter = { interpreter, check ? "" }: nameOrPath: content: assert lib.or (types.path.check nameOrPath) (builtins.match "([0-9A-Za-z._])[0-9A-Za-z._-]*" nameOrPath != null); assert lib.or (types.path.check content) (types.str.check content); let nameIsPath = types.path.check nameOrPath; name = last (builtins.split "/" nameOrPath); path = if nameIsPath then nameOrPath else "/bin/${name}"; # The inner derivation which creates the executable under $out/bin (never at $out directly) # This is required in order to support wrapping, as wrapped programs consist of at least two files: the executable and the wrapper. inner = in pkgs.runCommandLocal name ( { inherit makeWrapperArgs; nativeBuildInputs = [ makeBinaryWrapper ]; lib.optionalAttrs (nameOrPath == "/bin/${name}") { meta.mainProgram = name; } // ( Loading Loading @@ -85,61 +69,32 @@ rec { ${check} $out ''} chmod +x $out # Relocate executable # Wrap it if makeWrapperArgs are specified ${optionalString (types.path.check nameOrPath) '' mv $out tmp mkdir -p $out/$(dirname "${path}") mv tmp $out/${path} if [ -n "''${makeWrapperArgs+''${makeWrapperArgs[@]}}" ]; then wrapProgram $out/${path} ''${makeWrapperArgs[@]} fi ''; in if nameIsPath then inner # In case nameOrPath is a name, the user intends the executable to be located at $out. # This is achieved by creating a separate derivation containing a symlink at $out linking to ${inner}/bin/${name}. # This breaks the override pattern. # In case this turns out to be a problem, we can still add more magic else pkgs.runCommandLocal name {} '' ln -s ${inner}/bin/${name} $out mkdir -p $out/$(dirname "${nameOrPath}") mv tmp $out/${nameOrPath} ''} ''; # Base implementation for compiled executables. # Takes a compile script, which in turn takes the name as an argument. # # Examples: # writeSimpleC = makeBinWriter { compileScript = name: "gcc -o $out $contentPath"; } makeBinWriter = { compileScript, strip ? true, makeWrapperArgs ? [] }: nameOrPath: content: makeBinWriter = { compileScript, strip ? true }: nameOrPath: content: assert lib.or (types.path.check nameOrPath) (builtins.match "([0-9A-Za-z._])[0-9A-Za-z._-]*" nameOrPath != null); assert lib.or (types.path.check content) (types.str.check content); let nameIsPath = types.path.check nameOrPath; name = last (builtins.split "/" nameOrPath); path = if nameIsPath then nameOrPath else "/bin/${name}"; # The inner derivation which creates the executable under $out/bin (never at $out directly) # This is required in order to support wrapping, as wrapped programs consist of at least two files: the executable and the wrapper. inner = pkgs.runCommandLocal name ( { inherit makeWrapperArgs; nativeBuildInputs = [ makeBinaryWrapper ]; meta.mainProgram = name; } // ( if (types.str.check content) then { in pkgs.runCommand name ((if (types.str.check content) then { inherit content; passAsFile = [ "content" ]; } else { contentPath = content; } ) ) '' }) // lib.optionalAttrs (nameOrPath == "/bin/${name}") { meta.mainProgram = name; }) '' ${compileScript} ${lib.optionalString strip "${lib.getBin buildPackages.bintools-unwrapped}/bin/${buildPackages.bintools-unwrapped.targetPrefix}strip -S $out"} Loading @@ -147,165 +102,53 @@ rec { # mach-o executables from the get-go, but need to be corrected somehow # which is done by fixupPhase. ${lib.optionalString pkgs.stdenvNoCC.hostPlatform.isDarwin "fixupPhase"} ${optionalString (types.path.check nameOrPath) '' mv $out tmp mkdir -p $out/$(dirname "${path}") mv tmp $out/${path} if [ -n "''${makeWrapperArgs+''${makeWrapperArgs[@]}}" ]; then wrapProgram $out/${path} ''${makeWrapperArgs[@]} fi ''; in if nameIsPath then inner # In case nameOrPath is a name, the user intends the executable to be located at $out. # This is achieved by creating a separate derivation containing a symlink at $out linking to ${inner}/bin/${name}. # This breaks the override pattern. # In case this turns out to be a problem, we can still add more magic else pkgs.runCommandLocal name {} '' ln -s ${inner}/bin/${name} $out mkdir -p $out/$(dirname "${nameOrPath}") mv tmp $out/${nameOrPath} ''} ''; # Like writeScript but the first line is a shebang to bash # # Can be called with or without extra arguments. # # Example without arguments: # Example: # writeBash "example" '' # echo hello world # '' # # Example with arguments: # writeBash "example" # { # makeWrapperArgs = [ # "--prefix" "PATH" ":" "${pkgs.hello}/bin" # ]; # } # '' # hello # '' writeBash = name: argsOrScript: if lib.isAttrs argsOrScript && ! lib.isDerivation argsOrScript then makeScriptWriter (argsOrScript // { interpreter = "${lib.getExe pkgs.bash}"; }) name else makeScriptWriter { interpreter = "${lib.getExe pkgs.bash}"; } name argsOrScript; writeBash = makeScriptWriter { interpreter = "${lib.getExe pkgs.bash}"; }; # Like writeScriptBin but the first line is a shebang to bash # # Can be called with or without extra arguments. # # Example without arguments: # writeBashBin "example" '' # echo hello world # '' # # Example with arguments: # writeBashBin "example" # { # makeWrapperArgs = [ # "--prefix", "PATH", ":", "${pkgs.hello}/bin", # ]; # } # '' # hello # '' writeBashBin = name: writeBash "/bin/${name}"; # Like writeScript but the first line is a shebang to dash # # Can be called with or without extra arguments. # # Example without arguments: # Example: # writeDash "example" '' # echo hello world # '' # # Example with arguments: # writeDash "example" # { # makeWrapperArgs = [ # "--prefix", "PATH", ":", "${pkgs.hello}/bin", # ]; # } # '' # hello # '' writeDash = name: argsOrScript: if lib.isAttrs argsOrScript && ! lib.isDerivation argsOrScript then makeScriptWriter (argsOrScript // { interpreter = "${lib.getExe pkgs.dash}"; }) name else makeScriptWriter { interpreter = "${lib.getExe pkgs.dash}"; } name argsOrScript; writeDash = makeScriptWriter { interpreter = "${lib.getExe pkgs.dash}"; }; # Like writeScriptBin but the first line is a shebang to dash # # Can be called with or without extra arguments. # # Example without arguments: # writeDashBin "example" '' # echo hello world # '' # # Example with arguments: # writeDashBin "example" # { # makeWrapperArgs = [ # "--prefix", "PATH", ":", "${pkgs.hello}/bin", # ]; # } # '' # hello # '' writeDashBin = name: writeDash "/bin/${name}"; # Like writeScript but the first line is a shebang to fish # # Can be called with or without extra arguments. # # Example without arguments: # Example: # writeFish "example" '' # echo hello world # '' # # Example with arguments: # writeFish "example" # { # makeWrapperArgs = [ # "--prefix", "PATH", ":", "${pkgs.hello}/bin", # ]; # } # '' # hello # '' writeFish = name: argsOrScript: if lib.isAttrs argsOrScript && ! lib.isDerivation argsOrScript then makeScriptWriter (argsOrScript // { interpreter = "${lib.getExe pkgs.fish} --no-config"; check = "${lib.getExe pkgs.fish} --no-config --no-execute"; # syntax check only }) name else makeScriptWriter { writeFish = makeScriptWriter { interpreter = "${lib.getExe pkgs.fish} --no-config"; check = "${lib.getExe pkgs.fish} --no-config --no-execute"; # syntax check only } name argsOrScript; }; # Like writeScriptBin but the first line is a shebang to fish # # Can be called with or without extra arguments. # # Example without arguments: # writeFishBin "example" '' # echo hello world # '' # # Example with arguments: # writeFishBin "example" # { # makeWrapperArgs = [ # "--prefix", "PATH", ":", "${pkgs.hello}/bin", # ]; # } # '' # hello # '' writeFishBin = name: writeFish "/bin/${name}"; Loading @@ -319,12 +162,11 @@ rec { # main = launchMissiles # ''; writeHaskell = name: { libraries ? [], ghc ? pkgs.ghc, ghcArgs ? [], libraries ? [], makeWrapperArgs ? [], strip ? true, threadedRuntime ? true, strip ? true }: let appendIfNotSet = el: list: if elem el list then list else list ++ [ el ]; Loading @@ -336,7 +178,7 @@ rec { ${(ghc.withPackages (_: libraries ))}/bin/ghc ${lib.escapeShellArgs ghcArgs'} tmp.hs mv tmp $out ''; inherit makeWrapperArgs strip; inherit strip; } name; # writeHaskellBin takes the same arguments as writeHaskell but outputs a directory (like writeScriptBin) Loading @@ -345,72 +187,36 @@ rec { # Like writeScript but the first line is a shebang to nu # # Can be called with or without extra arguments. # # Example without arguments: # Example: # writeNu "example" '' # echo hello world # '' # # Example with arguments: # writeNu "example" # { # makeWrapperArgs = [ # "--prefix", "PATH", ":", "${pkgs.hello}/bin", # ]; # } # '' # hello # '' writeNu = name: argsOrScript: if lib.isAttrs argsOrScript && ! lib.isDerivation argsOrScript then makeScriptWriter (argsOrScript // { interpreter = "${lib.getExe pkgs.nushell} --no-config-file"; }) name else makeScriptWriter { interpreter = "${lib.getExe pkgs.nushell} --no-config-file"; } name argsOrScript; writeNu = makeScriptWriter { interpreter = "${lib.getExe pkgs.nushell} --no-config-file"; }; # Like writeScriptBin but the first line is a shebang to nu # # Can be called with or without extra arguments. # # Example without arguments: # writeNuBin "example" '' # echo hello world # '' # # Example with arguments: # writeNuBin "example" # { # makeWrapperArgs = [ # "--prefix", "PATH", ":", "${pkgs.hello}/bin", # ]; # } # '' # hello # '' writeNuBin = name: writeNu "/bin/${name}"; # makeRubyWriter takes ruby and compatible rubyPackages and produces ruby script writer, # If any libraries are specified, ruby.withPackages is used as interpreter, otherwise the "bare" ruby is used. makeRubyWriter = ruby: rubyPackages: buildRubyPackages: name: { libraries ? [], ... } @ args: makeScriptWriter ( (builtins.removeAttrs args ["libraries"]) // { makeRubyWriter = ruby: rubyPackages: buildRubyPackages: name: { libraries ? [], }: makeScriptWriter { interpreter = if libraries == [] then "${ruby}/bin/ruby" else "${(ruby.withPackages (ps: libraries))}/bin/ruby"; # Rubocop doesn't seem to like running in this fashion. # Rubocop doesnt seem to like running in this fashion. #check = (writeDash "rubocop.sh" '' # exec ${lib.getExe buildRubyPackages.rubocop} "$1" #''); } ) name; } name; # Like writeScript but the first line is a shebang to ruby # # Example: # writeRuby "example" { libraries = [ pkgs.rubyPackages.git ]; } '' # writeRuby "example" '' # puts "hello world" # '' writeRuby = makeRubyWriter pkgs.ruby pkgs.rubyPackages buildPackages.rubyPackages; Loading @@ -421,10 +227,8 @@ rec { # makeLuaWriter takes lua and compatible luaPackages and produces lua script writer, # which validates the script with luacheck at build time. If any libraries are specified, # lua.withPackages is used as interpreter, otherwise the "bare" lua is used. makeLuaWriter = lua: luaPackages: buildLuaPackages: name: { libraries ? [], ... } @ args: makeScriptWriter ( (builtins.removeAttrs args ["libraries"]) // { makeLuaWriter = lua: luaPackages: buildLuaPackages: name: { libraries ? [], }: makeScriptWriter { interpreter = lua.interpreter; # if libraries == [] # then lua.interpreter Loading @@ -433,8 +237,7 @@ rec { check = (writeDash "luacheck.sh" '' exec ${buildLuaPackages.luacheck}/bin/luacheck "$1" ''); } ) name; } name; # writeLua takes a name an attributeset with libraries and some lua source code and # returns an executable (should also work with luajit) Loading Loading @@ -462,10 +265,9 @@ rec { writeLua "/bin/${name}"; writeRust = name: { makeWrapperArgs ? [], rustc ? pkgs.rustc, rustcArgs ? [], strip ? true, strip ? true }: let darwinArgs = lib.optionals stdenv.isDarwin [ "-L${lib.getLib libiconv}/lib" ]; Loading @@ -475,7 +277,7 @@ rec { cp "$contentPath" tmp.rs PATH=${lib.makeBinPath [pkgs.gcc]} ${rustc}/bin/rustc ${lib.escapeShellArgs rustcArgs} ${lib.escapeShellArgs darwinArgs} -o "$out" tmp.rs ''; inherit makeWrapperArgs strip; inherit strip; } name; writeRustBin = name: Loading Loading @@ -535,13 +337,10 @@ rec { # use boolean; # print "Howdy!\n" if true; # '' writePerl = name: { libraries ? [], ... } @ args: makeScriptWriter ( (builtins.removeAttrs args ["libraries"]) // { writePerl = name: { libraries ? [] }: makeScriptWriter { interpreter = "${lib.getExe (pkgs.perl.withPackages (p: libraries))}"; } ) name; } name; # writePerlBin takes the same arguments as writePerl but outputs a directory (like writeScriptBin) writePerlBin = name: Loading @@ -550,14 +349,11 @@ rec { # makePythonWriter takes python and compatible pythonPackages and produces python script writer, # which validates the script with flake8 at build time. If any libraries are specified, # python.withPackages is used as interpreter, otherwise the "bare" python is used. makePythonWriter = python: pythonPackages: buildPythonPackages: name: { libraries ? [], flakeIgnore ? [], ... } @ args: makePythonWriter = python: pythonPackages: buildPythonPackages: name: { libraries ? [], flakeIgnore ? [] }: let ignoreAttribute = optionalString (flakeIgnore != []) "--ignore ${concatMapStringsSep "," escapeShellArg flakeIgnore}"; in makeScriptWriter ( (builtins.removeAttrs args ["libraries" "flakeIgnore"]) // { makeScriptWriter { interpreter = if pythonPackages != pkgs.pypy2Packages || pythonPackages != pkgs.pypy3Packages then if libraries == [] Loading @@ -568,9 +364,7 @@ rec { check = optionalString python.isPy3k (writeDash "pythoncheck.sh" '' exec ${buildPythonPackages.flake8}/bin/flake8 --show-source ${ignoreAttribute} "$1" ''); } ) name; } name; # writePyPy2 takes a name an attributeset with libraries and some pypy2 sourcecode and # returns an executable Loading Loading @@ -627,7 +421,7 @@ rec { writePyPy3 "/bin/${name}"; makeFSharpWriter = { dotnet-sdk ? pkgs.dotnet-sdk, fsi-flags ? "", libraries ? _: [], ... } @ args: nameOrPath: makeFSharpWriter = { dotnet-sdk ? pkgs.dotnet-sdk, fsi-flags ? "", libraries ? _: [] }: nameOrPath: let fname = last (builtins.split "/" nameOrPath); path = if strings.hasSuffix ".fsx" nameOrPath then nameOrPath else "${nameOrPath}.fsx"; Loading @@ -648,12 +442,9 @@ rec { ${lib.getExe dotnet-sdk} fsi --quiet --nologo --readline- ${fsi-flags} "$@" < "$script" ''; in content: makeScriptWriter ( (builtins.removeAttrs args ["dotnet-sdk" "fsi-flags" "libraries"]) // { in content: makeScriptWriter { interpreter = fsi; } ) path } path '' #i "nuget: ${nuget-source}/lib" ${ content } Loading @@ -665,4 +456,5 @@ rec { writeFSharpBin = name: writeFSharp "/bin/${name}"; } pkgs/build-support/writers/test.nix +6 −82 Original line number Diff line number Diff line { haskellPackages { glib , haskellPackages , lib , nodePackages , perlPackages , pypy2Packages , python3Packages , pypy3Packages , luaPackages , rubyPackages , runCommand , testers , writers Loading Loading @@ -305,85 +310,4 @@ lib.recurseIntoAttrs { expected = "hello: world\n"; }; }; wrapping = lib.recurseIntoAttrs { bash-bin = expectSuccessBin ( writeBashBin "test-writers-wrapping-bash-bin" { makeWrapperArgs = [ "--set" "ThaigerSprint" "Thailand" ]; } '' if [[ "$ThaigerSprint" == "Thailand" ]]; then echo "success" fi '' ); bash = expectSuccess ( writeBash "test-writers-wrapping-bash" { makeWrapperArgs = [ "--set" "ThaigerSprint" "Thailand" ]; } '' if [[ "$ThaigerSprint" == "Thailand" ]]; then echo "success" fi '' ); python = expectSuccess ( writePython3 "test-writers-wrapping-python" { makeWrapperArgs = [ "--set" "ThaigerSprint" "Thailand" ]; } '' import os if os.environ.get("ThaigerSprint") == "Thailand": print("success") '' ); rust = expectSuccess ( writeRust "test-writers-wrapping-rust" { makeWrapperArgs = [ "--set" "ThaigerSprint" "Thailand" ]; } '' fn main(){ if std::env::var("ThaigerSprint").unwrap() == "Thailand" { println!("success") } } '' ); no-empty-wrapper = let bin = writeBashBin "bin" { makeWrapperArgs = []; } ''true''; in runCommand "run-test-writers-wrapping-no-empty-wrapper" {} '' ls -A ${bin}/bin if [ $(ls -A ${bin}/bin | wc -l) -eq 1 ]; then touch $out else echo "Error: Empty wrapper was created" >&2 exit 1 fi ''; }; } Loading
pkgs/build-support/writers/scripts.nix +145 −353 Original line number Diff line number Diff line { buildPackages, gixy, lib, libiconv, makeBinaryWrapper, mkNugetDeps, mkNugetSource, pkgs, stdenv, }: { pkgs, buildPackages, lib, stdenv, libiconv, mkNugetDeps, mkNugetSource, gixy }: let inherit (lib) concatMapStringsSep Loading @@ -16,6 +6,7 @@ let escapeShellArg last optionalString stringLength strings types ; Loading @@ -27,22 +18,15 @@ rec { # Examples: # writeBash = makeScriptWriter { interpreter = "${pkgs.bash}/bin/bash"; } # makeScriptWriter { interpreter = "${pkgs.dash}/bin/dash"; } "hello" "echo hello world" makeScriptWriter = { interpreter, check ? "", makeWrapperArgs ? [], }: nameOrPath: content: makeScriptWriter = { interpreter, check ? "" }: nameOrPath: content: assert lib.or (types.path.check nameOrPath) (builtins.match "([0-9A-Za-z._])[0-9A-Za-z._-]*" nameOrPath != null); assert lib.or (types.path.check content) (types.str.check content); let nameIsPath = types.path.check nameOrPath; name = last (builtins.split "/" nameOrPath); path = if nameIsPath then nameOrPath else "/bin/${name}"; # The inner derivation which creates the executable under $out/bin (never at $out directly) # This is required in order to support wrapping, as wrapped programs consist of at least two files: the executable and the wrapper. inner = in pkgs.runCommandLocal name ( { inherit makeWrapperArgs; nativeBuildInputs = [ makeBinaryWrapper ]; lib.optionalAttrs (nameOrPath == "/bin/${name}") { meta.mainProgram = name; } // ( Loading Loading @@ -85,61 +69,32 @@ rec { ${check} $out ''} chmod +x $out # Relocate executable # Wrap it if makeWrapperArgs are specified ${optionalString (types.path.check nameOrPath) '' mv $out tmp mkdir -p $out/$(dirname "${path}") mv tmp $out/${path} if [ -n "''${makeWrapperArgs+''${makeWrapperArgs[@]}}" ]; then wrapProgram $out/${path} ''${makeWrapperArgs[@]} fi ''; in if nameIsPath then inner # In case nameOrPath is a name, the user intends the executable to be located at $out. # This is achieved by creating a separate derivation containing a symlink at $out linking to ${inner}/bin/${name}. # This breaks the override pattern. # In case this turns out to be a problem, we can still add more magic else pkgs.runCommandLocal name {} '' ln -s ${inner}/bin/${name} $out mkdir -p $out/$(dirname "${nameOrPath}") mv tmp $out/${nameOrPath} ''} ''; # Base implementation for compiled executables. # Takes a compile script, which in turn takes the name as an argument. # # Examples: # writeSimpleC = makeBinWriter { compileScript = name: "gcc -o $out $contentPath"; } makeBinWriter = { compileScript, strip ? true, makeWrapperArgs ? [] }: nameOrPath: content: makeBinWriter = { compileScript, strip ? true }: nameOrPath: content: assert lib.or (types.path.check nameOrPath) (builtins.match "([0-9A-Za-z._])[0-9A-Za-z._-]*" nameOrPath != null); assert lib.or (types.path.check content) (types.str.check content); let nameIsPath = types.path.check nameOrPath; name = last (builtins.split "/" nameOrPath); path = if nameIsPath then nameOrPath else "/bin/${name}"; # The inner derivation which creates the executable under $out/bin (never at $out directly) # This is required in order to support wrapping, as wrapped programs consist of at least two files: the executable and the wrapper. inner = pkgs.runCommandLocal name ( { inherit makeWrapperArgs; nativeBuildInputs = [ makeBinaryWrapper ]; meta.mainProgram = name; } // ( if (types.str.check content) then { in pkgs.runCommand name ((if (types.str.check content) then { inherit content; passAsFile = [ "content" ]; } else { contentPath = content; } ) ) '' }) // lib.optionalAttrs (nameOrPath == "/bin/${name}") { meta.mainProgram = name; }) '' ${compileScript} ${lib.optionalString strip "${lib.getBin buildPackages.bintools-unwrapped}/bin/${buildPackages.bintools-unwrapped.targetPrefix}strip -S $out"} Loading @@ -147,165 +102,53 @@ rec { # mach-o executables from the get-go, but need to be corrected somehow # which is done by fixupPhase. ${lib.optionalString pkgs.stdenvNoCC.hostPlatform.isDarwin "fixupPhase"} ${optionalString (types.path.check nameOrPath) '' mv $out tmp mkdir -p $out/$(dirname "${path}") mv tmp $out/${path} if [ -n "''${makeWrapperArgs+''${makeWrapperArgs[@]}}" ]; then wrapProgram $out/${path} ''${makeWrapperArgs[@]} fi ''; in if nameIsPath then inner # In case nameOrPath is a name, the user intends the executable to be located at $out. # This is achieved by creating a separate derivation containing a symlink at $out linking to ${inner}/bin/${name}. # This breaks the override pattern. # In case this turns out to be a problem, we can still add more magic else pkgs.runCommandLocal name {} '' ln -s ${inner}/bin/${name} $out mkdir -p $out/$(dirname "${nameOrPath}") mv tmp $out/${nameOrPath} ''} ''; # Like writeScript but the first line is a shebang to bash # # Can be called with or without extra arguments. # # Example without arguments: # Example: # writeBash "example" '' # echo hello world # '' # # Example with arguments: # writeBash "example" # { # makeWrapperArgs = [ # "--prefix" "PATH" ":" "${pkgs.hello}/bin" # ]; # } # '' # hello # '' writeBash = name: argsOrScript: if lib.isAttrs argsOrScript && ! lib.isDerivation argsOrScript then makeScriptWriter (argsOrScript // { interpreter = "${lib.getExe pkgs.bash}"; }) name else makeScriptWriter { interpreter = "${lib.getExe pkgs.bash}"; } name argsOrScript; writeBash = makeScriptWriter { interpreter = "${lib.getExe pkgs.bash}"; }; # Like writeScriptBin but the first line is a shebang to bash # # Can be called with or without extra arguments. # # Example without arguments: # writeBashBin "example" '' # echo hello world # '' # # Example with arguments: # writeBashBin "example" # { # makeWrapperArgs = [ # "--prefix", "PATH", ":", "${pkgs.hello}/bin", # ]; # } # '' # hello # '' writeBashBin = name: writeBash "/bin/${name}"; # Like writeScript but the first line is a shebang to dash # # Can be called with or without extra arguments. # # Example without arguments: # Example: # writeDash "example" '' # echo hello world # '' # # Example with arguments: # writeDash "example" # { # makeWrapperArgs = [ # "--prefix", "PATH", ":", "${pkgs.hello}/bin", # ]; # } # '' # hello # '' writeDash = name: argsOrScript: if lib.isAttrs argsOrScript && ! lib.isDerivation argsOrScript then makeScriptWriter (argsOrScript // { interpreter = "${lib.getExe pkgs.dash}"; }) name else makeScriptWriter { interpreter = "${lib.getExe pkgs.dash}"; } name argsOrScript; writeDash = makeScriptWriter { interpreter = "${lib.getExe pkgs.dash}"; }; # Like writeScriptBin but the first line is a shebang to dash # # Can be called with or without extra arguments. # # Example without arguments: # writeDashBin "example" '' # echo hello world # '' # # Example with arguments: # writeDashBin "example" # { # makeWrapperArgs = [ # "--prefix", "PATH", ":", "${pkgs.hello}/bin", # ]; # } # '' # hello # '' writeDashBin = name: writeDash "/bin/${name}"; # Like writeScript but the first line is a shebang to fish # # Can be called with or without extra arguments. # # Example without arguments: # Example: # writeFish "example" '' # echo hello world # '' # # Example with arguments: # writeFish "example" # { # makeWrapperArgs = [ # "--prefix", "PATH", ":", "${pkgs.hello}/bin", # ]; # } # '' # hello # '' writeFish = name: argsOrScript: if lib.isAttrs argsOrScript && ! lib.isDerivation argsOrScript then makeScriptWriter (argsOrScript // { interpreter = "${lib.getExe pkgs.fish} --no-config"; check = "${lib.getExe pkgs.fish} --no-config --no-execute"; # syntax check only }) name else makeScriptWriter { writeFish = makeScriptWriter { interpreter = "${lib.getExe pkgs.fish} --no-config"; check = "${lib.getExe pkgs.fish} --no-config --no-execute"; # syntax check only } name argsOrScript; }; # Like writeScriptBin but the first line is a shebang to fish # # Can be called with or without extra arguments. # # Example without arguments: # writeFishBin "example" '' # echo hello world # '' # # Example with arguments: # writeFishBin "example" # { # makeWrapperArgs = [ # "--prefix", "PATH", ":", "${pkgs.hello}/bin", # ]; # } # '' # hello # '' writeFishBin = name: writeFish "/bin/${name}"; Loading @@ -319,12 +162,11 @@ rec { # main = launchMissiles # ''; writeHaskell = name: { libraries ? [], ghc ? pkgs.ghc, ghcArgs ? [], libraries ? [], makeWrapperArgs ? [], strip ? true, threadedRuntime ? true, strip ? true }: let appendIfNotSet = el: list: if elem el list then list else list ++ [ el ]; Loading @@ -336,7 +178,7 @@ rec { ${(ghc.withPackages (_: libraries ))}/bin/ghc ${lib.escapeShellArgs ghcArgs'} tmp.hs mv tmp $out ''; inherit makeWrapperArgs strip; inherit strip; } name; # writeHaskellBin takes the same arguments as writeHaskell but outputs a directory (like writeScriptBin) Loading @@ -345,72 +187,36 @@ rec { # Like writeScript but the first line is a shebang to nu # # Can be called with or without extra arguments. # # Example without arguments: # Example: # writeNu "example" '' # echo hello world # '' # # Example with arguments: # writeNu "example" # { # makeWrapperArgs = [ # "--prefix", "PATH", ":", "${pkgs.hello}/bin", # ]; # } # '' # hello # '' writeNu = name: argsOrScript: if lib.isAttrs argsOrScript && ! lib.isDerivation argsOrScript then makeScriptWriter (argsOrScript // { interpreter = "${lib.getExe pkgs.nushell} --no-config-file"; }) name else makeScriptWriter { interpreter = "${lib.getExe pkgs.nushell} --no-config-file"; } name argsOrScript; writeNu = makeScriptWriter { interpreter = "${lib.getExe pkgs.nushell} --no-config-file"; }; # Like writeScriptBin but the first line is a shebang to nu # # Can be called with or without extra arguments. # # Example without arguments: # writeNuBin "example" '' # echo hello world # '' # # Example with arguments: # writeNuBin "example" # { # makeWrapperArgs = [ # "--prefix", "PATH", ":", "${pkgs.hello}/bin", # ]; # } # '' # hello # '' writeNuBin = name: writeNu "/bin/${name}"; # makeRubyWriter takes ruby and compatible rubyPackages and produces ruby script writer, # If any libraries are specified, ruby.withPackages is used as interpreter, otherwise the "bare" ruby is used. makeRubyWriter = ruby: rubyPackages: buildRubyPackages: name: { libraries ? [], ... } @ args: makeScriptWriter ( (builtins.removeAttrs args ["libraries"]) // { makeRubyWriter = ruby: rubyPackages: buildRubyPackages: name: { libraries ? [], }: makeScriptWriter { interpreter = if libraries == [] then "${ruby}/bin/ruby" else "${(ruby.withPackages (ps: libraries))}/bin/ruby"; # Rubocop doesn't seem to like running in this fashion. # Rubocop doesnt seem to like running in this fashion. #check = (writeDash "rubocop.sh" '' # exec ${lib.getExe buildRubyPackages.rubocop} "$1" #''); } ) name; } name; # Like writeScript but the first line is a shebang to ruby # # Example: # writeRuby "example" { libraries = [ pkgs.rubyPackages.git ]; } '' # writeRuby "example" '' # puts "hello world" # '' writeRuby = makeRubyWriter pkgs.ruby pkgs.rubyPackages buildPackages.rubyPackages; Loading @@ -421,10 +227,8 @@ rec { # makeLuaWriter takes lua and compatible luaPackages and produces lua script writer, # which validates the script with luacheck at build time. If any libraries are specified, # lua.withPackages is used as interpreter, otherwise the "bare" lua is used. makeLuaWriter = lua: luaPackages: buildLuaPackages: name: { libraries ? [], ... } @ args: makeScriptWriter ( (builtins.removeAttrs args ["libraries"]) // { makeLuaWriter = lua: luaPackages: buildLuaPackages: name: { libraries ? [], }: makeScriptWriter { interpreter = lua.interpreter; # if libraries == [] # then lua.interpreter Loading @@ -433,8 +237,7 @@ rec { check = (writeDash "luacheck.sh" '' exec ${buildLuaPackages.luacheck}/bin/luacheck "$1" ''); } ) name; } name; # writeLua takes a name an attributeset with libraries and some lua source code and # returns an executable (should also work with luajit) Loading Loading @@ -462,10 +265,9 @@ rec { writeLua "/bin/${name}"; writeRust = name: { makeWrapperArgs ? [], rustc ? pkgs.rustc, rustcArgs ? [], strip ? true, strip ? true }: let darwinArgs = lib.optionals stdenv.isDarwin [ "-L${lib.getLib libiconv}/lib" ]; Loading @@ -475,7 +277,7 @@ rec { cp "$contentPath" tmp.rs PATH=${lib.makeBinPath [pkgs.gcc]} ${rustc}/bin/rustc ${lib.escapeShellArgs rustcArgs} ${lib.escapeShellArgs darwinArgs} -o "$out" tmp.rs ''; inherit makeWrapperArgs strip; inherit strip; } name; writeRustBin = name: Loading Loading @@ -535,13 +337,10 @@ rec { # use boolean; # print "Howdy!\n" if true; # '' writePerl = name: { libraries ? [], ... } @ args: makeScriptWriter ( (builtins.removeAttrs args ["libraries"]) // { writePerl = name: { libraries ? [] }: makeScriptWriter { interpreter = "${lib.getExe (pkgs.perl.withPackages (p: libraries))}"; } ) name; } name; # writePerlBin takes the same arguments as writePerl but outputs a directory (like writeScriptBin) writePerlBin = name: Loading @@ -550,14 +349,11 @@ rec { # makePythonWriter takes python and compatible pythonPackages and produces python script writer, # which validates the script with flake8 at build time. If any libraries are specified, # python.withPackages is used as interpreter, otherwise the "bare" python is used. makePythonWriter = python: pythonPackages: buildPythonPackages: name: { libraries ? [], flakeIgnore ? [], ... } @ args: makePythonWriter = python: pythonPackages: buildPythonPackages: name: { libraries ? [], flakeIgnore ? [] }: let ignoreAttribute = optionalString (flakeIgnore != []) "--ignore ${concatMapStringsSep "," escapeShellArg flakeIgnore}"; in makeScriptWriter ( (builtins.removeAttrs args ["libraries" "flakeIgnore"]) // { makeScriptWriter { interpreter = if pythonPackages != pkgs.pypy2Packages || pythonPackages != pkgs.pypy3Packages then if libraries == [] Loading @@ -568,9 +364,7 @@ rec { check = optionalString python.isPy3k (writeDash "pythoncheck.sh" '' exec ${buildPythonPackages.flake8}/bin/flake8 --show-source ${ignoreAttribute} "$1" ''); } ) name; } name; # writePyPy2 takes a name an attributeset with libraries and some pypy2 sourcecode and # returns an executable Loading Loading @@ -627,7 +421,7 @@ rec { writePyPy3 "/bin/${name}"; makeFSharpWriter = { dotnet-sdk ? pkgs.dotnet-sdk, fsi-flags ? "", libraries ? _: [], ... } @ args: nameOrPath: makeFSharpWriter = { dotnet-sdk ? pkgs.dotnet-sdk, fsi-flags ? "", libraries ? _: [] }: nameOrPath: let fname = last (builtins.split "/" nameOrPath); path = if strings.hasSuffix ".fsx" nameOrPath then nameOrPath else "${nameOrPath}.fsx"; Loading @@ -648,12 +442,9 @@ rec { ${lib.getExe dotnet-sdk} fsi --quiet --nologo --readline- ${fsi-flags} "$@" < "$script" ''; in content: makeScriptWriter ( (builtins.removeAttrs args ["dotnet-sdk" "fsi-flags" "libraries"]) // { in content: makeScriptWriter { interpreter = fsi; } ) path } path '' #i "nuget: ${nuget-source}/lib" ${ content } Loading @@ -665,4 +456,5 @@ rec { writeFSharpBin = name: writeFSharp "/bin/${name}"; }
pkgs/build-support/writers/test.nix +6 −82 Original line number Diff line number Diff line { haskellPackages { glib , haskellPackages , lib , nodePackages , perlPackages , pypy2Packages , python3Packages , pypy3Packages , luaPackages , rubyPackages , runCommand , testers , writers Loading Loading @@ -305,85 +310,4 @@ lib.recurseIntoAttrs { expected = "hello: world\n"; }; }; wrapping = lib.recurseIntoAttrs { bash-bin = expectSuccessBin ( writeBashBin "test-writers-wrapping-bash-bin" { makeWrapperArgs = [ "--set" "ThaigerSprint" "Thailand" ]; } '' if [[ "$ThaigerSprint" == "Thailand" ]]; then echo "success" fi '' ); bash = expectSuccess ( writeBash "test-writers-wrapping-bash" { makeWrapperArgs = [ "--set" "ThaigerSprint" "Thailand" ]; } '' if [[ "$ThaigerSprint" == "Thailand" ]]; then echo "success" fi '' ); python = expectSuccess ( writePython3 "test-writers-wrapping-python" { makeWrapperArgs = [ "--set" "ThaigerSprint" "Thailand" ]; } '' import os if os.environ.get("ThaigerSprint") == "Thailand": print("success") '' ); rust = expectSuccess ( writeRust "test-writers-wrapping-rust" { makeWrapperArgs = [ "--set" "ThaigerSprint" "Thailand" ]; } '' fn main(){ if std::env::var("ThaigerSprint").unwrap() == "Thailand" { println!("success") } } '' ); no-empty-wrapper = let bin = writeBashBin "bin" { makeWrapperArgs = []; } ''true''; in runCommand "run-test-writers-wrapping-no-empty-wrapper" {} '' ls -A ${bin}/bin if [ $(ls -A ${bin}/bin | wc -l) -eq 1 ]; then touch $out else echo "Error: Empty wrapper was created" >&2 exit 1 fi ''; }; }