Files
Fabric/plugins/tools/githelper/githelper.go
Kayvan Sylvan 096f40df68 feat: add prompt strategies and improve installation documentation
## CHANGES

- Add prompt strategies like Chain of Thought (CoT)
- Implement strategy selection with `--strategy` flag
- Improve README with platform-specific installation instructions
- Fix web interface documentation link
- Refactor git operations with new githelper package
- Add `--liststrategies` command to view available strategies
- Support applying strategies to system prompts
- Fix YouTube configuration check
- Improve error handling in session management
2025-03-15 00:30:30 -07:00

112 lines
2.7 KiB
Go

package githelper
import (
"fmt"
"io"
"os"
"path/filepath"
"strings"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/object"
"github.com/go-git/go-git/v5/storage/memory"
)
// FetchOptions defines options for fetching files from a git repo
type FetchOptions struct {
// RepoURL is the URL of the git repository
RepoURL string
// PathPrefix is the folder within the repo to extract (e.g. "patterns/")
PathPrefix string
// DestDir is where the files will be saved locally
DestDir string
// SingleDirectory if true, only fetch files directly in the specified directory
// without recursing into subdirectories
SingleDirectory bool
}
// FetchFilesFromRepo clones a git repo and extracts files from a specific folder
func FetchFilesFromRepo(opts FetchOptions) error {
// Ensure path prefix ends with slash
if !strings.HasSuffix(opts.PathPrefix, "/") {
opts.PathPrefix = opts.PathPrefix + "/"
}
// Clone the repository in memory
r, err := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{
URL: opts.RepoURL,
Depth: 1,
})
if err != nil {
return fmt.Errorf("failed to clone repository: %w", err)
}
// Get HEAD reference
ref, err := r.Head()
if err != nil {
return fmt.Errorf("failed to get repository HEAD: %w", err)
}
// Get commit object
commit, err := r.CommitObject(ref.Hash())
if err != nil {
return fmt.Errorf("failed to get commit: %w", err)
}
// Get the file tree
tree, err := commit.Tree()
if err != nil {
return fmt.Errorf("failed to get tree: %w", err)
}
// Ensure destination directory exists
if err := os.MkdirAll(opts.DestDir, 0755); err != nil {
return fmt.Errorf("failed to create destination directory: %w", err)
}
// Extract files from the tree
return tree.Files().ForEach(func(f *object.File) error {
// Only process files in the specified path
if !strings.HasPrefix(f.Name, opts.PathPrefix) {
return nil
}
// For SingleDirectory mode, skip files in subdirectories
if opts.SingleDirectory {
remainingPath := strings.TrimPrefix(f.Name, opts.PathPrefix)
if strings.Contains(remainingPath, "/") {
return nil
}
}
// Create local path for the file, removing the prefix
relativePath := strings.TrimPrefix(f.Name, opts.PathPrefix)
localPath := filepath.Join(opts.DestDir, relativePath)
// Ensure directory structure exists
if err := os.MkdirAll(filepath.Dir(localPath), 0755); err != nil {
return err
}
// Get file contents
reader, err := f.Reader()
if err != nil {
return err
}
defer reader.Close()
// Create and write to local file
file, err := os.Create(localPath)
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(file, reader)
return err
})
}