about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--pkgs/development/tools/build-managers/bazel/default.nix21
-rw-r--r--pkgs/development/tools/build-managers/bazel/shebang-test.nix49
2 files changed, 65 insertions, 5 deletions
diff --git a/pkgs/development/tools/build-managers/bazel/default.nix b/pkgs/development/tools/build-managers/bazel/default.nix
index e9ce95c160996..d5cbd642e7053 100644
--- a/pkgs/development/tools/build-managers/bazel/default.nix
+++ b/pkgs/development/tools/build-managers/bazel/default.nix
@@ -5,7 +5,7 @@
 , lr, xe, zip, unzip, bash, writeCBin, coreutils
 , which, gawk, gnused, gnutar, gnugrep, gzip, findutils
 # updater
-, python3, writeScript
+, python27, python3, writeScript
 # Apple dependencies
 , cctools, libcxx, CoreFoundation, CoreServices, Foundation
 # Allow to independently override the jdks used to build and run respectively
@@ -223,6 +223,7 @@ stdenv.mkDerivation rec {
       };
 
     in {
+      shebang = callPackage ./shebang-test.nix { inherit runLocal extracted bazelTest distDir; };
       bashTools = callPackage ./bash-tools-test.nix { inherit runLocal bazelTest distDir; };
       cpp = callPackage ./cpp-test.nix { inherit runLocal bazelTest bazel-examples distDir; };
       java = callPackage ./java-test.nix { inherit runLocal bazelTest bazel-examples distDir; };
@@ -327,10 +328,12 @@ stdenv.mkDerivation rec {
     '';
 
     genericPatches = ''
-      # Substitute python's stub shebang to plain python path. (see TODO add pr URL)
-      # See also `postFixup` where python is added to $out/nix-support
-      substituteInPlace src/main/java/com/google/devtools/build/lib/bazel/rules/python/python_stub_template.txt \
-          --replace "#!/usr/bin/env python" "#!${python3}/bin/python"
+      # Substitute j2objc and objc wrapper's python shebang to plain python path.
+      # These scripts explicitly depend on Python 2.7, hence we use python27.
+      # See also `postFixup` where python27 is added to $out/nix-support
+      substituteInPlace tools/j2objc/j2objc_header_map.py --replace "$!/usr/bin/python2.7" "#!${python27}/bin/python"
+      substituteInPlace tools/j2objc/j2objc_wrapper.py --replace "$!/usr/bin/python2.7" "#!${python27}/bin/python"
+      substituteInPlace tools/objc/j2objc_dead_code_pruner.py --replace "$!/usr/bin/python2.7" "#!${python27}/bin/python"
 
       # md5sum is part of coreutils
       sed -i 's|/sbin/md5|md5sum|' \
@@ -340,8 +343,12 @@ stdenv.mkDerivation rec {
       grep -rlZ /bin src/main/java/com/google/devtools | while IFS="" read -r -d "" path; do
         # If you add more replacements here, you must change the grep above!
         # Only files containing /bin are taken into account.
+        # We default to python3 where possible. See also `postFixup` where
+        # python3 is added to $out/nix-support
         substituteInPlace "$path" \
           --replace /bin/bash ${customBash}/bin/bash \
+          --replace "/usr/bin/env bash" ${customBash}/bin/bash \
+          --replace "/usr/bin/env python" ${python3}/bin/python \
           --replace /usr/bin/env ${coreutils}/bin/env \
           --replace /bin/true ${coreutils}/bin/true
       done
@@ -517,6 +524,10 @@ stdenv.mkDerivation rec {
     echo "${customBash} ${defaultShellPath}" >> $out/nix-support/depends
     # The templates get tar’d up into a .jar,
     # so nix can’t detect python is needed in the runtime closure
+    # Some of the scripts explicitly depend on Python 2.7. Otherwise, we
+    # default to using python3. Therefore, both python27 and python3 are
+    # runtime dependencies.
+    echo "${python27}" >> $out/nix-support/depends
     echo "${python3}" >> $out/nix-support/depends
   '' + lib.optionalString stdenv.isDarwin ''
     echo "${cctools}" >> $out/nix-support/depends
diff --git a/pkgs/development/tools/build-managers/bazel/shebang-test.nix b/pkgs/development/tools/build-managers/bazel/shebang-test.nix
new file mode 100644
index 0000000000000..fd94f97a76592
--- /dev/null
+++ b/pkgs/development/tools/build-managers/bazel/shebang-test.nix
@@ -0,0 +1,49 @@
+{
+  bazel
+, bazelTest
+, distDir
+, extracted
+, runLocal
+, unzip
+}:
+
+# Tests that all shebangs are patched appropriately.
+# #!/usr/bin/... should be replaced by Nix store references.
+# #!.../bin/env python should be replaced by Nix store reference to the python interpreter.
+
+let
+
+  workspaceDir = runLocal "our_workspace" {} "mkdir $out";
+
+  testBazel = bazelTest {
+    name = "bazel-test-shebangs";
+    inherit workspaceDir;
+    bazelPkg = bazel;
+    bazelScript = ''
+      set -ueo pipefail
+      FAIL=
+      check_shebangs() {
+        local dir="$1"
+        { grep -Re '#!/usr/bin' $dir && FAIL=1; } || true
+        { grep -Re '#![^[:space:]]*/bin/env' $dir && FAIL=1; } || true
+      }
+      BAZEL_EXTRACTED=${extracted bazel}/install
+      check_shebangs $BAZEL_EXTRACTED
+      while IFS= read -r -d "" zip; do
+        unzipped="./$zip/UNPACKED"
+        mkdir -p "$unzipped"
+        unzip -qq $zip -d "$unzipped"
+        check_shebangs "$unzipped"
+        rm -rf unzipped
+      done < <(find $BAZEL_EXTRACTED -type f -name '*.zip' -or -name '*.jar' -print0)
+      if [[ $FAIL = 1 ]]; then
+        echo "Found files in the bazel distribution with illegal shebangs." >&2
+        echo "Replace those by explicit Nix store paths." >&2
+        echo "Python scripts should not use \`bin/env python' but the Python interpreter's store path." >&2
+        exit 1
+      fi
+    '';
+    buildInputs = [ unzip ];
+  };
+
+in testBazel