Initial commit
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
Signed-off-by: jolheiser <john.olheiser@gmail.com>pull/1/head
commit
4d2af9ae20
|
@ -0,0 +1,41 @@
|
|||
---
|
||||
kind: pipeline
|
||||
name: compliance
|
||||
trigger:
|
||||
event:
|
||||
- pull_request
|
||||
steps:
|
||||
- name: test
|
||||
pull: always
|
||||
image: golang:1.16
|
||||
commands:
|
||||
- go test -race ./...
|
||||
- name: check
|
||||
pull: always
|
||||
image: golang:1.16
|
||||
commands:
|
||||
- go vet ./...
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: release
|
||||
trigger:
|
||||
event:
|
||||
- push
|
||||
branch:
|
||||
- main
|
||||
steps:
|
||||
- name: build
|
||||
pull: always
|
||||
image: golang:1.16
|
||||
commands:
|
||||
- go build git.jojodev.com/golang/dl/cmd/godl
|
||||
- name: gitea-release
|
||||
pull: always
|
||||
image: jolheiser/drone-gitea-main:latest
|
||||
settings:
|
||||
token:
|
||||
from_secret: gitea_token
|
||||
base: https://git.jojodev.com
|
||||
files:
|
||||
- "godl"
|
|
@ -0,0 +1,2 @@
|
|||
.idea/
|
||||
/godl*
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2021 John Olheiser
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,9 @@
|
|||
# dl
|
||||
|
||||
`https://golang.org/dl/?mode=json`
|
||||
|
||||
**NOTE:** This URL may not remain permanent, it is simply usable at the time of writing this library.
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE)
|
|
@ -0,0 +1,144 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"git.jojodev.com/golang/dl"
|
||||
|
||||
"github.com/schollz/progressbar/v3"
|
||||
)
|
||||
|
||||
func main() {
|
||||
installFlag := flag.Bool("install", false, "Install/Update Go (Linux only)")
|
||||
versionFlag := flag.Bool("version", false, "Only print version")
|
||||
outFlag := flag.String("out", ".", "Where to put the downloaded file")
|
||||
flag.Parse()
|
||||
|
||||
latest, err := latestVersion()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
if *versionFlag {
|
||||
fmt.Println(latest.Version)
|
||||
return
|
||||
}
|
||||
|
||||
outPath, err := download(latest.Filename, *outFlag)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
fmt.Println(outPath)
|
||||
|
||||
if !*installFlag {
|
||||
return
|
||||
}
|
||||
|
||||
if !strings.EqualFold(runtime.GOOS, "linux") {
|
||||
fmt.Println("Install option is only for Linux. Mac and Windows users should run the downloaded installer.")
|
||||
return
|
||||
}
|
||||
|
||||
if os.Geteuid() != 0 {
|
||||
fmt.Println(`This command must be run as root to perform the install.
|
||||
Alternatively, you can run the following command manually, which is taken from https://golang.org/doc/install#install
|
||||
|
||||
rm -rf /usr/local/go && tar -C /usr/local -xzf ` + outPath)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("removing local installation")
|
||||
rm := exec.Command("rm", "-rf", "/usr/local/go")
|
||||
if err := rm.Run(); err != nil {
|
||||
fmt.Printf("could not remove local go installation: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("extracting new installation")
|
||||
tar := exec.Command("tar", "-C", "/usr/local", "-xzf", outPath)
|
||||
if err := tar.Run(); err != nil {
|
||||
fmt.Printf("could not extract new installation: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
rmDl := exec.Command("rm", outPath)
|
||||
if err := rmDl.Run(); err != nil {
|
||||
fmt.Printf("could not remove downloaded file: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
goVersion := exec.Command("/usr/local/go/bin/go", "version")
|
||||
out, err := goVersion.Output()
|
||||
if err != nil {
|
||||
fmt.Printf("could not check go version: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("Successfully installed: %s\n", string(out))
|
||||
}
|
||||
|
||||
func latestVersion() (*dl.File, error) {
|
||||
versions, err := dl.Versions(context.Background())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get latest Go version(s): %v", err)
|
||||
}
|
||||
if len(versions) < 1 {
|
||||
return nil, fmt.Errorf("no latest Go version(s) found: %v", err)
|
||||
}
|
||||
|
||||
var version dl.File
|
||||
for _, file := range versions[0].Files {
|
||||
if strings.EqualFold(file.OS, runtime.GOOS) && strings.EqualFold(file.Arch, runtime.GOARCH) {
|
||||
version = file
|
||||
break
|
||||
}
|
||||
}
|
||||
if version.Filename == "" {
|
||||
return nil, fmt.Errorf("could not find a download for OS = %s | Arch = %s", runtime.GOOS, runtime.GOARCH)
|
||||
}
|
||||
|
||||
return &version, nil
|
||||
}
|
||||
|
||||
func download(filename, out string) (string, error) {
|
||||
outPath := filepath.Join(out, filename)
|
||||
outFile, err := os.Create(outPath)
|
||||
if err != nil {
|
||||
return outPath, fmt.Errorf("could not create file for download: %v", err)
|
||||
}
|
||||
defer outFile.Close()
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("https://golang.org/dl/%s", filename), nil)
|
||||
if err != nil {
|
||||
return outPath, fmt.Errorf("could not create request: %v", err)
|
||||
}
|
||||
req.Header.Set("User-Agent", "git.jojodev.com/golang/dl/cmd/godl")
|
||||
|
||||
res, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return outPath, fmt.Errorf("could not download file: %v", err)
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
bar := progressbar.DefaultBytes(
|
||||
res.ContentLength,
|
||||
fmt.Sprintf("downloading %s", filename),
|
||||
)
|
||||
|
||||
if _, err := io.Copy(io.MultiWriter(outFile, bar), res.Body); err != nil {
|
||||
return outPath, err
|
||||
}
|
||||
|
||||
return outPath, nil
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package dl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const dlURL = "https://golang.org/dl/?mode=json"
|
||||
|
||||
// Version is a Go version
|
||||
type Version struct {
|
||||
Version string `json:"version"`
|
||||
Stable bool `json:"stable"`
|
||||
Files []File `json:"files"`
|
||||
}
|
||||
|
||||
// File is a dl file
|
||||
type File struct {
|
||||
Filename string `json:"filename"`
|
||||
OS string `json:"os"`
|
||||
Arch string `json:"arch"`
|
||||
Version string `json:"version"`
|
||||
Sha256 string `json:"sha256"`
|
||||
Size int `json:"size"`
|
||||
Kind string `json:"kind"`
|
||||
}
|
||||
|
||||
// Versions gets the latest Version(s) from dl
|
||||
func Versions(ctx context.Context) ([]Version, error) {
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, dlURL, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("User-Agent", "git.jojodev.com/golang/dl")
|
||||
|
||||
res, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
var versions []Version
|
||||
if err := json.NewDecoder(res.Body).Decode(&versions); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return versions, nil
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,5 @@
|
|||
module git.jojodev.com/golang/dl
|
||||
|
||||
go 1.16
|
||||
|
||||
require github.com/schollz/progressbar/v3 v3.8.2
|
|
@ -0,0 +1,31 @@
|
|||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
|
||||
github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
|
||||
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
|
||||
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/schollz/progressbar/v3 v3.8.2 h1:2kZJwZCpb+E/V79kGO7daeq+hUwUJW0A5QD1Wv455dA=
|
||||
github.com/schollz/progressbar/v3 v3.8.2/go.mod h1:9KHLdyuXczIsyStQwzvW8xiELskmX7fQMaZdN23nAv8=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 h1:RqytpXGR1iVNX7psjB3ff8y7sNFinVFvkx1c8SjBkio=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE=
|
||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
Loading…
Reference in New Issue