From e8b8ce71268f1f5dd193eac8d38071e02ad7b91f Mon Sep 17 00:00:00 2001 From: Albert Tugushev Date: Sat, 1 Jul 2023 08:40:01 +0200 Subject: [PATCH] Exclude default config value from the pip-compile header (#1893) --- piptools/utils.py | 28 +++++++++++++++++++++++++--- tests/conftest.py | 2 +- tests/test_utils.py | 24 ++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/piptools/utils.py b/piptools/utils.py index 4374b74a9..6b7d2d2c8 100644 --- a/piptools/utils.py +++ b/piptools/utils.py @@ -2,7 +2,6 @@ import collections import copy -import functools import itertools import json import os @@ -366,6 +365,12 @@ def get_compile_command(click_ctx: click.Context) -> str: if option_long_name in COMPILE_EXCLUDE_OPTIONS: continue + # Exclude config option if it's the default one + if option_long_name == "--config": + default_config = select_config_file(click_ctx.params.get("src_files", ())) + if value == default_config: + continue + # Skip options without a value if option.default is None and not value: continue @@ -594,7 +599,14 @@ def select_config_file(src_files: tuple[str, ...]) -> Path | None: ), None, ) - return config_file_path + if config_file_path is None: + return None + + return ( + config_file_path.relative_to(working_directory) + if is_path_relative_to(config_file_path, working_directory) + else config_file_path + ) # Some of the defined click options have different `dest` values than the defaults @@ -628,7 +640,6 @@ def get_click_dest_for_option(option_name: str) -> str: ] -@functools.lru_cache() def parse_config_file(config_file: Path) -> dict[str, Any]: try: config = tomllib.loads(config_file.read_text(encoding="utf-8")) @@ -656,3 +667,14 @@ def parse_config_file(config_file: Path) -> dict[str, Any]: original_option, f"Config key '{original_option}' must be a list" ) return piptools_config + + +def is_path_relative_to(path1: Path, path2: Path) -> bool: + """Return True if ``path1`` is relative to ``path2``.""" + # TODO: remove this function in favor of Path.is_relative_to() + # when we drop support for Python 3.8 + try: + path1.relative_to(path2) + except ValueError: + return False + return True diff --git a/tests/conftest.py b/tests/conftest.py index 70f0e0e90..513b72430 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -473,6 +473,6 @@ def _maker( config_to_dump = {"tool": {"pip-tools": {pyproject_param: new_default}}} config_file.write_text(tomli_w.dumps(config_to_dump)) - return config_file + return config_file.relative_to(tmpdir_cwd) return _maker diff --git a/tests/test_utils.py b/tests/test_utils.py index 5f1e9ab5d..4820492d6 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -386,6 +386,30 @@ def test_get_compile_command(tmpdir_cwd, cli_args, expected_command): assert get_compile_command(ctx) == expected_command +@pytest.mark.parametrize( + ("config_file", "expected_command"), + ( + pytest.param( + "pyproject.toml", "pip-compile", id="exclude default pyproject.toml" + ), + pytest.param( + ".pip-tools.toml", "pip-compile", id="exclude default .pip-tools.toml" + ), + pytest.param( + "my-config.toml", + "pip-compile --config=my-config.toml", + id="include non-default my-config.toml", + ), + ), +) +def test_get_compile_command_with_config(tmpdir_cwd, config_file, expected_command): + """Test that get_compile_command excludes or includes config file.""" + with open(config_file, "w"): + pass + with compile_cli.make_context("pip-compile", ["--config", config_file]) as ctx: + assert get_compile_command(ctx) == expected_command + + def test_get_compile_command_escaped_filenames(tmpdir_cwd): """ Test that get_compile_command output (re-)escapes ' -- '-escaped filenames.