diff --git a/news/2702.feature.md b/news/2702.feature.md new file mode 100644 index 0000000000..106b0c7684 --- /dev/null +++ b/news/2702.feature.md @@ -0,0 +1 @@ +Caches can be disabled by using the `--no-cache` option or setting the `PDM_NO_CACHE` environment variable. diff --git a/src/pdm/cli/completions/pdm.bash b/src/pdm/cli/completions/pdm.bash index dc44e6993b..e150b10902 100644 --- a/src/pdm/cli/completions/pdm.bash +++ b/src/pdm/cli/completions/pdm.bash @@ -24,7 +24,7 @@ _pdm_a919b69078acdf0a_complete() # completing for an option if [[ ${cur} == --* ]] ; then - opts="--config --help --ignore-python --pep582 --quiet --verbose --version" + opts="--config --help --ignore-python --no-cache --pep582 --quiet --verbose --version" case "$com" in diff --git a/src/pdm/cli/completions/pdm.fish b/src/pdm/cli/completions/pdm.fish index c4bbcbf979..2de8065e4e 100644 --- a/src/pdm/cli/completions/pdm.fish +++ b/src/pdm/cli/completions/pdm.fish @@ -14,6 +14,7 @@ end complete -c pdm -n '__fish_pdm_a919b69078acdf0a_complete_no_subcommand' -l config -d 'Specify another config file path [env var: PDM_CONFIG_FILE] ' complete -c pdm -n '__fish_pdm_a919b69078acdf0a_complete_no_subcommand' -l help -d 'Show this help message and exit.' complete -c pdm -n '__fish_pdm_a919b69078acdf0a_complete_no_subcommand' -l ignore-python -d 'Ignore the Python path saved in .pdm-python. [env var: PDM_IGNORE_SAVED_PYTHON]' +complete -c pdm -n '__fish_pdm_a919b69078acdf0a_complete_no_subcommand' -l no-cache -d 'Disable the cache for the current command. [env var: PDM_NO_CACHE]' complete -c pdm -n '__fish_pdm_a919b69078acdf0a_complete_no_subcommand' -l pep582 -d 'Print the command line to be eval\'d by the shell' complete -c pdm -n '__fish_pdm_a919b69078acdf0a_complete_no_subcommand' -l quiet -d 'Suppress output' complete -c pdm -n '__fish_pdm_a919b69078acdf0a_complete_no_subcommand' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' diff --git a/src/pdm/cli/completions/pdm.ps1 b/src/pdm/cli/completions/pdm.ps1 index befa6843b4..01ffe864f2 100644 --- a/src/pdm/cli/completions/pdm.ps1 +++ b/src/pdm/cli/completions/pdm.ps1 @@ -482,7 +482,7 @@ function TabExpansion($line, $lastWord) { default { # No command $command = $null - $completer.AddOpts(([Option]::new(("--pep582", "-I", "--ignore-python", "-c", "--config")))) + $completer.AddOpts(([Option]::new(("--pep582", "-I", "--ignore-python", "-c", "--config", "--no-cache")))) $completer.AddParams($AllCommands, $false) } } diff --git a/src/pdm/cli/completions/pdm.zsh b/src/pdm/cli/completions/pdm.zsh index 14356b1df4..c538c36ad1 100644 --- a/src/pdm/cli/completions/pdm.zsh +++ b/src/pdm/cli/completions/pdm.zsh @@ -46,6 +46,7 @@ _pdm() { {-c,--config}'[Specify another config file path\[env var: PDM_CONFIG_FILE\]]' \ {-V,--version}'[Show the version and exit]' \ {-I,--ignore-python}'[Ignore the Python path saved in .pdm-python]' \ + '--no-cache:Disable the cache for the current command. [env var: PDM_NO_CACHE]' \ '--pep582:Print the command line to be eval by the shell:shell:(zsh bash fish tcsh csh)' \ '*:: :->_subcmds' \ && return 0 diff --git a/src/pdm/cli/options.py b/src/pdm/cli/options.py index 60cf0d9b34..a2dc935cba 100644 --- a/src/pdm/cli/options.py +++ b/src/pdm/cli/options.py @@ -152,6 +152,12 @@ def from_splitted_env(name: str, separator: str) -> list[str] | None: ) verbose_option.add_argument("-q", "--quiet", action="store_const", const=-1, dest="verbose", help="Suppress output") +no_cache_option = Option( + "--no-cache", + action="store_true", + default=os.getenv("PDM_NO_CACHE"), + help="Disable the cache for the current command. [env var: PDM_NO_CACHE]", +) dry_run_option = Option( "--dry-run", diff --git a/src/pdm/core.py b/src/pdm/core.py index 6678635364..319d3ca5cf 100644 --- a/src/pdm/core.py +++ b/src/pdm/core.py @@ -23,7 +23,7 @@ from pdm import termui from pdm.__version__ import __version__ -from pdm.cli.options import ignore_python_option, pep582_option, verbose_option +from pdm.cli.options import ignore_python_option, no_cache_option, pep582_option, verbose_option from pdm.cli.utils import ArgumentParser, ErrorArgumentParser from pdm.compat import importlib_metadata from pdm.exceptions import PdmArgumentError, PdmUsageError @@ -89,6 +89,7 @@ def init_parser(self) -> None: help="Specify another config file path [env var: PDM_CONFIG_FILE] ", ) verbose_option.add_to_parser(self.parser) + no_cache_option.add_to_parser(self.parser) ignore_python_option.add_to_parser(self.parser) pep582_option.add_to_parser(self.parser) @@ -149,6 +150,10 @@ def handle(self, project: Project, options: argparse.Namespace) -> None: command = cast("BaseCommand | None", getattr(options, "command", None)) self.config_settings = getattr(options, "config_setting", None) + + if options.no_cache: + project.cache_dir = Path(self.create_temp_dir(prefix="pdm-cache-")) + hooks = HookManager(project, getattr(options, "skip", None)) hooks.try_emit("pre_invoke", command=command.name if command else None, options=options) diff --git a/src/pdm/project/core.py b/src/pdm/project/core.py index 2e681d37d6..24ca52ac1d 100644 --- a/src/pdm/project/core.py +++ b/src/pdm/project/core.py @@ -77,6 +77,7 @@ def __init__( self._lockfile: Lockfile | None = None self._environment: BaseEnvironment | None = None self._python: PythonInfo | None = None + self._cache_dir: Path | None = None self.core = core if global_config is None: @@ -587,7 +588,13 @@ def backend(self) -> BuildBackend: @property def cache_dir(self) -> Path: - return Path(self.config.get("cache_dir", "")).expanduser() + if self._cache_dir is None: + self._cache_dir = Path(self.config.get("cache_dir", "")).expanduser() + return self._cache_dir + + @cache_dir.setter + def cache_dir(self, value: Path) -> None: + self._cache_dir = value def cache(self, name: str) -> Path: path = self.cache_dir / name diff --git a/tests/cli/test_add.py b/tests/cli/test_add.py index 0b2c0c4f09..564938e7a9 100644 --- a/tests/cli/test_add.py +++ b/tests/cli/test_add.py @@ -321,3 +321,12 @@ def test_add_update_reuse_installed_config(project, working_set, repository, pdm pdm(["add", "foo"], obj=project, strict=True) locked_candidates = project.locked_repository.all_candidates assert locked_candidates["foo"].version == "1.0.0" + + +def test_add_disable_cache(project, pdm, working_set): + cache_dir = project.cache_dir + pdm(["--no-cache", "add", "requests"], obj=project, strict=True) + assert "requests" in working_set + + files = [file for file in cache_dir.rglob("*") if file.is_file()] + assert not files