init.go

 1package config
 2
 3import (
 4	"fmt"
 5	"os"
 6	"path/filepath"
 7	"strings"
 8)
 9
10const (
11	// InitFlagFilename is the name of the file that indicates whether the project has been initialized
12	InitFlagFilename = "init"
13)
14
15// ProjectInitFlag represents the initialization status for a project directory
16type ProjectInitFlag struct {
17	Initialized bool `json:"initialized"`
18}
19
20// ProjectNeedsInitialization checks if the current project needs initialization
21func ProjectNeedsInitialization() (bool, error) {
22	if instance == nil {
23		return false, fmt.Errorf("config not loaded")
24	}
25
26	flagFilePath := filepath.Join(instance.Options.DataDirectory, InitFlagFilename)
27
28	// Check if the flag file exists
29	_, err := os.Stat(flagFilePath)
30	if err == nil {
31		return false, nil
32	}
33
34	if !os.IsNotExist(err) {
35		return false, fmt.Errorf("failed to check init flag file: %w", err)
36	}
37
38	// Check if any variation of CRUSH.md already exists in working directory
39	crushExists, err := crushMdExists(WorkingDirectory())
40	if err != nil {
41		return false, fmt.Errorf("failed to check for CRUSH.md files: %w", err)
42	}
43	if crushExists {
44		return false, nil
45	}
46
47	return true, nil
48}
49
50// crushMdExists checks if any case variation of crush.md exists in the directory
51func crushMdExists(dir string) (bool, error) {
52	entries, err := os.ReadDir(dir)
53	if err != nil {
54		return false, err
55	}
56
57	for _, entry := range entries {
58		if entry.IsDir() {
59			continue
60		}
61
62		name := strings.ToLower(entry.Name())
63		if name == "crush.md" {
64			return true, nil
65		}
66	}
67
68	return false, nil
69}
70
71// MarkProjectInitialized marks the current project as initialized
72func MarkProjectInitialized() error {
73	if instance == nil {
74		return fmt.Errorf("config not loaded")
75	}
76	flagFilePath := filepath.Join(instance.Options.DataDirectory, InitFlagFilename)
77
78	file, err := os.Create(flagFilePath)
79	if err != nil {
80		return fmt.Errorf("failed to create init flag file: %w", err)
81	}
82	defer file.Close()
83
84	return nil
85}