Skip to content

Commit d17352e

Browse files
committed
Merge branch 'main' into feat/better_logging
2 parents 4636c9d + 64384d9 commit d17352e

16 files changed

+395
-45
lines changed

cmd/check_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,8 @@ func TestCheckCmd(t *testing.T) {
136136
t.Errorf("unexpected error: %v", err)
137137
}
138138

139-
if c.Name() != "check" {
140-
t.Errorf("got: '%s', want: 'check'", c.Name())
139+
if c.Name() != CheckCmd.Name() {
140+
t.Errorf("got: '%s', want: %s", c.Name(), CheckCmd.Name())
141141
}
142142
if !strings.Contains(got, tt.WantContains) {
143143
t.Errorf("got: %s, does not contain: %s", got, tt.WantContains)

cmd/config_test.go

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package cmd
2+
3+
import (
4+
"strings"
5+
"testing"
6+
7+
tu "github.com/everdrone/grab/testutils"
8+
)
9+
10+
func TestConfigCmd(t *testing.T) {
11+
t.Run("prints help message", func(tc *testing.T) {
12+
c, got, err := tu.ExecuteCommand(RootCmd, "config")
13+
14+
if err != nil {
15+
tc.Fatal(err)
16+
}
17+
18+
if c.Name() != ConfigCmd.Name() {
19+
tc.Fatalf("got: '%s', want: '%s'", c.Name(), ConfigCmd.Name())
20+
}
21+
22+
if !strings.HasPrefix(got, ConfigCmd.Short) {
23+
tc.Errorf("got: '%s', want: '%s'", got, ConfigCmd.Short)
24+
}
25+
})
26+
}

cmd/find_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ func TestFindCmd(t *testing.T) {
8989
tc.Errorf("got: %v, want: %v", err, tt.HasErrors)
9090
}
9191

92-
if c.Name() != "find" {
93-
tc.Errorf("got: %s, want: 'find", c.Name())
92+
if c.Name() != FindCmd.Name() {
93+
tc.Errorf("got: %s, want: %s", c.Name(), FindCmd.Name())
9494
}
9595
if got != tt.Want {
9696
tc.Errorf("got: %s, want: %s", got, tt.Want)

cmd/generate_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ func TestGenerate(t *testing.T) {
5858
tc.Errorf("got: %v, want: %v", err, tt.HasErrors)
5959
}
6060

61-
if c.Name() != "generate" {
62-
tc.Errorf("got: %s, want: 'generate", c.Name())
61+
if c.Name() != GenerateCmd.Name() {
62+
tc.Errorf("got: %s, want: %s", c.Name(), GenerateCmd.Name())
6363
}
6464

6565
if tt.CheckFile != "" {

cmd/get.go

+22
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package cmd
22

33
import (
4+
"github.com/everdrone/grab/internal/config"
45
"github.com/everdrone/grab/internal/instance"
6+
"github.com/everdrone/grab/internal/update"
57
"github.com/everdrone/grab/internal/utils"
8+
"github.com/fatih/color"
69
"github.com/rs/zerolog/log"
710

811
"github.com/spf13/cobra"
@@ -15,6 +18,12 @@ var GetCmd = &cobra.Command{
1518
RunE: func(cmd *cobra.Command, args []string) error {
1619
log.Logger = instance.DefaultLogger(cmd.OutOrStderr())
1720

21+
updateMessageChan := make(chan string)
22+
go func() {
23+
newVersion, _ := update.CheckForUpdates()
24+
updateMessageChan <- newVersion
25+
}()
26+
1827
g := instance.New(cmd)
1928

2029
g.ParseFlags()
@@ -46,6 +55,19 @@ var GetCmd = &cobra.Command{
4655
return utils.ErrSilent
4756
}
4857

58+
newVersion := <-updateMessageChan
59+
if newVersion != "" {
60+
// TODO: take in account possible package managers
61+
// if for example we installed with homebrew, we should display a different message
62+
cmd.Printf("\n\n%s %s → %s\n",
63+
color.New(color.FgMagenta).Sprintf("A new release of %s is available:", config.Name),
64+
config.Version,
65+
// color.New(color.FgHiBlack).Sprint(config.Version),
66+
color.New(color.FgCyan).Sprint(newVersion),
67+
)
68+
cmd.Printf("%s\n\n", "https://github.com/everdrone/grab/releases/latest")
69+
}
70+
4971
return nil
5072
},
5173
}

cmd/get_test.go

+63-12
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import (
44
"net/http/httptest"
55
"os"
66
"path/filepath"
7+
"strings"
78
"testing"
89

10+
"github.com/everdrone/grab/internal/config"
911
"github.com/everdrone/grab/internal/utils"
1012
tu "github.com/everdrone/grab/testutils"
1113
)
@@ -31,12 +33,14 @@ func TestGetCmd(t *testing.T) {
3133
defer ts.Close()
3234

3335
tests := []struct {
34-
Name string
35-
Args []string
36-
Config string
37-
ConfigPath string
38-
CheckFiles map[string]string
39-
WantErr bool
36+
Name string
37+
Args []string
38+
Config string
39+
ConfigPath string
40+
CheckFiles map[string]string
41+
WantErr bool
42+
UseBadReleaseURL bool
43+
WantUpdateMessage bool
4044
}{
4145
{
4246
Name: "invalid config",
@@ -116,7 +120,7 @@ site "example" {
116120
WantErr: true,
117121
},
118122
{
119-
Name: "can download",
123+
Name: "can download and get updates",
120124
Args: []string{ts.URL + "/gallery/123/test", "-s"},
121125
Config: `
122126
global {
@@ -138,11 +142,42 @@ site "example" {
138142
filepath.Join(globalLocation, "example", "b.jpg"): "imageb",
139143
filepath.Join(globalLocation, "example", "c.jpg"): "imagec",
140144
},
141-
ConfigPath: filepath.Join(root, "grab.hcl"),
142-
WantErr: false,
145+
ConfigPath: filepath.Join(root, "grab.hcl"),
146+
WantErr: false,
147+
WantUpdateMessage: true,
148+
},
149+
{
150+
Name: "can download without updates",
151+
Args: []string{ts.URL + "/gallery/123/test", "-s"},
152+
Config: `
153+
global {
154+
location = "` + escapedGlobalLocation + `"
155+
}
156+
157+
site "example" {
158+
test = "http:\\/\\/127\\.0\\.0\\.1:\\d+"
159+
160+
asset "image" {
161+
pattern = "<img src=\"([^\"]+/img/[^\"]+)"
162+
capture = 1
163+
find_all = true
164+
}
165+
}
166+
`,
167+
CheckFiles: map[string]string{
168+
filepath.Join(globalLocation, "example", "a.jpg"): "imagea",
169+
filepath.Join(globalLocation, "example", "b.jpg"): "imageb",
170+
filepath.Join(globalLocation, "example", "c.jpg"): "imagec",
171+
},
172+
ConfigPath: filepath.Join(root, "grab.hcl"),
173+
WantErr: false,
174+
UseBadReleaseURL: true,
175+
WantUpdateMessage: false,
143176
},
144177
}
145178

179+
updateMsg := "\n\nA new release of grab is available: " + config.Version + " → 987.654.321\nhttps://github.com/everdrone/grab/releases/latest\n\n"
180+
146181
for _, tt := range tests {
147182
t.Run(tt.Name, func(tc *testing.T) {
148183
// reset fs
@@ -152,10 +187,16 @@ site "example" {
152187
utils.AFS.MkdirAll(globalLocation, os.ModePerm)
153188
utils.AFS.WriteFile(tt.ConfigPath, []byte(tt.Config), os.ModePerm)
154189

155-
c, _, _, err := tu.ExecuteCommandErr(RootCmd, append([]string{"get"}, tt.Args...)...)
190+
// set releases url
191+
config.LatestReleaseURL = ts.URL + "/releases"
192+
if tt.UseBadReleaseURL {
193+
config.LatestReleaseURL = ts.URL + "/bad_releases"
194+
}
195+
196+
c, out, _, err := tu.ExecuteCommandErr(RootCmd, append([]string{"get"}, tt.Args...)...)
156197

157-
if c.Name() != "get" {
158-
tc.Fatalf("got: %s, want: 'find", c.Name())
198+
if c.Name() != GetCmd.Name() {
199+
tc.Fatalf("got: %s, want: %s", c.Name(), GetCmd.Name())
159200
}
160201

161202
if tt.CheckFiles != nil {
@@ -166,6 +207,16 @@ site "example" {
166207
}
167208
}
168209

210+
if tt.WantUpdateMessage {
211+
if !strings.Contains(out, updateMsg) {
212+
tc.Errorf("got: %s, want: %s", out, updateMsg)
213+
}
214+
} else {
215+
if strings.Contains(out, updateMsg) {
216+
tc.Errorf("got: %s, want: %s", out, updateMsg)
217+
}
218+
}
219+
169220
if (err != nil) != tt.WantErr {
170221
tc.Errorf("got: %v, want: %v", err, tt.WantErr)
171222
}

cmd/root_test.go

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package cmd
2+
3+
import (
4+
"strings"
5+
"testing"
6+
7+
tu "github.com/everdrone/grab/testutils"
8+
)
9+
10+
func TestRootCmd(t *testing.T) {
11+
t.Run("prints help message", func(tc *testing.T) {
12+
c, got, err := tu.ExecuteCommand(RootCmd, "")
13+
14+
if err != nil {
15+
tc.Fatal(err)
16+
}
17+
18+
if c.Name() != RootCmd.Name() {
19+
tc.Fatalf("got: '%s', want: '%s'", c.Name(), RootCmd.Name())
20+
}
21+
22+
if !strings.HasPrefix(got, RootCmd.Short) {
23+
tc.Errorf("got: '%s', want: '%s'", got, RootCmd.Short)
24+
}
25+
})
26+
}

cmd/version.go

+22-1
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,41 @@ package cmd
22

33
import (
44
"github.com/everdrone/grab/internal/config"
5+
"github.com/everdrone/grab/internal/update"
6+
"github.com/fatih/color"
57

68
"github.com/spf13/cobra"
79
)
810

911
var VersionCmd = &cobra.Command{
1012
Use: "version",
11-
Short: "Print the version number and exit",
13+
Short: "Print the version number and check for updates",
1214
Run: func(cmd *cobra.Command, args []string) {
15+
updateMessageChan := make(chan string)
16+
go func() {
17+
newVersion, _ := update.CheckForUpdates()
18+
updateMessageChan <- newVersion
19+
}()
20+
1321
cmd.Printf("%s v%s %s/%s (%s)\n",
1422
cmd.Root().Name(),
1523
config.Version,
1624
config.BuildOS,
1725
config.BuildArch,
1826
config.CommitHash[:7])
27+
28+
newVersion := <-updateMessageChan
29+
if newVersion != "" {
30+
// TODO: take in account possible package managers
31+
// if for example we installed with homebrew, we should display a different message
32+
cmd.Printf("\n\n%s %s → %s\n",
33+
color.New(color.FgMagenta).Sprintf("A new release of %s is available:", config.Name),
34+
config.Version,
35+
// color.New(color.FgHiBlack).Sprint(config.Version),
36+
color.New(color.FgCyan).Sprint(newVersion),
37+
)
38+
cmd.Printf("%s\n\n", "https://github.com/everdrone/grab/releases/latest")
39+
}
1940
},
2041
}
2142

cmd/version_test.go

+51-23
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,62 @@
11
package cmd
22

33
import (
4-
"fmt"
4+
"net/http"
5+
"net/http/httptest"
6+
"runtime"
57
"testing"
68

79
"github.com/everdrone/grab/internal/config"
810
tu "github.com/everdrone/grab/testutils"
911
)
1012

1113
func TestVersionCmd(t *testing.T) {
12-
t.Run("version", func(t *testing.T) {
13-
cmdName := "version"
14-
15-
c, got, err := tu.ExecuteCommand(RootCmd, cmdName)
16-
if err != nil {
17-
t.Fatal(err)
18-
}
19-
20-
want := fmt.Sprintf("%s v%s %s/%s (%s)\n",
21-
"grab",
22-
config.Version,
23-
"unknown",
24-
"unknown",
25-
"unknown",
26-
)
27-
if c.Name() != cmdName {
28-
t.Fatalf("got: '%s', want: '%s'", c.Name(), cmdName)
29-
}
30-
if got != want {
31-
t.Errorf("got: %s, want: %s", got, want)
32-
}
33-
})
14+
config.CommitHash = "abcdef0123456789"
15+
config.BuildOS = runtime.GOOS
16+
config.BuildArch = runtime.GOARCH
17+
18+
tests := []struct {
19+
name string
20+
handler func(w http.ResponseWriter, r *http.Request)
21+
want string
22+
}{
23+
{
24+
name: "no updates",
25+
handler: func(w http.ResponseWriter, r *http.Request) {
26+
w.Write([]byte(`{"tag_name": "v` + config.Version + `"}`))
27+
},
28+
want: "grab v" + config.Version + " " + config.BuildOS + "/" + config.BuildArch + " (" + config.CommitHash[:7] + ")\n",
29+
},
30+
{
31+
name: "newer version",
32+
handler: func(w http.ResponseWriter, r *http.Request) {
33+
w.Write([]byte(`{"tag_name": "v987.654.321"}`))
34+
},
35+
want: "grab v" + config.Version + " " + config.BuildOS + "/" + config.BuildArch + " (" + config.CommitHash[:7] + ")\n\n\n" +
36+
"A new release of grab is available: " + config.Version + " → 987.654.321\n" +
37+
"https://github.com/everdrone/grab/releases/latest\n\n",
38+
},
39+
}
40+
41+
for _, tt := range tests {
42+
t.Run(tt.name, func(tc *testing.T) {
43+
// start the test server
44+
ts := httptest.NewServer(http.HandlerFunc(tt.handler))
45+
46+
config.LatestReleaseURL = ts.URL
47+
48+
c, got, err := tu.ExecuteCommand(RootCmd, "version")
49+
if err != nil {
50+
tc.Fatal(err)
51+
}
52+
53+
if c.Name() != VersionCmd.Name() {
54+
tc.Fatalf("got: %s, want: %s", c.Name(), VersionCmd.Name())
55+
}
56+
57+
if got != tt.want {
58+
tc.Errorf("got: %q, want: %q", got, tt.want)
59+
}
60+
})
61+
}
3462
}

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ require (
2727
github.com/valyala/bytebufferpool v1.0.0 // indirect
2828
github.com/valyala/fasttemplate v1.2.1 // indirect
2929
golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167 // indirect
30+
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
3031
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect
3132
golang.org/x/sys v0.0.0-20220818161305-2296e01440c6 // indirect
3233
golang.org/x/text v0.3.7 // indirect

0 commit comments

Comments
 (0)