WORKSPACE: use nix for python/go if available

This introduces Nix, the package manager, and nixpkgs, the package
collection, into hscloud's bazel build machinery.

There are two reasons behind this:

 - on NixOS, it's painful or at least very difficult to run hscloud out
   of the box. Especially with rules_go, that download a blob from the
   Internet to get a Go toolchain, it just fails outright. This solves
   this and allows hscloud to be used on NixOS.

 - on non-NixOS platforms that still might have access to Nix this
   allows to somewhat hermeticize the build. Notably, Python now comes
   from nixpkgs, and is fabricobbled in a way that makes pip3_import
   use Nix system dependencies for ncurses and libpq.

This has been tested to run ci_presubmit on NixOS 20.09pre and Gentoo
~amd64.

Change-Id: Ic16e4827cb52a05aea0df0eed84d80c5e9ae0e07
diff --git a/WORKSPACE b/WORKSPACE
index 031d55a..6ecd658 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -7,7 +7,6 @@
 
 # Protobuf deps (shared between many rules).
 # Load this as early as possible, to avoid a different version being pulled in by deps of something else
-
 http_archive(
     name = "com_google_protobuf",
     sha256 = "bb8ce9ba11eb7bccf080599fe7cad9cc461751c8dd1ba61701c0070d58cde973",
@@ -18,8 +17,27 @@
 load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
 protobuf_deps()
 
-# Go/Gazelle rules
+# Force rules_python at a bleeding edge version (for pip3_import).
+http_archive(
+    name = "rules_python",
+    url = "https://github.com/bazelbuild/rules_python/releases/download/0.0.3/rules_python-0.0.3.tar.gz",
+    sha256 = "e46612e9bb0dae8745de6a0643be69e8665a03f63163ac6610c210e80d14c3e4",
+)
 
+# Load and setup Nixpkgs, if Nix is present on the build system.
+http_archive(
+    name = "io_tweag_rules_nixpkgs",
+    strip_prefix = "rules_nixpkgs-dc24090573d74adcf38730422941fd69b87682c7",
+    urls = ["https://github.com/tweag/rules_nixpkgs/archive/dc24090573d74adcf38730422941fd69b87682c7.tar.gz"],
+    sha256 = "aca86baa64174478c57f74ed09d5c2313113abe94aa3af030486d1b14032d3ed",
+)
+load("//third_party/nix:repository_rules.bzl", "hscloud_setup_nix")
+hscloud_setup_nix(
+    revision = "1179841f9a88b8a548f4b11d1a03aa25a790c379",
+    sha256 = "8b64041bfb9760de9e797c0a985a4830880c21732489f397e217d877edd9a990",
+)
+
+# Download Go/Gazelle rules
 http_archive(
     name = "io_bazel_rules_go",
     sha256 = "6a68e269802911fa419abb940c850734086869d7fe9bc8e12aaf60a09641c818",
@@ -28,7 +46,6 @@
         "https://github.com/bazelbuild/rules_go/releases/download/v0.23.0/rules_go-v0.23.0.tar.gz",
     ],
 )
-
 http_archive(
     name = "bazel_gazelle",
     sha256 = "bfd86b3cbe855d6c16c6fce60d76bd51f5c8dbc9cfcaef7a2bb5c1aafd0710e8",
@@ -39,23 +56,15 @@
 )
 
 # Python rules
-
 # Important: rules_python must be loaded before protobuf (and grpc) because they load an older version otherwise
-
-http_archive(
-    name = "rules_python",
-    url = "https://github.com/bazelbuild/rules_python/releases/download/0.0.2/rules_python-0.0.2.tar.gz",
-    strip_prefix = "rules_python-0.0.2",
-    sha256 = "b5668cde8bb6e3515057ef465a35ad712214962f0b3a314e551204266c7be90c",
-)
 load("@rules_python//python:repositories.bzl", "py_repositories")
 py_repositories()
 
 load("@rules_python//python:pip.bzl", "pip_repositories")
 pip_repositories()
 
-load("@rules_python//python:pip.bzl", "pip3_import")
-pip3_import(
+load("@hscloud_pip_imports//:imports.bzl", "hscloud_pip3_import")
+hscloud_pip3_import(
    name = "pydeps",
    requirements = "//third_party/py:requirements.txt",
 )
@@ -63,6 +72,14 @@
 load("@pydeps//:requirements.bzl", "pip_install")
 pip_install()
 
+
+# Setup Go toolchain.
+# This workspace is generated by hscloud_setup_nixpkgs. It will either call
+# go_register_toolchains() to automagically get Go toolchains from the Internet
+# or, if nix is present, instead setup a toolchain from nixpkgs.
+load("@hscloud_go_toolchain//:imports.bzl", "hscloud_go_register_toolchains")
+hscloud_go_register_toolchains()
+
 # IMPORTANT: match protobuf version above with the one loaded by grpc
 http_archive(
     name = "com_github_grpc_grpc",
@@ -71,21 +88,20 @@
     urls = ["https://github.com/grpc/grpc/archive/v1.30.0.tar.gz"],
 )
 
+# Load grpc deps after Go, to prevent overriding Go toolchains/SDK.
 load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")
 grpc_deps()
 load("@com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps")
 grpc_extra_deps()
 
-# Go rules dependencies and our own dependencies.
-
-load("@io_bazel_rules_go//go:deps.bzl", "go_rules_dependencies", "go_register_toolchains")
+load("@io_bazel_rules_go//go:deps.bzl", "go_rules_dependencies")
 go_rules_dependencies()
-go_register_toolchains()
 
 # gazelle:repository_macro third_party/go/repositories.bzl%go_repositories
 load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
 gazelle_dependencies()
 
+# Load Go third-party packages.
 load("//third_party/go:repositories.bzl", "go_repositories")
 go_repositories()