-
-
Notifications
You must be signed in to change notification settings - Fork 597
refactor: use click in dependency_resolver.py #1071
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,7 +19,9 @@ | |
import shutil | ||
import sys | ||
from pathlib import Path | ||
from typing import Optional, Tuple | ||
|
||
import click | ||
import piptools.writer as piptools_writer | ||
from piptools.scripts.compile import cli | ||
|
||
|
@@ -77,24 +79,25 @@ def _locate(bazel_runfiles, file): | |
return bazel_runfiles.Rlocation(file) | ||
|
||
|
||
if __name__ == "__main__": | ||
if len(sys.argv) < 4: | ||
print( | ||
"Expected at least two arguments: requirements_in requirements_out", | ||
file=sys.stderr, | ||
) | ||
sys.exit(1) | ||
|
||
parse_str_none = lambda s: None if s == "None" else s | ||
@click.command(context_settings={"ignore_unknown_options": True}) | ||
@click.argument("requirements_in") | ||
@click.argument("requirements_txt") | ||
@click.argument("update_target_label") | ||
@click.option("--requirements-linux") | ||
@click.option("--requirements-darwin") | ||
@click.option("--requirements-windows") | ||
@click.argument("extra_args", nargs=-1, type=click.UNPROCESSED) | ||
def main( | ||
requirements_in: str, | ||
requirements_txt: str, | ||
update_target_label: str, | ||
requirements_linux: Optional[str], | ||
requirements_darwin: Optional[str], | ||
requirements_windows: Optional[str], | ||
extra_args: Tuple[str, ...], | ||
) -> None: | ||
bazel_runfiles = runfiles.Create() | ||
|
||
requirements_in = sys.argv.pop(1) | ||
requirements_txt = sys.argv.pop(1) | ||
requirements_linux = parse_str_none(sys.argv.pop(1)) | ||
requirements_darwin = parse_str_none(sys.argv.pop(1)) | ||
requirements_windows = parse_str_none(sys.argv.pop(1)) | ||
update_target_label = sys.argv.pop(1) | ||
|
||
requirements_file = _select_golden_requirements_file( | ||
requirements_txt=requirements_txt, requirements_linux=requirements_linux, | ||
requirements_darwin=requirements_darwin, requirements_windows=requirements_windows | ||
|
@@ -128,6 +131,8 @@ def _locate(bazel_runfiles, file): | |
os.environ["LC_ALL"] = "C.UTF-8" | ||
os.environ["LANG"] = "C.UTF-8" | ||
|
||
argv = [] | ||
|
||
UPDATE = True | ||
# Detect if we are running under `bazel test`. | ||
if "TEST_TMPDIR" in os.environ: | ||
|
@@ -136,8 +141,7 @@ def _locate(bazel_runfiles, file): | |
# to the real user cache, Bazel sandboxing makes the file read-only | ||
# and we fail. | ||
# In theory this makes the test more hermetic as well. | ||
sys.argv.append("--cache-dir") | ||
sys.argv.append(os.environ["TEST_TMPDIR"]) | ||
argv.append(f"--cache-dir={os.environ['TEST_TMPDIR']}") | ||
# Make a copy for pip-compile to read and mutate. | ||
requirements_out = os.path.join( | ||
os.environ["TEST_TMPDIR"], os.path.basename(requirements_file) + ".out" | ||
|
@@ -153,14 +157,13 @@ def _locate(bazel_runfiles, file): | |
os.environ["CUSTOM_COMPILE_COMMAND"] = update_command | ||
os.environ["PIP_CONFIG_FILE"] = os.getenv("PIP_CONFIG_FILE") or os.devnull | ||
|
||
sys.argv.append("--output-file") | ||
sys.argv.append(requirements_file_relative if UPDATE else requirements_out) | ||
sys.argv.append( | ||
argv.append(f"--output-file={requirements_file_relative if UPDATE else requirements_out}") | ||
argv.append( | ||
requirements_in_relative | ||
if Path(requirements_in_relative).exists() | ||
else resolved_requirements_in | ||
) | ||
print(sys.argv) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unclear why this was here. Probably for debugging? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That was my assumption too. Didn't seem like something that ought to stick around (adding clutter to stdout!). Happy to add it back if someone has a good reason for it to stay there. |
||
argv.extend(extra_args) | ||
|
||
if UPDATE: | ||
print("Updating " + requirements_file_relative) | ||
|
@@ -176,7 +179,7 @@ def _locate(bazel_runfiles, file): | |
resolved_requirements_file, requirements_file_tree | ||
) | ||
) | ||
cli() | ||
cli(argv) | ||
requirements_file_relative_path = Path(requirements_file_relative) | ||
content = requirements_file_relative_path.read_text() | ||
content = content.replace(absolute_path_prefix, "") | ||
|
@@ -185,7 +188,7 @@ def _locate(bazel_runfiles, file): | |
# cli will exit(0) on success | ||
try: | ||
print("Checking " + requirements_file) | ||
cli() | ||
cli(argv) | ||
print("cli() should exit", file=sys.stderr) | ||
sys.exit(1) | ||
except SystemExit as e: | ||
|
@@ -219,3 +222,7 @@ def _locate(bazel_runfiles, file): | |
file=sys.stderr, | ||
) | ||
sys.exit(1) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like we lose sys.argv[0] compared to before. I'm not sure if the piptools cli expects argv to have argv[0] be the name of the original script but maybe we can add sys.argv[0] here in case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to be clear, are you suggesting we change this to the following?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I can tell, omitting argv[0] when calling cli() is correct.
Under the hood, piptools is using click, and the implementation is obscured by a ton of decorators. Digging into it...
compile.cli
is an instance of the clickCommand
class.Command.__call__
is an alias forCommand.main
Command.main
docs say, for the first positionl arg (namedargs
): "the arguments that should be used for parsing. If not provided sys.argv[1:] is used"So it doesn't expect args to contain argv[0]. The docs go on further to say the optional
prog_name
arg is initialized to sys.argv[0] if not specified.As a side note, there is a
standalone_mode
arg, which controls whether the command tries to exit or not.