Files
onyx-prebootstrap/internal/core/repository.go
Tanishq Dubey a0f80c5c7d
Some checks failed
CI / Test (pull_request) Failing after 6s
CI / Build (pull_request) Failing after 7s
CI / Lint (pull_request) Failing after 13s
milestone 2 complete
2025-10-10 19:03:31 -04:00

179 lines
4.6 KiB
Go

package core
import (
"fmt"
"os"
"path/filepath"
"time"
"github.com/go-git/go-git/v5"
)
// OnyxRepository implements the Repository interface
type OnyxRepository struct {
gitRepo *git.Repository
onyxPath string
gitPath string
metadata *OnyxMetadata
}
// Open opens an existing Onyx repository at the given path
func Open(path string) (*OnyxRepository, error) {
// Resolve to absolute path
absPath, err := filepath.Abs(path)
if err != nil {
return nil, fmt.Errorf("failed to resolve path: %w", err)
}
// Check if .git directory exists
gitPath := filepath.Join(absPath, ".git")
if _, err := os.Stat(gitPath); os.IsNotExist(err) {
return nil, fmt.Errorf("not a git repository (no .git directory found)")
}
// Check if .onx directory exists
onyxPath := filepath.Join(absPath, ".onx")
if _, err := os.Stat(onyxPath); os.IsNotExist(err) {
return nil, fmt.Errorf("not an onyx repository (no .onx directory found)")
}
// Open the Git repository
gitRepo, err := git.PlainOpen(absPath)
if err != nil {
return nil, fmt.Errorf("failed to open git repository: %w", err)
}
// Load Onyx metadata
metadata := &OnyxMetadata{
Version: "1.0.0",
Created: time.Now(), // TODO: Load from .onx/metadata file
OnyxPath: onyxPath,
}
return &OnyxRepository{
gitRepo: gitRepo,
onyxPath: onyxPath,
gitPath: gitPath,
metadata: metadata,
}, nil
}
// Init initializes a new Onyx repository at the given path
func (r *OnyxRepository) Init(path string) error {
// Resolve to absolute path
absPath, err := filepath.Abs(path)
if err != nil {
return fmt.Errorf("failed to resolve path: %w", err)
}
// Check if directory exists, create if it doesn't
if _, err := os.Stat(absPath); os.IsNotExist(err) {
if err := os.MkdirAll(absPath, 0755); err != nil {
return fmt.Errorf("failed to create directory: %w", err)
}
}
// Initialize Git repository if it doesn't exist
gitPath := filepath.Join(absPath, ".git")
if _, err := os.Stat(gitPath); os.IsNotExist(err) {
_, err := git.PlainInit(absPath, false)
if err != nil {
return fmt.Errorf("failed to initialize git repository: %w", err)
}
}
// Create .onx directory structure
onyxPath := filepath.Join(absPath, ".onx")
if err := os.MkdirAll(onyxPath, 0755); err != nil {
return fmt.Errorf("failed to create .onx directory: %w", err)
}
// Create subdirectories
subdirs := []string{"rerere_cache"}
for _, subdir := range subdirs {
subdirPath := filepath.Join(onyxPath, subdir)
if err := os.MkdirAll(subdirPath, 0755); err != nil {
return fmt.Errorf("failed to create %s directory: %w", subdir, err)
}
}
// Initialize oplog file
oplogPath := filepath.Join(onyxPath, "oplog")
if _, err := os.Stat(oplogPath); os.IsNotExist(err) {
if err := os.WriteFile(oplogPath, []byte{}, 0644); err != nil {
return fmt.Errorf("failed to create oplog file: %w", err)
}
}
// Initialize workstreams.json
workstreamsPath := filepath.Join(onyxPath, "workstreams.json")
if _, err := os.Stat(workstreamsPath); os.IsNotExist(err) {
initialContent := []byte("{\"workstreams\":{}}\n")
if err := os.WriteFile(workstreamsPath, initialContent, 0644); err != nil {
return fmt.Errorf("failed to create workstreams.json: %w", err)
}
}
// Open the repository
gitRepo, err := git.PlainOpen(absPath)
if err != nil {
return fmt.Errorf("failed to open git repository: %w", err)
}
// Set up the repository instance
r.gitRepo = gitRepo
r.onyxPath = onyxPath
r.gitPath = gitPath
r.metadata = &OnyxMetadata{
Version: "1.0.0",
Created: time.Now(),
OnyxPath: onyxPath,
}
return nil
}
// GetGitRepo returns the underlying Git repository
func (r *OnyxRepository) GetGitRepo() *git.Repository {
return r.gitRepo
}
// GetOnyxMetadata returns Onyx-specific metadata
func (r *OnyxRepository) GetOnyxMetadata() *OnyxMetadata {
return r.metadata
}
// Close releases any resources held by the repository
func (r *OnyxRepository) Close() error {
// Currently, go-git doesn't require explicit closing
// This method is here for future-proofing
return nil
}
// IsOnyxRepo checks if the given path is an Onyx repository
func IsOnyxRepo(path string) bool {
absPath, err := filepath.Abs(path)
if err != nil {
return false
}
// Check for both .git and .onx directories
gitPath := filepath.Join(absPath, ".git")
onyxPath := filepath.Join(absPath, ".onx")
_, gitErr := os.Stat(gitPath)
_, onyxErr := os.Stat(onyxPath)
return gitErr == nil && onyxErr == nil
}
// GetOnyxPath returns the path to the .onx directory
func (r *OnyxRepository) GetOnyxPath() string {
return r.onyxPath
}
// GetGitPath returns the path to the .git directory
func (r *OnyxRepository) GetGitPath() string {
return r.gitPath
}