1package git
2
3import (
4	"bytes"
5	"fmt"
6	"path/filepath"
7)
8
9// Status represents the current status of a Worktree.
10// The key of the map is the path of the file.
11type Status map[string]*FileStatus
12
13// File returns the FileStatus for a given path, if the FileStatus doesn't
14// exists a new FileStatus is added to the map using the path as key.
15func (s Status) File(path string) *FileStatus {
16	if _, ok := (s)[path]; !ok {
17		s[path] = &FileStatus{Worktree: Untracked, Staging: Untracked}
18	}
19
20	return s[path]
21}
22
23// IsUntracked checks if file for given path is 'Untracked'
24func (s Status) IsUntracked(path string) bool {
25	stat, ok := (s)[filepath.ToSlash(path)]
26	return ok && stat.Worktree == Untracked
27}
28
29// IsClean returns true if all the files are in Unmodified status.
30func (s Status) IsClean() bool {
31	for _, status := range s {
32		if status.Worktree != Unmodified || status.Staging != Unmodified {
33			return false
34		}
35	}
36
37	return true
38}
39
40func (s Status) String() string {
41	buf := bytes.NewBuffer(nil)
42	for path, status := range s {
43		if status.Staging == Unmodified && status.Worktree == Unmodified {
44			continue
45		}
46
47		if status.Staging == Renamed {
48			path = fmt.Sprintf("%s -> %s", path, status.Extra)
49		}
50
51		fmt.Fprintf(buf, "%c%c %s\n", status.Staging, status.Worktree, path)
52	}
53
54	return buf.String()
55}
56
57// FileStatus contains the status of a file in the worktree
58type FileStatus struct {
59	// Staging is the status of a file in the staging area
60	Staging StatusCode
61	// Worktree is the status of a file in the worktree
62	Worktree StatusCode
63	// Extra contains extra information, such as the previous name in a rename
64	Extra string
65}
66
67// StatusCode status code of a file in the Worktree
68type StatusCode byte
69
70const (
71	Unmodified         StatusCode = ' '
72	Untracked          StatusCode = '?'
73	Modified           StatusCode = 'M'
74	Added              StatusCode = 'A'
75	Deleted            StatusCode = 'D'
76	Renamed            StatusCode = 'R'
77	Copied             StatusCode = 'C'
78	UpdatedButUnmerged StatusCode = 'U'
79)
80