|
3 | 3 | import itertools |
4 | 4 | import os |
5 | 5 | import shlex |
| 6 | +import shutil |
6 | 7 | import sys |
7 | 8 | import tempfile |
| 9 | +import typing |
8 | 10 | from pathlib import Path |
| 11 | +from subprocess import run # nosec |
9 | 12 | from typing import IO, Any, BinaryIO, cast |
10 | 13 |
|
11 | 14 | import click |
@@ -79,9 +82,9 @@ def _determine_linesep( |
79 | 82 | ) |
80 | 83 | @click.pass_context |
81 | 84 | @options.version |
82 | | -@options.color |
83 | 85 | @options.verbose |
84 | 86 | @options.quiet |
| 87 | +@options.color |
85 | 88 | @options.dry_run |
86 | 89 | @options.pre |
87 | 90 | @options.rebuild |
@@ -122,11 +125,69 @@ def _determine_linesep( |
122 | 125 | @options.build_deps_for |
123 | 126 | @options.all_build_deps |
124 | 127 | @options.only_build_deps |
| 128 | +@typing.no_type_check |
125 | 129 | def cli( |
| 130 | + *args, |
| 131 | + verbose: int, |
| 132 | + quiet: int, |
| 133 | + **kwargs, |
| 134 | +): |
| 135 | + """ |
| 136 | + Compiles requirements.txt from requirements.in, pyproject.toml, setup.cfg, |
| 137 | + or setup.py specs. |
| 138 | + """ |
| 139 | + log.verbosity = verbose - quiet |
| 140 | + current_python = sys.executable |
| 141 | + log.debug(f"{current_python=}") |
| 142 | + env_python = shutil.which("python") |
| 143 | + log.debug(f"{env_python=}") |
| 144 | + if current_python != env_python: |
| 145 | + # pip-tools probably installed globally (e.g. via pipx) |
| 146 | + # install pip-tools in a venv made by env_python and run it there |
| 147 | + click.echo("Installing pip-tools in temporary venv...", err=True) |
| 148 | + with tempfile.TemporaryDirectory(prefix="pip-tools-env-") as venv_path: |
| 149 | + log.debug(f"Installing venv at {venv_path}") |
| 150 | + run( # nosec |
| 151 | + [ |
| 152 | + env_python, |
| 153 | + "-m", |
| 154 | + "venv", |
| 155 | + venv_path, |
| 156 | + ], |
| 157 | + capture_output=(not log.verbosity), |
| 158 | + check=True, |
| 159 | + ) |
| 160 | + temp_python = venv_path + "/bin/python" |
| 161 | + log.debug(f"{temp_python=}") |
| 162 | + run( # nosec |
| 163 | + [ |
| 164 | + temp_python, |
| 165 | + "-m", |
| 166 | + "pip", |
| 167 | + "install", |
| 168 | + "pip-tools", # TODO fix to this version of pip-tools? |
| 169 | + ], |
| 170 | + capture_output=(not log.verbosity), |
| 171 | + check=True, |
| 172 | + ) |
| 173 | + env = {**os.environ, "PATH": f"{venv_path}/bin:{os.environ['PATH']}"} |
| 174 | + run( # nosec |
| 175 | + [ |
| 176 | + "pip-compile", |
| 177 | + *sys.argv[1:], |
| 178 | + ], |
| 179 | + env=env, |
| 180 | + ) |
| 181 | + else: |
| 182 | + # pip-tools running in current env python |
| 183 | + cli_runner(*args, verbose, quiet, **kwargs) |
| 184 | + |
| 185 | + |
| 186 | +def cli_runner( |
126 | 187 | ctx: click.Context, |
127 | | - color: bool | None, |
128 | 188 | verbose: int, |
129 | 189 | quiet: int, |
| 190 | + color: bool | None, |
130 | 191 | dry_run: bool, |
131 | 192 | pre: bool, |
132 | 193 | rebuild: bool, |
|
0 commit comments