diff --git a/CHANGELOG.md b/CHANGELOG.md index 7aeb6dbc..258ad2fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,10 @@ Status of the `main` branch. Changes prior to the next official version change w - Fix: process-tree cleanup signaled descendant language-server processes without waiting for them, which could leave grandchildren as zombies; cleanup now waits for the discovered descendants (#1464) - Fix: `read_only` restriction in project definition was not applied to base tool set when in single-project context (#1938) + - Docs: `trusted_project_path_patterns` now documents how to trust a single project. Trust is decided by + the project's root path, so a `/**` entry matches only paths below the root and therefore + trusts no project at all; the template now shows the bare root form alongside the parent-directory + glob (#2001) * CLI: - Fix: `project health-check` reported `Health check passed - All tools working correctly` and diff --git a/src/serena/resources/serena_config.template.yml b/src/serena/resources/serena_config.template.yml index ffdf1431..864d037c 100644 --- a/src/serena/resources/serena_config.template.yml +++ b/src/serena/resources/serena_config.template.yml @@ -210,9 +210,13 @@ project_serena_folder_location: "$projectDir/.serena" # ? matches any single character except path separators # [abc] matches any single character in the set (here: a, b, or c) # Path separators are normalised internally, so on Windows, both / and \ can be used in the patterns. +# A pattern is matched against the project's root path itself. To trust one specific project, therefore +# give its root path as-is: appending "/**" to it matches only paths *below* the root and consequently +# matches no project root at all. # Example: # trusted_project_path_patterns: -# - /home/user/projects/** +# - /opt/dev/projects/my_trusted_project # trusts exactly this project +# - /home/user/projects/** # trusts every project located below this directory # - C:\Users\Anna\Dev\work\** # The pattern "**" matches any project path, so it can be used to trust all projects. trusted_project_path_patterns: [] diff --git a/test/serena/config/test_serena_config.py b/test/serena/config/test_serena_config.py index 529667f7..e9a3c46d 100644 --- a/test/serena/config/test_serena_config.py +++ b/test/serena/config/test_serena_config.py @@ -765,3 +765,37 @@ class TestProjectConfigActivationCommand: data["activation_command_timeout"] = -10 with pytest.raises(ValueError, match="activation_command_timeout must be positive"): ProjectConfig._from_dict(data, local_override_keys=[]) + + +class TestTrustedProjectPathPatterns: + """Pins the trust semantics that `serena_config.template.yml` documents by example.""" + + @staticmethod + def _config(*patterns: str) -> SerenaConfig: + return SerenaConfig( + gui_log_window=False, + web_dashboard=False, + trusted_project_path_patterns=list(patterns), + ) + + def test_bare_project_root_trusts_that_project(self): + """The documented way to trust a single project: its root path, without a trailing glob.""" + root = "/opt/dev/projects/my_trusted_project" + assert self._config(root).is_trusted_project_path(root) + + def test_project_root_with_trailing_glob_trusts_nothing(self): + """`/**` matches only paths below the root, and trust is decided by the root itself. + + This is why the template documents the bare form; the difference is invisible otherwise. + """ + root = "/opt/dev/projects/my_trusted_project" + assert not self._config(root + "/**").is_trusted_project_path(root) + + def test_parent_directory_glob_trusts_projects_below_it(self): + parent = self._config("/home/user/projects/**") + assert parent.is_trusted_project_path("/home/user/projects/some_project") + assert not parent.is_trusted_project_path("/home/user/projects") + + def test_unrelated_path_is_not_trusted(self): + """Control: the patterns above are not vacuously true.""" + assert not self._config("/opt/dev/projects/my_trusted_project", "/home/user/projects/**").is_trusted_project_path("/somewhere/else")