diff --git a/CHANGELOG.md b/CHANGELOG.md index a1929e6f..cc684b3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ 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`. + Current effects: + - `ls_specific_settings` defined in project configurations will only be applied for trusted projects - 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..8aa12542 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. @@ -199,9 +200,12 @@ Most users will not need to adjust these settings. ::: Under the key `ls_specific_settings` in `serena_config.yml`, you can you pass global per-language, -language server-specific configuration. You can use the same key in the project configuration files (`project.yml` +language server-specific configuration. + +You can use the same key in the project configuration files (`project.yml` and `project.local.yml` ) to override or extend the global settings for a specific project. -The settings are merged on top-level, meaning that project-level settings for a language will replace global settings for the same language. +The settings are merged on top-level, meaning that project-level settings for a language will replace global settings for the same language. +Note: Project-level settings are considered only for *trusted projects* (which are defined in the [global configuration](global-config)). Structure: 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..1ddc53ac 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. @@ -417,7 +425,15 @@ class Project(ToStringMixin): log.info(f"Creating language server manager for {self.project_root}") self._language_server_manager_init_error = None - ls_specific_settings = {**self.serena_config.ls_specific_settings, **self.project_config.ls_specific_settings} + ls_specific_settings = dict(self.serena_config.ls_specific_settings) + if self.project_config.ls_specific_settings: + if self.is_trusted(): + ls_specific_settings.update(self.project_config.ls_specific_settings) + else: + log.warning( + f"Project path {self.project_root} is not trusted, ignoring LS-specific settings from project configuration. " + "To trust the project, modify the trusted path patterns in the global configuration." + ) factory = LanguageServerFactory( project_root=self.project_root, project_data_path=self._serena_data_folder, diff --git a/src/serena/resources/project.template.yml b/src/serena/resources/project.template.yml index a4dddb37..a4dc26ee 100644 --- a/src/serena/resources/project.template.yml +++ b/src/serena/resources/project.template.yml @@ -54,8 +54,8 @@ ignore_all_files_in_gitignore: true # advanced configuration option allowing to configure language server-specific options. # Maps the language key to the options. -# Have a look at the docstring of the constructors of the LS implementations within solidlsp (e.g., for C# or PHP) to see which options are available. -# No documentation on options means no options are available. +# The settings are considered only if the project is trusted (see global configuration to define trusted projects). +# See https://oraios.github.io/serena/02-usage/050_configuration.html#language-server-specific-settings ls_specific_settings: {} # list of additional workspace folder paths for cross-package reference support (e.g. in monorepos). 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: []