milestone 2 complete
Some checks failed
CI / Test (pull_request) Failing after 6s
CI / Build (pull_request) Failing after 7s
CI / Lint (pull_request) Failing after 13s

This commit is contained in:
2025-10-10 19:03:31 -04:00
parent 4a517d104a
commit a0f80c5c7d
19 changed files with 2225 additions and 145 deletions

View File

@ -24,6 +24,8 @@ log for universal undo functionality.`,
// Add commands
rootCmd.AddCommand(commands.NewInitCmd())
rootCmd.AddCommand(commands.NewUndoCmd())
rootCmd.AddCommand(commands.NewDaemonCmd())
rootCmd.AddCommand(commands.NewSaveCmd())
// Execute the root command
if err := rootCmd.Execute(); err != nil {

127
cmd/onxd/main.go Normal file
View File

@ -0,0 +1,127 @@
package main
import (
"fmt"
"log"
"os"
"os/signal"
"path/filepath"
"syscall"
"time"
"git.dws.rip/DWS/onyx/internal/core"
"git.dws.rip/DWS/onyx/internal/daemon"
"github.com/spf13/cobra"
)
var (
version = "0.1.0"
repoPath string
interval time.Duration
debounce time.Duration
pidFile string
)
func main() {
rootCmd := &cobra.Command{
Use: "onxd",
Short: "Onyx Daemon - Transparent versioning daemon",
Long: `The Onyx daemon monitors your repository for changes and automatically
creates snapshots of your work. This enables transparent versioning without
manual commits.`,
Version: version,
RunE: runDaemon,
}
// Add flags
rootCmd.PersistentFlags().StringVarP(&repoPath, "repo", "r", ".", "Path to the Onyx repository")
rootCmd.PersistentFlags().DurationVarP(&interval, "interval", "i", 1*time.Second, "Ticker interval for periodic checks")
rootCmd.PersistentFlags().DurationVarP(&debounce, "debounce", "d", 500*time.Millisecond, "Debounce duration for filesystem events")
if err := rootCmd.Execute(); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
}
func runDaemon(cmd *cobra.Command, args []string) error {
// Resolve repository path
absPath, err := filepath.Abs(repoPath)
if err != nil {
return fmt.Errorf("failed to resolve repository path: %w", err)
}
// Check if this is an Onyx repository
if !core.IsOnyxRepo(absPath) {
return fmt.Errorf("not an Onyx repository: %s", absPath)
}
// Open the repository
repo, err := core.Open(absPath)
if err != nil {
return fmt.Errorf("failed to open repository: %w", err)
}
defer repo.Close()
// Create daemon configuration
config := &daemon.Config{
Debounce: debounce,
TickerInterval: interval,
RepoPath: absPath,
}
// Create the daemon
d, err := daemon.New(repo, config)
if err != nil {
return fmt.Errorf("failed to create daemon: %w", err)
}
// Write PID file
pidFile = filepath.Join(repo.GetOnyxPath(), "daemon.pid")
if err := writePIDFile(pidFile); err != nil {
return fmt.Errorf("failed to write PID file: %w", err)
}
defer os.Remove(pidFile)
// Set up signal handlers
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
// Start the daemon
if err := d.Start(); err != nil {
return fmt.Errorf("failed to start daemon: %w", err)
}
log.Printf("Onyx daemon started (PID: %d)", os.Getpid())
log.Printf("Watching repository: %s", absPath)
log.Printf("Debounce: %v, Interval: %v", debounce, interval)
// Wait for shutdown signal
sig := <-sigChan
log.Printf("Received signal: %v", sig)
// Stop the daemon
if err := d.Stop(); err != nil {
return fmt.Errorf("failed to stop daemon: %w", err)
}
return nil
}
// writePIDFile writes the current process ID to a file
func writePIDFile(path string) error {
pid := os.Getpid()
return os.WriteFile(path, []byte(fmt.Sprintf("%d\n", pid)), 0644)
}
// readPIDFile reads the process ID from a file
func readPIDFile(path string) (int, error) {
data, err := os.ReadFile(path)
if err != nil {
return 0, err
}
var pid int
_, err = fmt.Sscanf(string(data), "%d", &pid)
return pid, err
}