├── .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 | Latest Release 5 | GoDoc 6 | Build Status 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 <