1
0
Fork 0

Adding upstream version 1.2.3.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-05-22 09:45:13 +02:00
parent 3a3aa427d7
commit e7ed09875d
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
58 changed files with 3068 additions and 0 deletions

View file

@ -0,0 +1,20 @@
This command line tool is a small wrapper of [`selfupdate.DetectLatest()`](https://godoc.org/github.com/rhysd/go-github-selfupdate/selfupdate#DetectLatest).
Please install using `go get`.
```
$ go get -u github.com/rhysd/go-github-selfupdate/cmd/detect-latest-release
```
To know the usage, please try the command without any argument.
```
$ detect-latest-release
```
For example, following shows the latest version of [github-clone-all](https://github.com/rhysd/github-clone-all).
```
$ detect-latest-release rhysd/github-clone-all
```

View file

@ -0,0 +1,66 @@
package main
import (
"flag"
"fmt"
"github.com/rhysd/go-github-selfupdate/selfupdate"
"os"
"regexp"
"strings"
)
func usage() {
fmt.Fprintln(os.Stderr, "Usage: detect-latest-release [flags] {repo}\n\n {repo} must be URL to GitHub repository or in 'owner/name' format.\n\nFlags:\n")
flag.PrintDefaults()
}
func main() {
asset := flag.Bool("asset", false, "Output URL to asset")
notes := flag.Bool("release-notes", false, "Output release notes additionally")
url := flag.Bool("url", false, "Output URL for release page")
flag.Usage = usage
flag.Parse()
if flag.NArg() != 1 {
usage()
os.Exit(1)
}
repo := flag.Arg(0)
if strings.HasPrefix(repo, "https://") {
repo = repo[len("https://"):]
}
if strings.HasPrefix(repo, "github.com/") {
repo = repo[len("github.com/"):]
}
matched, err := regexp.MatchString("[^/]+/[^/]+", repo)
if err != nil {
panic(err)
}
if !matched {
usage()
os.Exit(1)
}
latest, found, err := selfupdate.DetectLatest(repo)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
if !found {
fmt.Println("No release was found")
} else {
if *asset {
fmt.Println(latest.AssetURL)
} else if *url {
fmt.Println(latest.URL)
} else {
fmt.Println(latest.Version)
if *notes {
fmt.Printf("\nRelease Notes:\n%s\n", latest.ReleaseNotes)
}
}
}
}

View file

@ -0,0 +1,29 @@
Like `go get`, but it downloads and installs the latest release binary from GitHub instead.
Please download a binary from [release page](https://github.com/rhysd/go-github-selfupdate/releases/tag/go-get-release)
and put it in `$PATH` or build from source with `go get`.
```
$ go get -u github.com/rhysd/go-github-selfupdate/cmd/go-get-release
```
Usage is quite similar to `go get`. But `{package}` must be hosted on GitHub. So it needs to start with `github.com/`.
```
$ go-get-release {package}
```
Please note that this command assumes that specified package is following Git tag naming rules and
released binaries naming rules described in [README](../../README.md).
For example, following command downloads and installs the released binary of [ghr](https://github.com/tcnksm/ghr)
to `$GOPATH/bin`.
```
$ go-get-release github.com/tcnksm/ghr
Command was updated to the latest version 0.5.4: /Users/you/.go/bin/ghr
$ ghr -version
ghr version v0.5.4 (a12ff1c)
```

132
cmd/go-get-release/main.go Normal file
View file

@ -0,0 +1,132 @@
package main
import (
"flag"
"fmt"
"github.com/rhysd/go-github-selfupdate/selfupdate"
"go/build"
"io"
"net/http"
"os"
"path/filepath"
"strings"
)
var version = "1.0.0"
func usage() {
fmt.Fprintln(os.Stderr, `Usage: go-get-release [flags] {package}
go-get-release is like "go get", but it downloads the latest release from
GitHub. {package} must start with "github.com/".
Flags:`)
flag.PrintDefaults()
}
func getCommand(pkg string) string {
_, cmd := filepath.Split(pkg)
if cmd == "" {
// When pkg path is ending with path separator, we need to split it out.
// i.e. github.com/rhysd/foo/cmd/bar/
_, cmd = filepath.Split(cmd)
}
return cmd
}
func parseSlug(pkg string) (string, bool) {
pkg = pkg[len("github.com/"):]
first := false
for i, r := range pkg {
if r == '/' {
if !first {
first = true
} else {
return pkg[:i], true
}
}
}
if first {
// When 'github.com/foo/bar' is specified, reaching here.
return pkg, true
}
return "", false
}
func installFrom(url, cmd, path string) error {
res, err := http.Get(url)
if err != nil {
return fmt.Errorf("Failed to download release binary from %s: %s", url, err)
}
defer res.Body.Close()
if res.StatusCode != 200 {
return fmt.Errorf("Failed to download release binary from %s: Invalid response ", url)
}
executable, err := selfupdate.UncompressCommand(res.Body, url, cmd)
if err != nil {
return fmt.Errorf("Failed to uncompress downloaded asset from %s: %s", url, err)
}
bin, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0755)
if err != nil {
return err
}
if _, err := io.Copy(bin, executable); err != nil {
return fmt.Errorf("Failed to write binary to %s: %s", path, err)
}
return nil
}
func main() {
help := flag.Bool("help", false, "Show help")
ver := flag.Bool("version", false, "Show version")
flag.Usage = usage
flag.Parse()
if *ver {
fmt.Println(version)
os.Exit(0)
}
if *help || flag.NArg() != 1 || !strings.HasPrefix(flag.Arg(0), "github.com/") {
usage()
os.Exit(1)
}
slug, ok := parseSlug(flag.Arg(0))
if !ok {
usage()
os.Exit(1)
}
latest, found, err := selfupdate.DetectLatest(slug)
if err != nil {
fmt.Fprintln(os.Stderr, "Error while detecting the latest version:", err)
os.Exit(1)
}
if !found {
fmt.Fprintln(os.Stderr, "No release was found in", slug)
os.Exit(1)
}
cmd := getCommand(flag.Arg(0))
cmdPath := filepath.Join(build.Default.GOPATH, "bin", cmd)
if _, err := os.Stat(cmdPath); err != nil {
// When executable is not existing yet
if err := installFrom(latest.AssetURL, cmd, cmdPath); err != nil {
fmt.Fprintf(os.Stderr, "Error while installing the release binary from %s: %s\n", latest.AssetURL, err)
os.Exit(1)
}
} else {
if err := selfupdate.UpdateTo(latest.AssetURL, cmdPath); err != nil {
fmt.Fprintf(os.Stderr, "Error while replacing the binary with %s: %s\n", latest.AssetURL, err)
os.Exit(1)
}
}
fmt.Printf(`Command was updated to the latest version %s: %s
Release Notes:
%s
`, latest.Version, cmdPath, latest.ReleaseNotes)
}

View file

@ -0,0 +1,64 @@
package main
import (
"flag"
"fmt"
"github.com/blang/semver"
"github.com/rhysd/go-github-selfupdate/selfupdate"
"os"
)
const version = "1.2.3"
func selfUpdate(slug string) error {
selfupdate.EnableLog()
previous := semver.MustParse(version)
latest, err := selfupdate.UpdateSelf(previous, slug)
if err != nil {
return err
}
if previous.Equals(latest.Version) {
fmt.Println("Current binary is the latest version", version)
} else {
fmt.Println("Update successfully done to version", latest.Version)
fmt.Println("Release note:\n", latest.ReleaseNotes)
}
return nil
}
func usage() {
fmt.Fprintln(os.Stderr, "Usage: selfupdate-example [flags]\n")
flag.PrintDefaults()
}
func main() {
help := flag.Bool("help", false, "Show this help")
ver := flag.Bool("version", false, "Show version")
update := flag.Bool("selfupdate", false, "Try go-github-selfupdate via GitHub")
slug := flag.String("slug", "rhysd/go-github-selfupdate", "Repository of this command")
flag.Usage = usage
flag.Parse()
if *help {
usage()
os.Exit(0)
}
if *ver {
fmt.Println(version)
os.Exit(0)
}
if *update {
if err := selfUpdate(*slug); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
os.Exit(0)
}
usage()
}