Skip to content

Commit 8f2f2e0

Browse files
committed
chore: codebase improvements
1 parent b729f26 commit 8f2f2e0

11 files changed

Lines changed: 153 additions & 124 deletions

File tree

cmd/init.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,20 @@ var initCmd = &cobra.Command{
8989
pluginPath := filepath.Join(dir, "plugin.json")
9090
endgitPath := filepath.Join(dir, "endgit.json")
9191

92-
writeJSON(pluginPath, plugin)
92+
if err := writeJSON(pluginPath, plugin); err != nil {
93+
color.Red("Failed to write plugin.json: %v", err)
94+
os.Exit(1)
95+
}
9396

9497
endgit := EndgitJSON{
9598
DisplayName: displayName,
9699
PluginType: pluginType,
97100
}
98101

99-
writeJSON(endgitPath, endgit)
102+
if err := writeJSON(endgitPath, endgit); err != nil {
103+
color.Red("Failed to write endgit.json: %v", err)
104+
os.Exit(1)
105+
}
100106

101107
color.Green("\nSuccessfully created plugin.json and endgit.json.")
102108
color.HiBlack("You can now run endgit publish to push your plugin.")
@@ -107,9 +113,12 @@ func init() {
107113
rootCmd.AddCommand(initCmd)
108114
}
109115

110-
func writeJSON(path string, v any) {
111-
data, _ := json.MarshalIndent(v, "", " ")
112-
_ = os.WriteFile(path, data, 0644)
116+
func writeJSON(path string, v any) error {
117+
data, err := json.MarshalIndent(v, "", " ")
118+
if err != nil {
119+
return err
120+
}
121+
return os.WriteFile(path, data, 0644)
113122
}
114123

115124
func sanitizeSlug(s string) string {

cmd/install.go

Lines changed: 41 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,35 @@ import (
1919
"github.com/two-tech-dev/endgit-cli/internal/common"
2020
)
2121

22+
func downloadAndSave(s *spinner.Spinner, client *api.Client, url string, filename string) {
23+
if err := os.MkdirAll("plugins", 0755); err != nil {
24+
s.Stop()
25+
color.Red("Failed to create plugins directory: %v", err)
26+
os.Exit(1)
27+
}
28+
29+
file := filepath.Join("plugins", filename)
30+
baseSuffix := s.Suffix
31+
32+
onProgress := func(downloaded, total int64) {
33+
if total > 0 {
34+
percent := float64(downloaded) / float64(total) * 100
35+
s.Suffix = fmt.Sprintf("%s (%.1f%% of %.2fMB)", baseSuffix, percent, float64(total)/(1024*1024))
36+
} else {
37+
s.Suffix = fmt.Sprintf("%s (%.2fMB)", baseSuffix, float64(downloaded)/(1024*1024))
38+
}
39+
}
40+
41+
if err := client.DownloadFile(url, file, onProgress); err != nil {
42+
s.Stop()
43+
color.Red("Download failed: %v", err)
44+
os.Exit(1)
45+
}
46+
47+
s.Stop()
48+
color.HiBlack("Saved to: %s", file)
49+
}
50+
2251
var installCmd = &cobra.Command{
2352
Use: "install <plugin[@version|@commit]>",
2453
Short: "Download and install a plugin to the current directory",
@@ -49,6 +78,8 @@ var installCmd = &cobra.Command{
4978
ext := ".so"
5079
if runtime.GOOS == "windows" {
5180
ext = ".dll"
81+
} else if runtime.GOOS == "darwin" {
82+
ext = ".dylib"
5283
}
5384

5485
// =========================
@@ -83,28 +114,11 @@ var installCmd = &cobra.Command{
83114

84115
s.Suffix = fmt.Sprintf(" Downloading build #%d...", target.BuildNumber)
85116

86-
url := common.ResolveArtifactURL(target)
87-
88-
data, err := common.DownloadFile(url)
89-
if err != nil {
90-
s.Stop()
91-
color.Red("Download failed: %v", err)
92-
return
93-
}
94-
95-
_ = os.MkdirAll("plugins", 0755)
96-
97-
file := filepath.Join(
98-
"plugins",
99-
fmt.Sprintf("%s-build%d-%s%s", plugin, target.BuildNumber, commit[:7], ext),
100-
)
101-
102-
_ = os.WriteFile(file, data, 0644)
103-
104-
s.Stop()
105-
117+
url := target.ResolveArtifactURL()
118+
filename := fmt.Sprintf("%s-build%d-%s%s", plugin, target.BuildNumber, commit[:7], ext)
119+
120+
downloadAndSave(s, client, url, filename)
106121
color.Green("Installed dev build %s #%d", plugin, target.BuildNumber)
107-
color.HiBlack("Saved to: %s", file)
108122
return
109123
}
110124

@@ -124,26 +138,9 @@ var installCmd = &cobra.Command{
124138
runtime.GOOS,
125139
)
126140

127-
data, err := common.DownloadFile(downloadURL)
128-
if err != nil {
129-
s.Stop()
130-
color.Red("Download failed: %v", err)
131-
return
132-
}
133-
134-
_ = os.MkdirAll("plugins", 0755)
135-
136-
file := filepath.Join(
137-
"plugins",
138-
fmt.Sprintf("%s-%s%s", plugin, version, ext),
139-
)
140-
141-
_ = os.WriteFile(file, data, 0644)
142-
143-
s.Stop()
144-
141+
filename := fmt.Sprintf("%s-%s%s", plugin, version, ext)
142+
downloadAndSave(s, client, downloadURL, filename)
145143
color.Green("Installed %s@%s", plugin, version)
146-
color.HiBlack("Saved to: %s", file)
147144
return
148145
}
149146

@@ -166,6 +163,8 @@ var installCmd = &cobra.Command{
166163
return
167164
}
168165

166+
s.Suffix = fmt.Sprintf(" Downloading %s@%s...", plugin, p.LatestVersion)
167+
169168
downloadURL := fmt.Sprintf(
170169
"%s/download/%s/%s?platform=%s",
171170
client.BaseURL,
@@ -174,26 +173,9 @@ var installCmd = &cobra.Command{
174173
runtime.GOOS,
175174
)
176175

177-
data, err := common.DownloadFile(downloadURL)
178-
if err != nil {
179-
s.Stop()
180-
color.Red("Download failed: %v", err)
181-
return
182-
}
183-
184-
_ = os.MkdirAll("plugins", 0755)
185-
186-
file := filepath.Join(
187-
"plugins",
188-
fmt.Sprintf("%s-%s%s", plugin, p.LatestVersion, ext),
189-
)
190-
191-
_ = os.WriteFile(file, data, 0644)
192-
193-
s.Stop()
194-
176+
filename := fmt.Sprintf("%s-%s%s", plugin, p.LatestVersion, ext)
177+
downloadAndSave(s, client, downloadURL, filename)
195178
color.Green("Installed %s@%s", plugin, p.LatestVersion)
196-
color.HiBlack("Saved to: %s", file)
197179
},
198180
}
199181

cmd/login.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ var loginCmd = &cobra.Command{
4646
s.Suffix = " Saving credentials..."
4747
s.Start()
4848

49-
err = config.SaveConfig(config.EndGitConfig{
50-
APIToken: token,
51-
})
49+
cfg := config.GetConfig()
50+
cfg.APIToken = token
51+
err = config.SaveConfig(cfg)
5252

5353
s.Stop()
5454

cmd/logout.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ var logoutCmd = &cobra.Command{
2222
s.Suffix = " Removing stored credentials..."
2323
s.Start()
2424

25-
err := config.SaveConfig(config.EndGitConfig{
26-
APIToken: "",
27-
})
25+
cfg := config.GetConfig()
26+
cfg.APIToken = ""
27+
err := config.SaveConfig(cfg)
2828

2929
s.Stop()
3030

cmd/root.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ import (
1414

1515
var endgit = color.New(color.FgCyan, color.Bold).Sprint("EndGit")
1616

17+
var Version = "dev"
18+
1719
var rootCmd = &cobra.Command{
18-
Use: "endgit",
20+
Use: "endgit",
21+
Version: Version,
1922
Short: endgit + " - The package manager for Endstone plugins",
2023
Long: endgit + ` - The package manager for Endstone plugins
2124

go.mod

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,18 @@ module github.com/two-tech-dev/endgit-cli
33
go 1.26.2
44

55
require (
6-
github.com/AlecAivazis/survey/v2 v2.3.7 // indirect
7-
github.com/briandowns/spinner v1.23.2 // indirect
8-
github.com/fatih/color v1.19.0 // indirect
6+
github.com/AlecAivazis/survey/v2 v2.3.7
7+
github.com/briandowns/spinner v1.23.2
8+
github.com/fatih/color v1.19.0
9+
github.com/spf13/cobra v1.10.2
10+
)
11+
12+
require (
913
github.com/inconshreveable/mousetrap v1.1.0 // indirect
1014
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
1115
github.com/mattn/go-colorable v0.1.14 // indirect
1216
github.com/mattn/go-isatty v0.0.20 // indirect
1317
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
14-
github.com/spf13/cobra v1.10.2 // indirect
1518
github.com/spf13/pflag v1.0.9 // indirect
1619
golang.org/x/sys v0.42.0 // indirect
1720
golang.org/x/term v0.1.0 // indirect

go.sum

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ=
22
github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo=
3+
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
34
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
45
github.com/briandowns/spinner v1.23.2 h1:Zc6ecUnI+YzLmJniCfDNaMbW0Wid1d5+qcTq4L2FW8w=
56
github.com/briandowns/spinner v1.23.2/go.mod h1:LaZeM4wm2Ywy6vO571mvhQNRcWfRUnXOs0RcKV0wYKM=
67
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
8+
github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI=
79
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
810
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
11+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
912
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
1013
github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
1114
github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
15+
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
1216
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
1317
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
1418
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
@@ -22,13 +26,15 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
2226
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
2327
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
2428
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
29+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
2530
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
2631
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
2732
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
2833
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
2934
github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
3035
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
3136
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
37+
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
3238
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
3339
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
3440
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
@@ -63,4 +69,5 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
6369
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
6470
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
6571
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
72+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
6673
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

internal/api/client.go

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,21 @@ import (
99
"io"
1010
"net/http"
1111
"net/url"
12+
"os"
13+
"time"
1214

1315
"github.com/two-tech-dev/endgit-cli/internal/config"
1416
)
1517

18+
type userAgentTransport struct {
19+
rt http.RoundTripper
20+
}
21+
22+
func (t *userAgentTransport) RoundTrip(req *http.Request) (*http.Response, error) {
23+
req.Header.Set("User-Agent", "endgit-cli")
24+
return t.rt.RoundTrip(req)
25+
}
26+
1627
type Client struct {
1728
BaseURL string
1829
HTTP *http.Client
@@ -28,7 +39,12 @@ func NewClient() *Client {
2839

2940
return &Client{
3041
BaseURL: base + "/api/v1",
31-
HTTP: &http.Client{},
42+
HTTP: &http.Client{
43+
Timeout: 10 * time.Minute,
44+
Transport: &userAgentTransport{
45+
rt: http.DefaultTransport,
46+
},
47+
},
3248
}
3349
}
3450

@@ -108,13 +124,46 @@ func (c *Client) GetBuilds(plugin string) (*BuildResponse, error) {
108124
return &res, nil
109125
}
110126

111-
func (c *Client) DownloadFile(url string) ([]byte, error) {
127+
type progressWriter struct {
128+
writer io.Writer
129+
total int64
130+
written int64
131+
progress func(downloaded int64, total int64)
132+
}
133+
134+
func (pw *progressWriter) Write(p []byte) (int, error) {
135+
n, err := pw.writer.Write(p)
136+
pw.written += int64(n)
137+
if pw.progress != nil {
138+
pw.progress(pw.written, pw.total)
139+
}
140+
return n, err
141+
}
142+
143+
func (c *Client) DownloadFile(url string, destPath string, onProgress func(downloaded int64, total int64)) error {
112144
resp, err := c.HTTP.Get(url)
113145
if err != nil {
114-
return nil, err
146+
return err
115147
}
116-
fmt.Printf("%s", url)
117148
defer resp.Body.Close()
118149

119-
return io.ReadAll(resp.Body)
150+
if resp.StatusCode != http.StatusOK {
151+
return fmt.Errorf("http status %d", resp.StatusCode)
152+
}
153+
154+
out, err := os.Create(destPath)
155+
if err != nil {
156+
return err
157+
}
158+
defer out.Close()
159+
160+
pw := &progressWriter{
161+
writer: out,
162+
total: resp.ContentLength,
163+
progress: onProgress,
164+
}
165+
166+
buf := make([]byte, 1024*1024) // 1MB buffer for faster disk writes
167+
_, err = io.CopyBuffer(pw, resp.Body, buf)
168+
return err
120169
}

0 commit comments

Comments
 (0)