# Git Interface Redesign Plan ## Current Understanding The current git interface consists of standalone functions like `git_clone`, `git_list`, `git_update`, etc. We want to replace this with an object-oriented interface using a builder pattern that allows for method chaining. ## New Interface Design ### Core Components ```mermaid classDiagram class GitTree { +String base_path +new(base_path: &str) Result +list() Result, GitError> +find(pattern: &str) Result, GitError> +get(path_pattern: &str) Result, GitError> } class GitRepo { +String path +pull() Result +reset() Result +push() Result +commit(message: &str) Result +has_changes() Result } GitTree --> GitRepo : creates ``` ### Implementation Details 1. **GitTree Class**: - Constructor takes a base path parameter that specifies where all git repositories will be located - Methods for listing and finding repositories - A `get()` method that returns one or more GitRepo objects based on a path pattern - The `get()` method can also accept a URL (git or http format) and will clone the repository if it doesn't exist 2. **GitRepo Class**: - Represents a single git repository - Methods for common git operations: pull, reset, push, commit - Each method returns a Result containing either the GitRepo object (for chaining) or an error - If an operation fails, subsequent operations in the chain are skipped 3. **Error Handling**: - Each method returns a Result type for immediate error handling - Errors are propagated up the call chain - The existing GitError enum will be reused ## Implementation Plan ### 1. Create the GitTree and GitRepo Structs in git.rs ```rust pub struct GitTree { base_path: String, } pub struct GitRepo { path: String, } ``` ### 2. Implement the GitTree Methods ```rust impl GitTree { pub fn new(base_path: &str) -> Result { // Validate the base path // Create the directory if it doesn't exist Ok(GitTree { base_path: base_path.to_string(), }) } pub fn list(&self) -> Result, GitError> { // List all git repositories under the base path } pub fn find(&self, pattern: &str) -> Result, GitError> { // Find repositories matching the pattern } pub fn get(&self, path_pattern: &str) -> Result, GitError> { // Find repositories matching the pattern // Return GitRepo objects for each match } } ``` ### 3. Implement the GitRepo Methods ```rust impl GitRepo { pub fn pull(&self) -> Result { // Pull the latest changes // Return self for chaining or an error } pub fn reset(&self) -> Result { // Reset any local changes // Return self for chaining or an error } pub fn push(&self) -> Result { // Push changes to the remote // Return self for chaining or an error } pub fn commit(&self, message: &str) -> Result { // Commit changes with the given message // Return self for chaining or an error } pub fn has_changes(&self) -> Result { // Check if the repository has uncommitted changes } } ``` ### 4. Update the Rhai Wrappers in rhai/git.rs ```rust // Register the GitTree and GitRepo types with Rhai pub fn register_git_module(engine: &mut Engine) -> Result<(), Box> { // Register the GitTree type engine.register_type::(); engine.register_fn("new", git_tree_new); // Register GitTree methods engine.register_fn("list", git_tree_list); engine.register_fn("find", git_tree_find); engine.register_fn("get", git_tree_get); // Register GitRepo methods engine.register_type::(); engine.register_fn("pull", git_repo_pull); engine.register_fn("reset", git_repo_reset); engine.register_fn("push", git_repo_push); engine.register_fn("commit", git_repo_commit); engine.register_fn("has_changes", git_repo_has_changes); Ok(()) } ``` ### 5. Update Tests and Examples - Update the test files to use the new interface - Create new examples demonstrating the builder pattern and method chaining ## Usage Examples ### Example 1: Basic Repository Operations ```rhai // Create a new GitTree object let git_tree = new("/home/user/code"); // List all repositories let repos = git_tree.list(); print(`Found ${repos.len()} repositories`); // Find repositories matching a pattern let matching = git_tree.find("my-project*"); print(`Found ${matching.len()} matching repositories`); // Get a repository and perform operations let repo = git_tree.get("my-project")[0]; let result = repo.pull().reset().commit("Update files").push(); ``` ### Example 2: Working with Multiple Repositories ```rhai // Create a new GitTree object let git_tree = new("/home/user/code"); // Get all repositories matching a pattern let repos = git_tree.get("project*"); print(`Found ${repos.len()} matching repositories`); // Perform operations on all repositories for repo in repos { let result = repo.pull(); if result.is_ok() { print(`Successfully pulled ${repo.path}`); } else { print(`Failed to pull ${repo.path}: ${result.error}`); } } ``` ### Example 3: Cloning a Repository ```rhai // Create a new GitTree object let git_tree = new("/home/user/code"); // Clone a repository by URL let repos = git_tree.get("https://github.com/username/repo.git"); let repo = repos[0]; print(`Repository cloned to: ${repo.path}`); ``` ## Migration Strategy 1. Implement the new interface in git.rs and rhai/git.rs 2. Update all tests and examples to use the new interface 3. Remove the old standalone functions