Files
herolib_rust/src/git_interface_redesign_plan.md
2025-04-05 04:45:56 +02:00

6.0 KiB

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

classDiagram
    class GitTree {
        +String base_path
        +new(base_path: &str) Result<GitTree, GitError>
        +list() Result<Vec<String>, GitError>
        +find(pattern: &str) Result<Vec<String>, GitError>
        +get(path_pattern: &str) Result<Vec<GitRepo>, GitError>
    }
    
    class GitRepo {
        +String path
        +pull() Result<GitRepo, GitError>
        +reset() Result<GitRepo, GitError>
        +push() Result<GitRepo, GitError>
        +commit(message: &str) Result<GitRepo, GitError>
        +has_changes() Result<bool, GitError>
    }
    
    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

pub struct GitTree {
    base_path: String,
}

pub struct GitRepo {
    path: String,
}

2. Implement the GitTree Methods

impl GitTree {
    pub fn new(base_path: &str) -> Result<Self, GitError> {
        // 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<Vec<String>, GitError> {
        // List all git repositories under the base path
    }
    
    pub fn find(&self, pattern: &str) -> Result<Vec<String>, GitError> {
        // Find repositories matching the pattern
    }
    
    pub fn get(&self, path_pattern: &str) -> Result<Vec<GitRepo>, GitError> {
        // Find repositories matching the pattern
        // Return GitRepo objects for each match
    }
}

3. Implement the GitRepo Methods

impl GitRepo {
    pub fn pull(&self) -> Result<Self, GitError> {
        // Pull the latest changes
        // Return self for chaining or an error
    }
    
    pub fn reset(&self) -> Result<Self, GitError> {
        // Reset any local changes
        // Return self for chaining or an error
    }
    
    pub fn push(&self) -> Result<Self, GitError> {
        // Push changes to the remote
        // Return self for chaining or an error
    }
    
    pub fn commit(&self, message: &str) -> Result<Self, GitError> {
        // Commit changes with the given message
        // Return self for chaining or an error
    }
    
    pub fn has_changes(&self) -> Result<bool, GitError> {
        // Check if the repository has uncommitted changes
    }
}

4. Update the Rhai Wrappers in rhai/git.rs

// Register the GitTree and GitRepo types with Rhai
pub fn register_git_module(engine: &mut Engine) -> Result<(), Box<EvalAltResult>> {
    // Register the GitTree type
    engine.register_type::<GitTree>();
    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::<GitRepo>();
    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

// 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

// 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

// 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