Skip to content

Commit 18309a0

Browse files
committed
Uninit and Clean CLI commands
- Uninit removes GTM tracking for a git repo - Clean removes uncommitted time data
1 parent d9f710e commit 18309a0

8 files changed

Lines changed: 504 additions & 19 deletions

File tree

command/clean.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package command
2+
3+
import (
4+
"flag"
5+
"fmt"
6+
"os"
7+
"strings"
8+
9+
"github.com/git-time-metric/gtm/project"
10+
"github.com/mitchellh/cli"
11+
)
12+
13+
type CleanCmd struct {
14+
}
15+
16+
func NewClean() (cli.Command, error) {
17+
return CleanCmd{}, nil
18+
}
19+
20+
func (v CleanCmd) Help() string {
21+
return v.Synopsis()
22+
}
23+
24+
func (v CleanCmd) Run(args []string) int {
25+
26+
cleanFlags := flag.NewFlagSet("clean", flag.ExitOnError)
27+
yes := cleanFlags.Bool(
28+
"yes",
29+
false,
30+
"Automatically confirm yes for cleaning uncommitted time data")
31+
if err := cleanFlags.Parse(os.Args[2:]); err != nil {
32+
fmt.Println(err)
33+
return 1
34+
}
35+
36+
confirm := *yes
37+
if !confirm {
38+
var response string
39+
fmt.Printf("\nClean uncommitted time data (y/n)? ")
40+
_, err := fmt.Scanln(&response)
41+
if err != nil {
42+
fmt.Println(err)
43+
return 1
44+
}
45+
confirm = strings.TrimSpace(strings.ToLower(response)) == "y"
46+
}
47+
48+
if confirm {
49+
var (
50+
m string
51+
err error
52+
)
53+
if m, err = project.Clean(); err != nil {
54+
fmt.Println(err)
55+
return 1
56+
}
57+
fmt.Println(m)
58+
}
59+
return 0
60+
}
61+
62+
func (v CleanCmd) Synopsis() string {
63+
return `
64+
Usage: gtm clean [-yes]
65+
Cleans uncommitted time data by removing all event and metric files from the .gtm directory
66+
`
67+
}

command/report.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func (r ReportCmd) Run(args []string) int {
6565
commits = append(commits, a)
6666
}
6767

68-
// if running from within a MINGW console isatty does not work
68+
// TODO: if running from within a MINGW console isatty does not work
6969
// https://github.com/mintty/mintty/issues/482
7070
if !isatty.IsTerminal(os.Stdin.Fd()) && len(commits) == 0 && *limit == 0 {
7171
scanner := bufio.NewScanner(os.Stdin)

command/uninit.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package command
2+
3+
import (
4+
"flag"
5+
"fmt"
6+
"os"
7+
"strings"
8+
9+
"github.com/git-time-metric/gtm/project"
10+
"github.com/mitchellh/cli"
11+
)
12+
13+
type UninitCmd struct {
14+
}
15+
16+
func NewUninit() (cli.Command, error) {
17+
return UninitCmd{}, nil
18+
}
19+
20+
func (v UninitCmd) Help() string {
21+
return v.Synopsis()
22+
}
23+
24+
func (v UninitCmd) Run(args []string) int {
25+
26+
uninitFlags := flag.NewFlagSet("uninit", flag.ExitOnError)
27+
yes := uninitFlags.Bool(
28+
"yes",
29+
false,
30+
"Automatically confirm yes to remove GTM tracking for the current Git repository")
31+
if err := uninitFlags.Parse(os.Args[2:]); err != nil {
32+
fmt.Println(err)
33+
return 1
34+
}
35+
36+
confirm := *yes
37+
if !confirm {
38+
var response string
39+
fmt.Printf("\nRemove GTM tracking for the current git repository (y/n)? ")
40+
_, err := fmt.Scanln(&response)
41+
if err != nil {
42+
fmt.Println(err)
43+
return 1
44+
}
45+
confirm = strings.TrimSpace(strings.ToLower(response)) == "y"
46+
}
47+
48+
if confirm {
49+
var (
50+
m string
51+
err error
52+
)
53+
if m, err = project.Uninitialize(); err != nil {
54+
fmt.Println(err)
55+
return 1
56+
}
57+
fmt.Println(m)
58+
}
59+
return 0
60+
}
61+
62+
func (v UninitCmd) Synopsis() string {
63+
return `
64+
Usage: gtm uninit [-yes]
65+
Remove GTM tracking for the current git repository
66+
Note - this removes uncommitted time data but does not remove time data that is committed
67+
`
68+
}

command/verify.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ func (v VerifyCmd) Synopsis() string {
4141
return `
4242
Usage: gtm verify <version constraint>
4343
Verify gtm satisfies the version constraint
44+
This is typically invoked by plug-ins to determine if GTM needs to be upgraded
4445
`
4546
}
4647

main.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import (
99
"github.com/mitchellh/cli"
1010
)
1111

12-
var Version string = "0.0.0"
12+
// Version is the released version set during the release build process
13+
var Version = "0.0.0"
1314

1415
func main() {
1516
c := cli.NewCLI("gtm", Version)
@@ -21,6 +22,8 @@ func main() {
2122
"report": command.NewReport,
2223
"status": command.NewStatus,
2324
"verify": command.NewVerify(Version),
25+
"uninit": command.NewUninit,
26+
"clean": command.NewClean,
2427
}
2528

2629
exitStatus, err := c.Run()

project/project.go

Lines changed: 125 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ import (
44
"bytes"
55
"errors"
66
"fmt"
7+
"io/ioutil"
78
"log"
89
"os"
910
"path/filepath"
11+
"strings"
1012
"text/template"
1113
"time"
1214

@@ -45,6 +47,19 @@ const (
4547
const initMsgTpl string = `
4648
{{print "Git Time Metric initialized for " (.ProjectPath) | printf (.HeaderFormat) }}
4749
50+
{{ range $hook, $command := .GitHooks -}}
51+
{{- $hook | printf "%16s" }}: {{ $command }}
52+
{{ end -}}
53+
{{ range $key, $val := .GitConfig -}}
54+
{{- $key | printf "%16s" }}: {{ $val }}
55+
{{end -}}
56+
{{ print ".gitignore:" | printf "%17s" }} {{ .GitIgnore }}
57+
`
58+
const removeMsgTpl string = `
59+
{{print "Git Time Metric uninitialized for " (.ProjectPath) | printf (.HeaderFormat) }}
60+
61+
The following items have been removed.
62+
4863
{{ range $hook, $command := .GitHooks -}}
4964
{{- $hook | printf "%16s" }}: {{ $command }}
5065
{{ end -}}
@@ -60,35 +75,39 @@ var Now = func() time.Time { return time.Now() }
6075

6176
// Initialize initializes a git repo for time tracking
6277
func Initialize() (string, error) {
63-
var fp string
64-
6578
wd, err := os.Getwd()
6679
if err != nil {
6780
return "", err
6881
}
6982

70-
fp = filepath.Join(wd, ".git")
71-
if _, err := os.Stat(fp); os.IsNotExist(err) {
83+
projRoot, err := scm.RootPath(wd)
84+
if err != nil {
85+
return "", fmt.Errorf(
86+
"Unable to intialize Git Time Metric, Git repository not found in %s", projRoot)
87+
}
88+
89+
gitPath := filepath.Join(projRoot, ".git")
90+
if _, err := os.Stat(gitPath); os.IsNotExist(err) {
7291
return "", fmt.Errorf(
73-
"Unable to intialize Git Time Metric, Git repository not found in %s", wd)
92+
"Unable to intialize Git Time Metric, Git repository not found in %s", gitPath)
7493
}
7594

76-
fp = filepath.Join(wd, GTMDir)
77-
if _, err := os.Stat(fp); os.IsNotExist(err) {
78-
if err := os.MkdirAll(fp, 0700); err != nil {
95+
gtmPath := filepath.Join(projRoot, GTMDir)
96+
if _, err := os.Stat(gtmPath); os.IsNotExist(err) {
97+
if err := os.MkdirAll(gtmPath, 0700); err != nil {
7998
return "", err
8099
}
81100
}
82101

83-
if err := scm.SetHooks(GitHooks); err != nil {
102+
if err := scm.SetHooks(GitHooks, projRoot); err != nil {
84103
return "", err
85104
}
86105

87-
if err := scm.Config(GitConfig); err != nil {
106+
if err := scm.ConfigSet(GitConfig, projRoot); err != nil {
88107
return "", err
89108
}
90109

91-
if err := scm.Ignore(GitIgnore); err != nil {
110+
if err := scm.IgnoreSet(GitIgnore, projRoot); err != nil {
92111
return "", err
93112
}
94113

@@ -108,7 +127,7 @@ func Initialize() (string, error) {
108127
GitIgnore string
109128
}{
110129
headerFormat,
111-
wd,
130+
projRoot,
112131
GitHooks,
113132
GitConfig,
114133
GitIgnore})
@@ -120,6 +139,100 @@ func Initialize() (string, error) {
120139
return b.String(), nil
121140
}
122141

142+
//Uninitialize remove GTM tracking from the project in the current working directory
143+
func Uninitialize() (string, error) {
144+
wd, err := os.Getwd()
145+
if err != nil {
146+
return "", err
147+
}
148+
149+
projRoot, err := scm.RootPath(wd)
150+
if err != nil {
151+
return "", fmt.Errorf(
152+
"Unable to unintialize Git Time Metric, Git repository not found in %s", projRoot)
153+
}
154+
155+
gtmPath := filepath.Join(projRoot, GTMDir)
156+
if _, err := os.Stat(gtmPath); os.IsNotExist(err) {
157+
return "", fmt.Errorf(
158+
"Unable to uninitialize Git Time Metric, %s directory not found", gtmPath)
159+
}
160+
if err := scm.RemoveHooks(GitHooks, projRoot); err != nil {
161+
return "", err
162+
}
163+
if err := scm.ConfigRemove(GitConfig, projRoot); err != nil {
164+
return "", err
165+
}
166+
if err := scm.IgnoreRemove(GitIgnore, projRoot); err != nil {
167+
return "", err
168+
}
169+
if err := os.RemoveAll(gtmPath); err != nil {
170+
return "", err
171+
}
172+
173+
headerFormat := "%s"
174+
if terminal.IsTerminal(int(os.Stdout.Fd())) {
175+
headerFormat = "\x1b[1m%s\x1b[0m"
176+
}
177+
b := new(bytes.Buffer)
178+
t := template.Must(template.New("msg").Parse(removeMsgTpl))
179+
err = t.Execute(b,
180+
struct {
181+
HeaderFormat string
182+
ProjectPath string
183+
GitHooks map[string]string
184+
GitConfig map[string]string
185+
GitIgnore string
186+
}{
187+
headerFormat,
188+
projRoot,
189+
GitHooks,
190+
GitConfig,
191+
GitIgnore})
192+
193+
if err != nil {
194+
return "", err
195+
}
196+
197+
return b.String(), nil
198+
}
199+
200+
//Clean removes any event or metrics files from project in the current working directory
201+
func Clean() (string, error) {
202+
wd, err := os.Getwd()
203+
if err != nil {
204+
return "", err
205+
}
206+
207+
projRoot, err := scm.RootPath(wd)
208+
if err != nil {
209+
return "", fmt.Errorf(
210+
"Unable to clean, Git repository not found in %s", projRoot)
211+
}
212+
213+
gtmPath := filepath.Join(projRoot, GTMDir)
214+
if _, err := os.Stat(gtmPath); os.IsNotExist(err) {
215+
return "", fmt.Errorf(
216+
"Unable to clean GTM data, %s directory not found", gtmPath)
217+
}
218+
219+
files, err := ioutil.ReadDir(gtmPath)
220+
if err != nil {
221+
return "", err
222+
}
223+
for _, f := range files {
224+
if !strings.HasSuffix(f.Name(), ".event") &&
225+
!strings.HasSuffix(f.Name(), ".metric") {
226+
continue
227+
}
228+
if err := os.Remove(filepath.Join(gtmPath, f.Name())); err != nil {
229+
return "", err
230+
}
231+
}
232+
233+
return "", nil
234+
}
235+
123236
// Paths returns the root git repo and gtm paths
124237
func Paths(wd ...string) (string, string, error) {
125238
var (

0 commit comments

Comments
 (0)