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

212 lines
6.0 KiB
Markdown

# 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<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
```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<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
```rust
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
```rust
// 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
```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