diff --git a/src/serena/cli.py b/src/serena/cli.py index 2a8c4358..580815fe 100644 --- a/src/serena/cli.py +++ b/src/serena/cli.py @@ -18,7 +18,7 @@ from tqdm import tqdm from serena.agent import SerenaAgent from serena.config.context_mode import SerenaAgentContext, SerenaAgentMode -from serena.config.serena_config import LanguageBackend, ProjectConfig, SerenaConfig, SerenaPaths +from serena.config.serena_config import LanguageBackend, ProjectConfig, SerenaConfig, SerenaPaths, RegisteredProject from serena.constants import ( DEFAULT_CONTEXT, DEFAULT_MODES, @@ -521,7 +521,8 @@ class ProjectCommands(AutoRegisteringGroup): :raises FileExistsError: If project.yml already exists :raises ValueError: If an unsupported language is specified """ - yml_path = os.path.join(project_path, ProjectConfig.rel_path_to_project_yml()) + project_root = Path(project_path).resolve() + yml_path = ProjectConfig.path_to_project_yml(project_root) if os.path.exists(yml_path): raise FileExistsError(f"Project file {yml_path} already exists.") @@ -540,6 +541,15 @@ class ProjectCommands(AutoRegisteringGroup): yml_path = ProjectConfig.path_to_project_yml(project_path) languages_str = ", ".join([lang.value for lang in generated_conf.languages]) if generated_conf.languages else "N/A" click.echo(f"Generated project with languages {{{languages_str}}} at {yml_path}.") + + # add to SerenaConfig's list of registered projects + serena_config = SerenaConfig.from_config_file() + if serena_config.get_registered_project(str(project_root)) is None: + registered_project = RegisteredProject(str(project_root), generated_conf) + serena_config.projects.append(registered_project) + click.echo(f"Saving project registration to {serena_config}") + serena_config.save() + return generated_conf @staticmethod diff --git a/src/serena/config/serena_config.py b/src/serena/config/serena_config.py index 7bfbb3e8..9523cf05 100644 --- a/src/serena/config/serena_config.py +++ b/src/serena/config/serena_config.py @@ -613,14 +613,14 @@ class SerenaConfig(ToolInclusionDefinition, ToStringMixin): def project_names(self) -> list[str]: return sorted(project.project_config.project_name for project in self.projects) - def get_project(self, project_root_or_name: str) -> Optional["Project"]: + def get_registered_project(self, project_root_or_name: str) -> Optional[RegisteredProject]: # look for project by name project_candidates = [] for project in self.projects: if project.project_config.project_name == project_root_or_name: project_candidates.append(project) if len(project_candidates) == 1: - return project_candidates[0].get_project_instance() + return project_candidates[0] elif len(project_candidates) > 1: raise ValueError( f"Multiple projects found with name '{project_root_or_name}'. Please activate it by location instead. " @@ -630,13 +630,21 @@ class SerenaConfig(ToolInclusionDefinition, ToStringMixin): if os.path.isdir(project_root_or_name): for project in self.projects: if project.matches_root_path(project_root_or_name): - return project.get_project_instance() + return project return None + def get_project(self, project_root_or_name: str) -> Optional["Project"]: + registered_project = self.get_registered_project(project_root_or_name) + if registered_project is None: + return None + else: + return registered_project.get_project_instance() + def add_project_from_path(self, project_root: Path | str) -> "Project": """ - Add a project to the Serena configuration from a given path. Will raise a FileExistsError if a - project already exists at the path. + Add a new project to the Serena configuration from a given path, auto-generating the project + with defaults if it does not exist. + Will raise a FileExistsError if a project already exists at the path. :param project_root: the path to the project to add :return: the project that was added