diff --git a/piptools/scripts/compile.py b/piptools/scripts/compile.py index e87b5c406..a41412d0d 100755 --- a/piptools/scripts/compile.py +++ b/piptools/scripts/compile.py @@ -33,7 +33,12 @@ ) from ..writer import OutputWriter -DEFAULT_REQUIREMENTS_FILE = "requirements.in" +DEFAULT_REQUIREMENTS_FILES = ( + "requirements.in", + "setup.py", + "pyproject.toml", + "setup.cfg", +) DEFAULT_REQUIREMENTS_OUTPUT_FILE = "requirements.txt" METADATA_FILENAMES = frozenset({"setup.py", "setup.cfg", "pyproject.toml"}) @@ -342,16 +347,15 @@ def cli( log.verbosity = verbose - quiet if len(src_files) == 0: - if os.path.exists(DEFAULT_REQUIREMENTS_FILE): - src_files = (DEFAULT_REQUIREMENTS_FILE,) - elif os.path.exists("setup.py"): - src_files = ("setup.py",) + for file_path in DEFAULT_REQUIREMENTS_FILES: + if os.path.exists(file_path): + src_files = (file_path,) + break else: raise click.BadParameter( ( - "If you do not specify an input file, " - "the default is {} or setup.py" - ).format(DEFAULT_REQUIREMENTS_FILE) + "If you do not specify an input file, the default is one of: {}" + ).format(", ".join(DEFAULT_REQUIREMENTS_FILES)) ) if not output_file: diff --git a/tests/test_cli_compile.py b/tests/test_cli_compile.py index d29bc8632..69c773035 100644 --- a/tests/test_cli_compile.py +++ b/tests/test_cli_compile.py @@ -1393,16 +1393,6 @@ def test_stdin_without_output_file(runner): assert "--output-file is required if input is from stdin" in out.stderr -def test_not_specified_input_file(runner): - """ - It should raise an error if there are no input files or default input files - such as "setup.py" or "requirements.in". - """ - out = runner.invoke(cli) - assert "If you do not specify an input file" in out.stderr - assert out.exit_code == 2 - - def test_stdin(pip_conf, runner): """ Test compile requirements from STDIN. @@ -2459,6 +2449,49 @@ def test_triple_equal_pinned_dependency_is_used( ) +@pytest.mark.network +@pytest.mark.parametrize(("fname", "content"), METADATA_TEST_CASES) +def test_not_specified_input_file( + fake_dists, runner, make_module, fname, content, monkeypatch +): + """ + Test that a default-named file is parsed if present. + """ + meta_path = make_module(fname=fname, content=content) + monkeypatch.chdir(os.path.dirname(meta_path)) + out = runner.invoke( + cli, + [ + "--output-file", + "-", + "--no-header", + "--no-emit-options", + "--no-annotate", + "--no-build-isolation", + "--find-links", + fake_dists, + ], + ) + monkeypatch.undo() + + assert out.exit_code == 0, out.stderr + assert "small-fake-a==0.1\n" == out.stdout + + +def test_not_specified_input_file_without_allowed_files(runner): + """ + It should raise an error if there are no input files or default input files + such as "setup.py" or "requirements.in". + """ + out = runner.invoke(cli) + assert out.exit_code == 2 + expected_error = ( + "Error: Invalid value: If you do not specify an input file, the default " + "is one of: requirements.in, setup.py, pyproject.toml, setup.cfg" + ) + assert expected_error in out.stderr.splitlines() + + @pytest.mark.network @pytest.mark.parametrize(("fname", "content"), METADATA_TEST_CASES) def test_input_formats(fake_dists, runner, make_module, fname, content):