diff --git a/CHANGELOG.md b/CHANGELOG.md index a9c71a00..9f2b13f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ Status of the `main` branch. Changes prior to the next official version change will appear here. * General: + - Add notion of trusted projects via new global configuration setting `trusted_project_path_patterns`. + Existing users are advised to edit this setting. - Fix `--project-from-cwd` hijacking git worktrees nested under a Serena project. `find_project_root` now walks up in a single pass so the nearest project boundary wins (either a `.serena/project.yml` or a `.git`, including worktree/submodule pointer files), instead of preferring an ancestor's diff --git a/docs/02-usage/050_configuration.md b/docs/02-usage/050_configuration.md index 983924bb..b2e2978b 100644 --- a/docs/02-usage/050_configuration.md +++ b/docs/02-usage/050_configuration.md @@ -27,10 +27,11 @@ Some of the configurable settings include: this can also be [overridden per project](per-project-language-backend) * UI settings affecting the [Serena Dashboard and GUI tool](060_dashboard.md) * the set of tools to enable/disable by default - * the set of modes to use by default + * the set of [modes](modes) to use by default * tool execution parameters (timeout, max. answer length) * global ignore rules * logging settings + * the set of trusted project paths * advanced settings specific to individual language servers (see [below](ls-specific-settings)) The global configuration settings apply to all projects. diff --git a/src/serena/config/serena_config.py b/src/serena/config/serena_config.py index 4aaabdec..0b8fc673 100644 --- a/src/serena/config/serena_config.py +++ b/src/serena/config/serena_config.py @@ -32,6 +32,7 @@ from serena.constants import ( SERENA_MANAGED_DIR_NAME, ) from serena.util.inspection import determine_programming_language_composition +from serena.util.text_utils import glob_match from serena.util.yaml import YamlCommentNormalisation, load_yaml, normalise_yaml_comments, save_yaml, transfer_yaml_comments from solidlsp.ls_config import Language @@ -785,7 +786,16 @@ class SerenaConfig(SharedConfig, ModeSelectionDefinitionWithBaseModes): - "/projects-metadata/$projectFolderName/.serena" (stores data in a central location) """ + trusted_project_path_patterns: list[str] = field(default_factory=lambda: ["**"]) + """ + list of glob patterns for project root directories that are considered trusted. + The default "**" considers all project roots as trusted, which is necessary for backward compatibility. + The default will apply if a user does not yet have the setting, while new users will get the value + defined in the configuration template file. + """ + # settings with overridden defaults + language_backend: LanguageBackend = LanguageBackend.LSP """ the language backend to use for code understanding features @@ -799,6 +809,7 @@ class SerenaConfig(SharedConfig, ModeSelectionDefinitionWithBaseModes): If the budget is exceeded, Serena stops issuing further requests and returns partial info results. 0 disables the budget (no early stopping). Negative values are invalid. """ + # *** fields that are NOT mapped to/from the configuration file *** _loaded_commented_yaml: CommentedMap | None = None @@ -1273,3 +1284,16 @@ class SerenaConfig(SharedConfig, ModeSelectionDefinitionWithBaseModes): from serena.tools import JetBrainsPluginClient JetBrainsPluginClient.set_server_address(self.jetbrains_plugin_server_address) + + def is_trusted_project_path(self, project_root: str | Path) -> bool: + """ + Checks if the given project root path matches any of the trusted project root patterns. + + :param project_root: the path to the project root directory + :return: True if the project root is trusted, False otherwise + """ + project_root_str = str(project_root) + for pattern in self.trusted_project_path_patterns: + if glob_match(pattern, project_root_str): + return True + return False diff --git a/src/serena/project.py b/src/serena/project.py index f83a881d..de7c7ea2 100644 --- a/src/serena/project.py +++ b/src/serena/project.py @@ -146,6 +146,14 @@ class Project(ToStringMixin): def path_to_project_yml(self) -> str: return self.serena_config.get_project_yml_location(self.project_root) + def is_trusted(self) -> bool: + """ + Checks whether the project is trusted, based on the global configuration. + + :return: True if the project is trusted, False otherwise + """ + return self.serena_config.is_trusted_project_path(self.project_root) + def read_file(self, relative_path: str) -> str: """ Reads a file relative to the project root. diff --git a/src/serena/resources/serena_config.template.yml b/src/serena/resources/serena_config.template.yml index fb5c1d40..efa572ba 100644 --- a/src/serena/resources/serena_config.template.yml +++ b/src/serena/resources/serena_config.template.yml @@ -183,5 +183,20 @@ symbol_info_budget: 10 # Example for a central location: "/projects-metadata/$projectFolderName/.serena" project_serena_folder_location: "$projectDir/.serena" +# list of glob patterns for project root directories that are considered trusted. +# Some project settings will only be applied if the project is trusted. +# A glob pattern can contain the following: +# * matches any sequence of characters except path separators +# ** matches any sequence of characters including path separators +# ? 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. +# Example: +# trusted_project_path_patterns: +# - /home/user/projects/** +# - C:\Users\Anna\Dev\work\** +# The pattern "**" matches any project path, so it can be used to trust all projects. +trusted_project_path_patterns: [] + # the list of registered project paths (updated automatically). projects: []