...
This commit is contained in:
212
src/git_interface_redesign_plan.md
Normal file
212
src/git_interface_redesign_plan.md
Normal file
@@ -0,0 +1,212 @@
|
||||
# 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
|
Reference in New Issue
Block a user