From 3e632c511ed47183b498e228a6c7b7c9082e3e81 Mon Sep 17 00:00:00 2001 From: Albert Tugushev Date: Thu, 4 Jul 2019 12:18:41 +0300 Subject: [PATCH] Fix output file update on dry-run compile --- piptools/utils.py | 7 ++-- tests/test_cli_compile.py | 71 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/piptools/utils.py b/piptools/utils.py index c0b1bdbaf..9642c49f5 100644 --- a/piptools/utils.py +++ b/piptools/utils.py @@ -6,6 +6,7 @@ from itertools import chain, groupby import six +from click.utils import LazyFile from six.moves import shlex_quote from ._compat import install_req_from_line @@ -339,11 +340,7 @@ def get_compile_command(click_ctx): continue # Use a file name for file-like objects - if ( - hasattr(value, "write") - and hasattr(value, "read") - and hasattr(value, "name") - ): + if isinstance(value, LazyFile): value = value.name # Convert value to the list diff --git a/tests/test_cli_compile.py b/tests/test_cli_compile.py index 050993e07..26d1cc9bc 100644 --- a/tests/test_cli_compile.py +++ b/tests/test_cli_compile.py @@ -722,3 +722,74 @@ def test_pre_option(runner, cli_option, infile_option, expected_package): assert out.exit_code == 0, out.output assert expected_package in out.output.splitlines(), out.output + + +@pytest.mark.parametrize( + "add_options", + [ + [], + ["--output-file", "requirements.txt"], + ["--upgrade"], + ["--upgrade", "--output-file", "requirements.txt"], + ["--upgrade-package", "small-fake-a"], + ["--upgrade-package", "small-fake-a", "--output-file", "requirements.txt"], + ], +) +def test_dry_run_option(runner, add_options): + """ + Tests pip-compile doesn't create requirements.txt file on dry-run. + """ + with open("requirements.in", "w") as req_in: + req_in.write("small-fake-a\n") + + out = runner.invoke( + cli, ["--dry-run", "--find-links", MINIMAL_WHEELS_PATH] + add_options + ) + + assert out.exit_code == 0, out.output + assert "small-fake-a==0.2" in out.output.splitlines() + assert not os.path.exists("requirements.txt") + + +@pytest.mark.parametrize( + "add_options, expected_cli_output_package", + [ + ([], "small-fake-a==0.1"), + (["--output-file", "requirements.txt"], "small-fake-a==0.1"), + (["--upgrade"], "small-fake-a==0.2"), + (["--upgrade", "--output-file", "requirements.txt"], "small-fake-a==0.2"), + (["--upgrade-package", "small-fake-a"], "small-fake-a==0.2"), + ( + ["--upgrade-package", "small-fake-a", "--output-file", "requirements.txt"], + "small-fake-a==0.2", + ), + ], +) +def test_dry_run_doesnt_touch_output_file( + runner, add_options, expected_cli_output_package +): + """ + Tests pip-compile doesn't touch requirements.txt file on dry-run. + """ + with open("requirements.in", "w") as req_in: + req_in.write("small-fake-a\n") + + with open("requirements.txt", "w") as req_txt: + req_txt.write("small-fake-a==0.1\n") + + before_compile_mtime = os.stat("requirements.txt").st_mtime + + out = runner.invoke( + cli, ["--dry-run", "--find-links", MINIMAL_WHEELS_PATH] + add_options + ) + + assert out.exit_code == 0, out.output + assert expected_cli_output_package in out.output.splitlines() + + # The package version must NOT be updated in the output file + with open("requirements.txt", "r") as req_txt: + assert "small-fake-a==0.1" in req_txt.read().splitlines() + + # The output file must not be touched + after_compile_mtime = os.stat("requirements.txt").st_mtime + assert after_compile_mtime == before_compile_mtime