Skip to content

Commit c51fa51

Browse files
authored
Parse the filename from target URL (#6)
* Add support to parse filename from URL * Add an option to keep part files * Shoule not append to the final file * Update the readme file * Fix the lint errors fix the comment of function DownloadFileWithMultipleThreadKeepParts
1 parent 902ee22 commit c51fa51

File tree

5 files changed

+45
-13
lines changed

5 files changed

+45
-13
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
build: fmt
2+
export GOPROXY=https://goproxy.io
23
CGO_ENABLE=0 go build -ldflags "-w -s" -o bin/hd
34

45
run:

README-zh.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,13 @@ mv hd /usr/local/bin
1919
# 用法
2020

2121
```
22-
hd get https://github.com/jenkins-zh/jenkins-cli/releases/latest/download/jcli-linux-amd64.tar.gz -o jcli.tar.gz --thread 10
22+
hd get https://github.com/jenkins-zh/jenkins-cli/releases/latest/download/jcli-linux-amd64.tar.gz --thread 6
23+
```
24+
25+
或者,用一个更加简便的办法:
26+
27+
```
28+
hd get jenkins-zh/jenkins-cli/jcli --thread 6
2329
```
2430

2531
# 功能

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,13 @@ mv hd /usr/local/bin
1919
# Usage
2020

2121
```
22-
hd get https://github.com/jenkins-zh/jenkins-cli/releases/latest/download/jcli-linux-amd64.tar.gz -o jcli.tar.gz --thread 10
22+
hd get https://github.com/jenkins-zh/jenkins-cli/releases/latest/download/jcli-linux-amd64.tar.gz --thread 6
23+
```
24+
25+
Or use a simple way:
26+
27+
```
28+
hd get jenkins-zh/jenkins-cli/jcli --thread 6
2329
```
2430

2531
# Features

cmd/root.go

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
extver "github.com/linuxsuren/cobra-extension/version"
66
"github.com/linuxsuren/http-downloader/pkg"
77
"github.com/spf13/cobra"
8+
"net/url"
9+
"path"
810
"runtime"
911
"strings"
1012
)
@@ -20,7 +22,7 @@ func NewRoot() (cmd *cobra.Command) {
2022
getCmd := &cobra.Command{
2123
Use: "get",
2224
Short: "download the file",
23-
Example: "hd get jenkins-zh/jenkins-cli/jcli -o jcli.tar.gz --thread 3",
25+
Example: "hd get jenkins-zh/jenkins-cli/jcli --thread 6",
2426
PreRunE: opt.preRunE,
2527
RunE: opt.runE,
2628
}
@@ -31,6 +33,8 @@ func NewRoot() (cmd *cobra.Command) {
3133
flags.BoolVarP(&opt.ShowProgress, "show-progress", "", true, "If show the progress of download")
3234
flags.Int64VarP(&opt.ContinueAt, "continue-at", "", -1, "ContinueAt")
3335
flags.IntVarP(&opt.Thread, "thread", "", 0, "")
36+
flags.BoolVarP(&opt.KeepPart, "keep-part", "", false,
37+
"If you want to keep the part files instead of deleting them")
3438
flags.StringVarP(&opt.Provider, "provider", "", ProviderGitHub, "The file provider")
3539
flags.StringVarP(&opt.OS, "os", "", "", "The OS of target binary file")
3640
flags.StringVarP(&opt.Arch, "arch", "", "", "The arch of target binary file")
@@ -52,7 +56,8 @@ type downloadOption struct {
5256
Arch string
5357
OS string
5458

55-
Thread int
59+
Thread int
60+
KeepPart bool
5661
}
5762

5863
const (
@@ -118,18 +123,27 @@ func (o *downloadOption) preRunE(cmd *cobra.Command, args []string) (err error)
118123
o.Arch = runtime.GOARCH
119124
}
120125

121-
url := args[0]
122-
if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {
123-
if url, err = o.providerURLParse(url); err != nil {
126+
targetURL := args[0]
127+
if !strings.HasPrefix(targetURL, "http://") && !strings.HasPrefix(targetURL, "https://") {
128+
if targetURL, err = o.providerURLParse(targetURL); err != nil {
124129
err = fmt.Errorf("only http:// or https:// supported, error: %v", err)
125130
return
126131
}
127-
cmd.Printf("start to download from %s\n", url)
132+
cmd.Printf("start to download from %s\n", targetURL)
128133
}
129-
o.URL = url
134+
o.URL = targetURL
130135

131136
if o.Output == "" {
132-
err = fmt.Errorf("output cannot be empty")
137+
var urlObj *url.URL
138+
if urlObj, err = url.Parse(o.URL); err == nil {
139+
o.Output = path.Base(urlObj.Path)
140+
141+
if o.Output == "" {
142+
err = fmt.Errorf("output cannot be empty")
143+
}
144+
} else {
145+
err = fmt.Errorf("cannot parse the target URL, error: '%v'", err)
146+
}
133147
}
134148
return
135149
}
@@ -138,7 +152,7 @@ func (o *downloadOption) runE(cmd *cobra.Command, args []string) (err error) {
138152
if o.Thread <= 1 {
139153
err = pkg.DownloadWithContinue(o.URL, o.Output, o.ContinueAt, 0, o.ShowProgress)
140154
} else {
141-
err = pkg.DownloadFileWithMultipleThread(o.URL, o.Output, o.Thread, o.ShowProgress)
155+
err = pkg.DownloadFileWithMultipleThreadKeepParts(o.URL, o.Output, o.Thread, o.KeepPart, o.ShowProgress)
142156
}
143157
return
144158
}

pkg/http.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,11 @@ func (h *HTTPDownloader) DownloadFile() error {
176176

177177
// DownloadFileWithMultipleThread downloads the files with multiple threads
178178
func DownloadFileWithMultipleThread(targetURL, targetFilePath string, thread int, showProgress bool) (err error) {
179+
return DownloadFileWithMultipleThreadKeepParts(targetURL, targetFilePath, thread, false, showProgress)
180+
}
181+
182+
// DownloadFileWithMultipleThreadKeepParts downloads the files with multiple threads
183+
func DownloadFileWithMultipleThreadKeepParts(targetURL, targetFilePath string, thread int, keepParts, showProgress bool) (err error) {
179184
// get the total size of the target file
180185
var total int64
181186
var rangeSupport bool
@@ -211,7 +216,7 @@ func DownloadFileWithMultipleThread(targetURL, targetFilePath string, thread int
211216

212217
// concat all these partial files
213218
var f *os.File
214-
if f, err = os.OpenFile(targetFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644); err == nil {
219+
if f, err = os.OpenFile(targetFilePath, os.O_CREATE|os.O_WRONLY, 0644); err == nil {
215220
defer func() {
216221
_ = f.Close()
217222
}()
@@ -222,7 +227,7 @@ func DownloadFileWithMultipleThread(targetURL, targetFilePath string, thread int
222227
if _, err = f.Write(data); err != nil {
223228
err = fmt.Errorf("failed to write file: '%s'", partFile)
224229
break
225-
} else {
230+
} else if !keepParts {
226231
_ = os.RemoveAll(partFile)
227232
}
228233
} else {

0 commit comments

Comments
 (0)