1package cli
2
3import (
4 "fmt"
5
6 "arche/internal/issuedb"
7 "arche/internal/wc"
8
9 "github.com/spf13/cobra"
10)
11
12var statusCmd = &cobra.Command{
13 Use: "status",
14 Aliases: []string{"st"},
15 Short: "Show working copy state, conflicts, and current change",
16 RunE: func(cmd *cobra.Command, args []string) error {
17 r := openRepo()
18 defer r.Close()
19
20 head, err := r.Head()
21 if err != nil {
22 return err
23 }
24
25 headCommit, commitID, err := r.HeadCommit()
26 if err != nil {
27 return err
28 }
29
30 phase, _ := r.Store.GetPhase(commitID)
31
32 w := wc.New(r)
33 changes, err := w.Status()
34 if err != nil {
35 return err
36 }
37 conflicts, _ := r.Store.ListConflicts()
38
39 empty := ""
40 if len(changes) == 0 && len(conflicts) == 0 {
41 empty = ", empty"
42 }
43 fmt.Printf("Working copy: %s (%s%s)\n", head, phase, empty)
44 fmt.Printf("Commit: %x %s\n", commitID[:8], headCommit.Message)
45
46 bms, _ := r.Store.ListBookmarks()
47 var bmNames []string
48 for _, bm := range bms {
49 if bm.CommitID == commitID {
50 bmNames = append(bmNames, bm.Name)
51 }
52 }
53 if len(bmNames) > 0 {
54 fmt.Printf("Bookmarks: %v\n", bmNames)
55 } else if len(bms) == 0 {
56 fmt.Println("No bookmark. Run arche snap to record your first commit.")
57 } else {
58 fmt.Println("No bookmark points here. Create one with: arche bookmark set <name>")
59 }
60 fmt.Println()
61
62 conflictSet := make(map[string]bool, len(conflicts))
63 for _, p := range conflicts {
64 conflictSet[p] = true
65 }
66
67 if len(changes) == 0 && len(conflicts) == 0 {
68 fmt.Println("Nothing changed (working copy matches commit).")
69 return nil
70 }
71
72 for _, f := range changes {
73 var label string
74 if conflictSet[f.Path] {
75 label = "conflict"
76 } else {
77 switch f.Status {
78 case 'M':
79 label = "modified"
80 case 'A':
81 label = "added "
82 case 'D':
83 label = "deleted "
84 default:
85 label = "unknown "
86 }
87 }
88 fmt.Printf(" %s %s\n", label, f.Path)
89 }
90
91 for _, p := range conflicts {
92 if !func() bool {
93 for _, f := range changes {
94 if f.Path == p {
95 return true
96 }
97 }
98 return false
99 }() {
100 fmt.Printf(" conflict %s\n", p)
101 }
102 }
103 if len(conflicts) > 0 {
104 fmt.Printf("\n%d unresolved conflict(s). Run 'arche resolve <path>' after editing.\n", len(conflicts))
105 }
106
107 idb, err := issuedb.Open(r.ArcheDir())
108 if err == nil {
109 defer idb.Close()
110 stubs, err := idb.Issues.ListIssues()
111 if err == nil {
112 var bodyConflicts int
113 for _, st := range stubs {
114 issue, err := idb.Issues.GetIssue(st.ID)
115 if err == nil && issue.BodyConflict != nil {
116 if bodyConflicts == 0 {
117 fmt.Println()
118 }
119 fmt.Printf(" issue conflict %s %s\n", st.ID[:8], st.Title)
120 bodyConflicts++
121 }
122 }
123 if bodyConflicts > 0 {
124 fmt.Printf("%d issue body conflict(s). Resolve via 'arche ui'.\n", bodyConflicts)
125 }
126 }
127 }
128
129 return nil
130 },
131}