Add extra_pip_args option to pip_import (#274)

Adds the attr extra_pip_args to pip_import.  These args will be passed
along to the pip invocation inside piptool.

Closes #274 and closes #278.

Co-authored-by: scarito1 <scarito@google.com>
diff --git a/docs/pip.md b/docs/pip.md
index 037bdfa..73035fd 100755
--- a/docs/pip.md
+++ b/docs/pip.md
@@ -5,7 +5,7 @@
 ## pip_import
 
 <pre>
-pip_import(<a href="#pip_import-name">name</a>, <a href="#pip_import-python_interpreter">python_interpreter</a>, <a href="#pip_import-requirements">requirements</a>)
+pip_import(<a href="#pip_import-name">name</a>, <a href="#pip_import-extra_pip_args">extra_pip_args</a>, <a href="#pip_import-python_interpreter">python_interpreter</a>, <a href="#pip_import-requirements">requirements</a>)
 </pre>
 
 A rule for importing `requirements.txt` dependencies into Bazel.
@@ -67,6 +67,15 @@
         </p>
       </td>
     </tr>
+    <tr id="pip_import-extra_pip_args">
+      <td><code>extra_pip_args</code></td>
+      <td>
+        List of strings; optional
+        <p>
+          Extra arguments to pass on to pip. Must not contain spaces.
+        </p>
+      </td>
+    </tr>
     <tr id="pip_import-python_interpreter">
       <td><code>python_interpreter</code></td>
       <td>
diff --git a/packaging/piptool.py b/packaging/piptool.py
index 766a674..ffae941 100644
--- a/packaging/piptool.py
+++ b/packaging/piptool.py
@@ -102,6 +102,9 @@
 parser.add_argument('--directory', action='store',
                     help=('The directory into which to put .whl files.'))
 
+parser.add_argument('--extra_pip_args', action='store',
+                    help=('Extra arguments to pass down to pip.'))
+
 def determine_possible_extras(whls):
   """Determines the list of possible "extras" for each .whl
 
@@ -160,7 +163,10 @@
   args = parser.parse_args()
 
   # https://github.com/pypa/pip/blob/9.0.1/pip/__init__.py#L209
-  if pip_main(["wheel", "-w", args.directory, "-r", args.input]):
+  pip_args = ["wheel", "-w", args.directory, "-r", args.input]
+  if args.extra_pip_args:
+      pip_args += args.extra_pip_args.strip("\"").split()
+  if pip_main(pip_args):
     sys.exit(1)
 
   # Enumerate the .whl files we downloaded.
diff --git a/python/pip.bzl b/python/pip.bzl
index 37da2a2..cae023f 100644
--- a/python/pip.bzl
+++ b/python/pip.bzl
@@ -22,8 +22,7 @@
     # requirements.bzl without it.
     repository_ctx.file("BUILD", "")
 
-    # To see the output, pass: quiet=False
-    result = repository_ctx.execute([
+    args = [
         repository_ctx.attr.python_interpreter,
         repository_ctx.path(repository_ctx.attr._script),
         "--python_interpreter",
@@ -36,13 +35,24 @@
         repository_ctx.path("requirements.bzl"),
         "--directory",
         repository_ctx.path(""),
-    ])
+    ]
+    if repository_ctx.attr.extra_pip_args:
+        args += [
+            "--extra_pip_args",
+            "\"" + " ".join(repository_ctx.attr.extra_pip_args) + "\"",
+        ]
+
+    # To see the output, pass: quiet=False
+    result = repository_ctx.execute(args)
 
     if result.return_code:
         fail("pip_import failed: %s (%s)" % (result.stdout, result.stderr))
 
 pip_import = repository_rule(
     attrs = {
+        "extra_pip_args": attr.string_list(
+            doc = "Extra arguments to pass on to pip. Must not contain spaces.",
+        ),
         "python_interpreter": attr.string(default = "python", doc = """
 The command to run the Python interpreter used to invoke pip and unpack the
 wheels.
diff --git a/tools/piptool.par b/tools/piptool.par
index 57ef98d..2fa8909 100755
--- a/tools/piptool.par
+++ b/tools/piptool.par
Binary files differ