├── .github
└── workflows
│ ├── build.yml
│ └── lint.yml
├── .gitignore
├── .golangci.yml
├── .goreleaser.yml
├── LICENSE
├── Makefile
├── README.md
├── cmd
├── root.go
└── update.go
├── go.mod
├── go.sum
├── install.sh
├── internal
├── config
│ └── config.go
└── tui
│ ├── init.go
│ ├── keys.go
│ ├── model.go
│ ├── update.go
│ └── view.go
└── main.go
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: build
2 |
3 | on:
4 | push:
5 | tags:
6 | - "*"
7 | jobs:
8 | build:
9 | name: GoReleaser build
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: Check out code into the Go module directory
13 | uses: actions/checkout@v3
14 | with:
15 | fetch-depth: 0
16 | - name: Set up Go 1.18
17 | uses: actions/setup-go@v3
18 | with:
19 | go-version: 1.18
20 | id: go
21 | - name: Run GoReleaser
22 | uses: goreleaser/goreleaser-action@v2
23 | with:
24 | version: latest
25 | args: release --rm-dist
26 | env:
27 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
28 | - name: Upload assets
29 | uses: actions/upload-artifact@v3
30 | with:
31 | name: bubbletea-starter
32 | path: dist/*
33 |
--------------------------------------------------------------------------------
/.github/workflows/lint.yml:
--------------------------------------------------------------------------------
1 | name: lint
2 |
3 | on: [push, pull_request]
4 | jobs:
5 | golangci:
6 | name: lint
7 | runs-on: ubuntu-latest
8 | steps:
9 | - uses: actions/checkout@v3
10 | - name: golangci-lint
11 | uses: golangci/golangci-lint-action@v3
12 | with:
13 | args: --issues-exit-code=0
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | vendor/
2 | .DS_Store
3 | debug.log
--------------------------------------------------------------------------------
/.golangci.yml:
--------------------------------------------------------------------------------
1 | run:
2 | timeout: 5m
3 |
4 | linters:
5 | disable-all: true
6 | enable:
7 | - bodyclose
8 | - deadcode
9 | - depguard
10 | - dogsled
11 | - dupl
12 | - errcheck
13 | - exportloopref
14 | - gochecknoinits
15 | - goconst
16 | - gocritic
17 | - gofmt
18 | - goprintffuncname
19 | - gosimple
20 | - govet
21 | - ineffassign
22 | - misspell
23 | - nakedret
24 | - noctx
25 | - nolintlint
26 | - rowserrcheck
27 | - staticcheck
28 | - structcheck
29 | - stylecheck
30 | - typecheck
31 | - unconvert
32 | - unparam
33 | - unused
34 | - varcheck
35 | - whitespace
36 | - wastedassign
37 | - nilerr
38 | - godot
39 | - godox
40 | - goimports
41 |
--------------------------------------------------------------------------------
/.goreleaser.yml:
--------------------------------------------------------------------------------
1 | project_name: "bubbletea-starter"
2 |
3 | # before are hooks that will be run before any builds are done, so good to put install scripts and stuff that your builds need here
4 | before:
5 | hooks:
6 | # Remove unused packaged from the build process
7 | - go mod tidy
8 | # You may remove this if you don't use go modules - Downloads all modules specified in go.mod
9 | - go mod download
10 |
11 | builds:
12 | - main: ./main.go
13 | binary: bubletea-starter
14 | goos:
15 | - linux
16 | - windows
17 | - darwin
18 | goarch:
19 | - amd64
20 | - arm64
21 | env:
22 | - CGO_ENABLED=0
23 |
24 | nfpms:
25 | - maintainer: Tyler Knipfer
26 | description: bubbletea-starter is a starting point for bubbletea apps
27 | homepage: https://github.com/knipferrc/bubbletea-starter
28 | license: MIT
29 | formats:
30 | - deb
31 | - rpm
32 | - apk
33 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Tyler Knipfer
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | make:
2 | go run main.go
3 |
4 | test:
5 | go test ./... -short
6 |
7 | build:
8 | go build -o bubbletea-starter main.go
9 |
10 | install:
11 | go install
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
Bubbletea-Starter
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | ## About The Project
11 |
12 | A starting point for bubbletea apps
13 |
14 | ### Built With
15 |
16 | - [Go](https://golang.org/)
17 | - [bubbletea](https://github.com/charmbracelet/bubbletea)
18 | - [bubbles](https://github.com/charmbracelet/bubbles)
19 | - [lipgloss](https://github.com/charmbracelet/lipgloss)
20 | - [Viper](https://github.com/spf13/viper)
21 | - [Cobra](https://github.com/spf13/cobra)
22 |
23 | ## Installation
24 |
25 | ### Curl
26 |
27 | ```sh
28 | curl -sfL https://raw.githubusercontent.com/knipferrc/bubbletea-starter/main/install.sh | sh
29 | ```
30 |
31 | ### Go
32 |
33 | ```
34 | go install github.com/knipferrc/bubbletea-starter@latest
35 | ```
36 |
37 | ## Features
38 |
39 | - Add your awesome feature list here
40 |
41 | ## Configuration
42 |
43 | A config file will be generated (`bubbletea-starter.yml`) in the config directory of the OS in which the app is ran from. If `XDG_CONFIG_HOME` is set, that will be used instead.
44 |
45 | ```yml
46 | settings:
47 | enable_logging: false
48 | enable_mousewheel: true
49 | ```
50 |
--------------------------------------------------------------------------------
/cmd/root.go:
--------------------------------------------------------------------------------
1 | package cmd
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "os"
7 |
8 | "github.com/knipferrc/bubbletea-starter/internal/config"
9 | "github.com/knipferrc/bubbletea-starter/internal/tui"
10 |
11 | tea "github.com/charmbracelet/bubbletea"
12 | "github.com/spf13/cobra"
13 | )
14 |
15 | var rootCmd = &cobra.Command{
16 | Use: "bubbletea-starter",
17 | Short: "bubbletea-starter is a starting point for bubbletea apps",
18 | Version: "0.0.1",
19 | Args: cobra.MaximumNArgs(1),
20 | Run: func(cmd *cobra.Command, args []string) {
21 | cfg, err := config.ParseConfig()
22 | if err != nil {
23 | log.Fatal(err)
24 | }
25 |
26 | // If logging is enabled, logs will be output to debug.log.
27 | if cfg.Settings.EnableLogging {
28 | f, err := tea.LogToFile("debug.log", "debug")
29 | if err != nil {
30 | log.Fatal(err)
31 | os.Exit(1)
32 | }
33 |
34 | defer func() {
35 | if err = f.Close(); err != nil {
36 | log.Fatal(err)
37 | os.Exit(1)
38 | }
39 | }()
40 | }
41 |
42 | b := tui.NewBubble(cfg)
43 | var opts []tea.ProgramOption
44 |
45 | // Always append alt screen program option.
46 | opts = append(opts, tea.WithAltScreen())
47 |
48 | // If mousewheel is enabled, append it to the program options.
49 | if cfg.Settings.EnableMouseWheel {
50 | opts = append(opts, tea.WithMouseAllMotion())
51 | }
52 |
53 | // Initialize new app.
54 | p := tea.NewProgram(b, opts...)
55 | if err := p.Start(); err != nil {
56 | log.Fatal("Failed to start bubbletea-starter", err)
57 | os.Exit(1)
58 | }
59 | },
60 | }
61 |
62 | // Execute executes the root command which starts the application.
63 | func Execute() {
64 | rootCmd.AddCommand(updateCmd)
65 |
66 | if err := rootCmd.Execute(); err != nil {
67 | fmt.Fprintln(os.Stderr, err)
68 | os.Exit(1)
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/cmd/update.go:
--------------------------------------------------------------------------------
1 | package cmd
2 |
3 | import (
4 | "log"
5 | "os"
6 | "os/exec"
7 |
8 | "github.com/spf13/cobra"
9 | )
10 |
11 | var updateCmd = &cobra.Command{
12 | Use: "update",
13 | Short: "Update bubbletea-starter to the latest version",
14 | Long: `Update bubbletea-starter to the latest version.`,
15 | Run: func(cmd *cobra.Command, args []string) {
16 | updateCommand := exec.Command("bash", "-c", "curl -sfL https://raw.githubusercontent.com/knipferrc/bubbletea-starter/main/install.sh | sh")
17 | updateCommand.Stdin = os.Stdin
18 | updateCommand.Stdout = os.Stdout
19 | updateCommand.Stderr = os.Stderr
20 |
21 | err := updateCommand.Run()
22 | if err != nil {
23 | log.Fatal(err)
24 | }
25 |
26 | os.Exit(0)
27 | },
28 | }
29 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/knipferrc/bubbletea-starter
2 |
3 | go 1.18
4 |
5 | require (
6 | github.com/charmbracelet/bubbles v0.10.3
7 | github.com/charmbracelet/bubbletea v0.20.0
8 | github.com/charmbracelet/lipgloss v0.5.0
9 | github.com/spf13/cobra v1.4.0
10 | gopkg.in/yaml.v3 v3.0.1
11 | )
12 |
13 | require (
14 | github.com/containerd/console v1.0.3 // indirect
15 | github.com/inconshreveable/mousetrap v1.0.0 // indirect
16 | github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
17 | github.com/mattn/go-isatty v0.0.14 // indirect
18 | github.com/mattn/go-runewidth v0.0.13 // indirect
19 | github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70 // indirect
20 | github.com/muesli/reflow v0.3.0 // indirect
21 | github.com/muesli/termenv v0.11.1-0.20220212125758-44cd13922739 // indirect
22 | github.com/rivo/uniseg v0.2.0 // indirect
23 | github.com/spf13/pflag v1.0.5 // indirect
24 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
25 | golang.org/x/term v0.0.0-20220526004731-065cf7ba2467 // indirect
26 | )
27 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
2 | github.com/charmbracelet/bubbles v0.10.3 h1:fKarbRaObLn/DCsZO4Y3vKCwRUzynQD9L+gGev1E/ho=
3 | github.com/charmbracelet/bubbles v0.10.3/go.mod h1:jOA+DUF1rjZm7gZHcNyIVW+YrBPALKfpGVdJu8UiJsA=
4 | github.com/charmbracelet/bubbletea v0.19.3/go.mod h1:VuXF2pToRxDUHcBUcPmCRUHRvFATM4Ckb/ql1rBl3KA=
5 | github.com/charmbracelet/bubbletea v0.20.0 h1:/b8LEPgCbNr7WWZ2LuE/BV1/r4t5PyYJtDb+J3vpwxc=
6 | github.com/charmbracelet/bubbletea v0.20.0/go.mod h1:zpkze1Rioo4rJELjRyGlm9T2YNou1Fm4LIJQSa5QMEM=
7 | github.com/charmbracelet/harmonica v0.1.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao=
8 | github.com/charmbracelet/lipgloss v0.4.0/go.mod h1:vmdkHvce7UzX6xkyf4cca8WlwdQ5RQr8fzta+xl7BOM=
9 | github.com/charmbracelet/lipgloss v0.5.0 h1:lulQHuVeodSgDez+3rGiuxlPVXSnhth442DATR2/8t8=
10 | github.com/charmbracelet/lipgloss v0.5.0/go.mod h1:EZLha/HbzEt7cYqdFPovlqy5FZPj0xFhg5SaqxScmgs=
11 | github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ=
12 | github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
13 | github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
14 | github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
15 | github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
16 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
17 | github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
18 | github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
19 | github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
20 | github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
21 | github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
22 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
23 | github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
24 | github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
25 | github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
26 | github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
27 | github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho=
28 | github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70 h1:kMlmsLSbjkikxQJ1IPwaM+7LJ9ltFu/fi8CRzvSnQmA=
29 | github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho=
30 | github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68/go.mod h1:Xk+z4oIWdQqJzsxyjgl3P22oYZnHdZ8FFTHAQQt5BMQ=
31 | github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
32 | github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
33 | github.com/muesli/termenv v0.9.0/go.mod h1:R/LzAKf+suGs4IsO95y7+7DpFHO0KABgnZqtlyx2mBw=
34 | github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0/go.mod h1:Bd5NYQ7pd+SrtBSrSNoBBmXlcY8+Xj4BMJgh8qcZrvs=
35 | github.com/muesli/termenv v0.11.1-0.20220212125758-44cd13922739 h1:QANkGiGr39l1EESqrE0gZw0/AJNYzIvoGLhIoVYtluI=
36 | github.com/muesli/termenv v0.11.1-0.20220212125758-44cd13922739/go.mod h1:Bd5NYQ7pd+SrtBSrSNoBBmXlcY8+Xj4BMJgh8qcZrvs=
37 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
38 | github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
39 | github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
40 | github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
41 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
42 | github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
43 | github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q=
44 | github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
45 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
46 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
47 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
48 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
49 | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
50 | golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
51 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
52 | golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 h1:xHms4gcpe1YE7A3yIllJXP16CMAGuqwO2lX1mTyyRRc=
53 | golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
54 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
55 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
56 | golang.org/x/term v0.0.0-20210422114643-f5beecf764ed/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
57 | golang.org/x/term v0.0.0-20220411215600-e5f449aeb171 h1:EH1Deb8WZJ0xc0WK//leUHXcX9aLE5SymusoTmMZye8=
58 | golang.org/x/term v0.0.0-20220411215600-e5f449aeb171/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
59 | golang.org/x/term v0.0.0-20220526004731-065cf7ba2467 h1:CBpWXWQpIRjzmkkA+M7q9Fqnwd2mZr3AFqexg8YTfoM=
60 | golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
61 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
62 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
63 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
64 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
65 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
66 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
67 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
68 |
--------------------------------------------------------------------------------
/install.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 | # Code generated by godownloader on 2021-09-20T00:19:35Z. DO NOT EDIT.
4 | #
5 |
6 | usage() {
7 | this=$1
8 | cat </dev/null
106 | }
107 | echoerr() {
108 | echo "$@" 1>&2
109 | }
110 | log_prefix() {
111 | echo "$0"
112 | }
113 | _logp=6
114 | log_set_priority() {
115 | _logp="$1"
116 | }
117 | log_priority() {
118 | if test -z "$1"; then
119 | echo "$_logp"
120 | return
121 | fi
122 | [ "$1" -le "$_logp" ]
123 | }
124 | log_tag() {
125 | case $1 in
126 | 0) echo "emerg" ;;
127 | 1) echo "alert" ;;
128 | 2) echo "crit" ;;
129 | 3) echo "err" ;;
130 | 4) echo "warning" ;;
131 | 5) echo "notice" ;;
132 | 6) echo "info" ;;
133 | 7) echo "debug" ;;
134 | *) echo "$1" ;;
135 | esac
136 | }
137 | log_debug() {
138 | log_priority 7 || return 0
139 | echoerr "$(log_prefix)" "$(log_tag 7)" "$@"
140 | }
141 | log_info() {
142 | log_priority 6 || return 0
143 | echoerr "$(log_prefix)" "$(log_tag 6)" "$@"
144 | }
145 | log_err() {
146 | log_priority 3 || return 0
147 | echoerr "$(log_prefix)" "$(log_tag 3)" "$@"
148 | }
149 | log_crit() {
150 | log_priority 2 || return 0
151 | echoerr "$(log_prefix)" "$(log_tag 2)" "$@"
152 | }
153 | uname_os() {
154 | os=$(uname -s | tr '[:upper:]' '[:lower:]')
155 | case "$os" in
156 | cygwin_nt*) os="windows" ;;
157 | mingw*) os="windows" ;;
158 | msys_nt*) os="windows" ;;
159 | esac
160 | echo "$os"
161 | }
162 | uname_arch() {
163 | arch=$(uname -m)
164 | case $arch in
165 | x86_64) arch="amd64" ;;
166 | x86) arch="386" ;;
167 | i686) arch="386" ;;
168 | i386) arch="386" ;;
169 | aarch64) arch="arm64" ;;
170 | armv5*) arch="armv5" ;;
171 | armv6*) arch="armv6" ;;
172 | armv7*) arch="armv7" ;;
173 | esac
174 | echo ${arch}
175 | }
176 | uname_os_check() {
177 | os=$(uname_os)
178 | case "$os" in
179 | darwin) return 0 ;;
180 | dragonfly) return 0 ;;
181 | freebsd) return 0 ;;
182 | linux) return 0 ;;
183 | android) return 0 ;;
184 | nacl) return 0 ;;
185 | netbsd) return 0 ;;
186 | openbsd) return 0 ;;
187 | plan9) return 0 ;;
188 | solaris) return 0 ;;
189 | windows) return 0 ;;
190 | esac
191 | log_crit "uname_os_check '$(uname -s)' got converted to '$os' which is not a GOOS value. Please file bug at https://github.com/client9/shlib"
192 | return 1
193 | }
194 | uname_arch_check() {
195 | arch=$(uname_arch)
196 | case "$arch" in
197 | 386) return 0 ;;
198 | amd64) return 0 ;;
199 | arm64) return 0 ;;
200 | armv5) return 0 ;;
201 | armv6) return 0 ;;
202 | armv7) return 0 ;;
203 | ppc64) return 0 ;;
204 | ppc64le) return 0 ;;
205 | mips) return 0 ;;
206 | mipsle) return 0 ;;
207 | mips64) return 0 ;;
208 | mips64le) return 0 ;;
209 | s390x) return 0 ;;
210 | amd64p32) return 0 ;;
211 | esac
212 | log_crit "uname_arch_check '$(uname -m)' got converted to '$arch' which is not a GOARCH value. Please file bug report at https://github.com/client9/shlib"
213 | return 1
214 | }
215 | untar() {
216 | tarball=$1
217 | case "${tarball}" in
218 | *.tar.gz | *.tgz) tar --no-same-owner -xzf "${tarball}" ;;
219 | *.tar) tar --no-same-owner -xf "${tarball}" ;;
220 | *.zip) unzip "${tarball}" ;;
221 | *)
222 | log_err "untar unknown archive format for ${tarball}"
223 | return 1
224 | ;;
225 | esac
226 | }
227 | http_download_curl() {
228 | local_file=$1
229 | source_url=$2
230 | header=$3
231 | if [ -z "$header" ]; then
232 | code=$(curl -w '%{http_code}' -sL -o "$local_file" "$source_url")
233 | else
234 | code=$(curl -w '%{http_code}' -sL -H "$header" -o "$local_file" "$source_url")
235 | fi
236 | if [ "$code" != "200" ]; then
237 | log_debug "http_download_curl received HTTP status $code"
238 | return 1
239 | fi
240 | return 0
241 | }
242 | http_download_wget() {
243 | local_file=$1
244 | source_url=$2
245 | header=$3
246 | if [ -z "$header" ]; then
247 | wget -q -O "$local_file" "$source_url"
248 | else
249 | wget -q --header "$header" -O "$local_file" "$source_url"
250 | fi
251 | }
252 | http_download() {
253 | log_debug "http_download $2"
254 | if is_command curl; then
255 | http_download_curl "$@"
256 | return
257 | elif is_command wget; then
258 | http_download_wget "$@"
259 | return
260 | fi
261 | log_crit "http_download unable to find wget or curl"
262 | return 1
263 | }
264 | http_copy() {
265 | tmp=$(mktemp)
266 | http_download "${tmp}" "$1" "$2" || return 1
267 | body=$(cat "$tmp")
268 | rm -f "${tmp}"
269 | echo "$body"
270 | }
271 | github_release() {
272 | owner_repo=$1
273 | version=$2
274 | test -z "$version" && version="latest"
275 | giturl="https://github.com/${owner_repo}/releases/${version}"
276 | json=$(http_copy "$giturl" "Accept:application/json")
277 | test -z "$json" && return 1
278 | version=$(echo "$json" | tr -s '\n' ' ' | sed 's/.*"tag_name":"//' | sed 's/".*//')
279 | test -z "$version" && return 1
280 | echo "$version"
281 | }
282 | hash_sha256() {
283 | TARGET=${1:-/dev/stdin}
284 | if is_command gsha256sum; then
285 | hash=$(gsha256sum "$TARGET") || return 1
286 | echo "$hash" | cut -d ' ' -f 1
287 | elif is_command sha256sum; then
288 | hash=$(sha256sum "$TARGET") || return 1
289 | echo "$hash" | cut -d ' ' -f 1
290 | elif is_command shasum; then
291 | hash=$(shasum -a 256 "$TARGET" 2>/dev/null) || return 1
292 | echo "$hash" | cut -d ' ' -f 1
293 | elif is_command openssl; then
294 | hash=$(openssl -dst openssl dgst -sha256 "$TARGET") || return 1
295 | echo "$hash" | cut -d ' ' -f a
296 | else
297 | log_crit "hash_sha256 unable to find command to compute sha-256 hash"
298 | return 1
299 | fi
300 | }
301 | hash_sha256_verify() {
302 | TARGET=$1
303 | checksums=$2
304 | if [ -z "$checksums" ]; then
305 | log_err "hash_sha256_verify checksum file not specified in arg2"
306 | return 1
307 | fi
308 | BASENAME=${TARGET##*/}
309 | want=$(grep "${BASENAME}" "${checksums}" 2>/dev/null | tr '\t' ' ' | cut -d ' ' -f 1)
310 | if [ -z "$want" ]; then
311 | log_err "hash_sha256_verify unable to find checksum for '${TARGET}' in '${checksums}'"
312 | return 1
313 | fi
314 | got=$(hash_sha256 "$TARGET")
315 | if [ "$want" != "$got" ]; then
316 | log_err "hash_sha256_verify checksum for '$TARGET' did not verify ${want} vs $got"
317 | return 1
318 | fi
319 | }
320 | cat /dev/null <