| 567 | |
| 568 | |
| 569 | def init_repo(repo_name: str, template: str, repo_path: Optional[str] = None): |
| 570 | import os |
| 571 | from pathlib import Path |
| 572 | from shutil import copytree |
| 573 | |
| 574 | from colorama import Fore, Style |
| 575 | |
| 576 | # Validate project name |
| 577 | if not is_valid_name(repo_name): |
| 578 | raise BadParameter( |
| 579 | message="Name should be alphanumeric values, underscores, and hyphens but not start with an underscore or hyphen", |
| 580 | param_hint="PROJECT_DIRECTORY", |
| 581 | ) |
| 582 | |
| 583 | # Determine where to create the repository |
| 584 | if repo_path: |
| 585 | # User specified a custom path |
| 586 | target_path = Path(repo_path).resolve() |
| 587 | target_path.mkdir(parents=True, exist_ok=True) |
| 588 | display_path = repo_path |
| 589 | else: |
| 590 | # Default behavior: create subdirectory with project name |
| 591 | target_path = Path(os.path.join(Path.cwd(), repo_name)) |
| 592 | target_path.mkdir(exist_ok=True) |
| 593 | display_path = repo_name |
| 594 | |
| 595 | repo_config_path = target_path / "feature_store.yaml" |
| 596 | |
| 597 | if repo_config_path.exists(): |
| 598 | print( |
| 599 | f"The directory {Style.BRIGHT + Fore.GREEN}{display_path}{Style.RESET_ALL} contains an existing feature " |
| 600 | f"store repository that may cause a conflict" |
| 601 | ) |
| 602 | print() |
| 603 | sys.exit(1) |
| 604 | |
| 605 | # Copy template directory |
| 606 | template_path = str(Path(Path(__file__).parent / "templates" / template).absolute()) |
| 607 | if not os.path.exists(template_path): |
| 608 | raise IOError(f"Could not find template {template}") |
| 609 | copytree(template_path, str(target_path), dirs_exist_ok=True) |
| 610 | |
| 611 | # Rename gitignore files back to .gitignore |
| 612 | for gitignore_path in target_path.rglob("gitignore"): |
| 613 | gitignore_path.rename(gitignore_path.with_name(".gitignore")) |
| 614 | |
| 615 | # Seed the repository |
| 616 | bootstrap_path = target_path / "bootstrap.py" |
| 617 | if os.path.exists(bootstrap_path): |
| 618 | import importlib.util |
| 619 | |
| 620 | spec = importlib.util.spec_from_file_location("bootstrap", str(bootstrap_path)) |
| 621 | assert isinstance(spec, ModuleSpec) |
| 622 | bootstrap = importlib.util.module_from_spec(spec) |
| 623 | assert isinstance(spec.loader, Loader) |
| 624 | spec.loader.exec_module(bootstrap) |
| 625 | bootstrap.bootstrap() # type: ignore |
| 626 | os.remove(bootstrap_path) |