Unverified Commit 41ec80f6 authored by Vladimír Čunát's avatar Vladimír Čunát
Browse files

Merge #293181: Revert "writers: add support for wrapping"

Reverting this unexplained huge rebuild merged directly to master.
parents 0d58a849 ea4b9575
Loading
Loading
Loading
Loading
+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
@@ -16,6 +6,7 @@ let
    escapeShellArg
    last
    optionalString
    stringLength
    strings
    types
    ;
@@ -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;
      }
      // (
@@ -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"}
@@ -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}";

@@ -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 ];
@@ -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)
@@ -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;
@@ -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
@@ -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)
@@ -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" ];
@@ -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:
@@ -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:
@@ -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 == []
@@ -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
@@ -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";
@@ -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 }
@@ -665,4 +456,5 @@ rec {

  writeFSharpBin = name:
    writeFSharp "/bin/${name}";

}
+6 −82
Original line number Diff line number Diff line
{ haskellPackages
{ glib
, haskellPackages
, lib
, nodePackages
, perlPackages
, pypy2Packages
, python3Packages
, pypy3Packages
, luaPackages
, rubyPackages
, runCommand
, testers
, writers
@@ -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
    '';
  };
}