diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 00000000..eb797fca --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,207 @@ +# Copyright (c) 2021 Blacknon. All rights reserved. +# Use of this source code is governed by an MIT license +# that can be found in the LICENSE file. +# reference: +# - https://motemen.hatenablog.com/entry/2019/11/github-actions-crossbuild-rust +# - https://github.com/motemen/lssh/blob/97d3745dcc8931a1d75217573d5ca60705be632f/.github/workflows/release.yml +# - https://github.com/greymd/teip/blob/master/.github/workflows/release.yml + + +name: Release Job. + +on: + push: + branches: + - master + +jobs: + # build rust binary + build: + strategy: + matrix: + include: + - goos: linux + goarch: amd64 + os: ubuntu-latest + ext: tar.gz + - goos: linux + goarch: amd64 + os: ubuntu-latest + ext: rpm + - goos: linux + goarch: amd64 + os: ubuntu-latest + ext: deb + - goos: darwin + goarch: amd64 + os: macos-latest + ext: tar.gz + # - goos: windows + # goarch: amd64 + # os: windows-latest + # ext: zip + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v1 + + - name: Set up Go 1.17 + uses: actions/setup-go@v1 + with: + go-version: 1.17 + + - name: Get version + id: package_version + shell: bash + run: | + VERSION="$(go run ./cmd/lssh/ --version | awk '{print $NF}')" + echo "::set-output name=version::$VERSION" + + - name: Build binary + run: | + go build -o lssh.${{ matrix.goos }}_${{ matrix.goarch }} ./cmd/lssh + go build -o lscp.${{ matrix.goos }}_${{ matrix.goarch }} ./cmd/lscp + go build -o lsftp.${{ matrix.goos }}_${{ matrix.goarch }} ./cmd/lsftp + + - name: Create package file + if: ${{ (matrix.ext == 'tar.gz') || (matrix.ext == 'rpm') || (matrix.ext == 'deb') }} + run: | + _TAR=lssh_${{ steps.package_version.outputs.version }}_${{ matrix.goos }}_${{ matrix.goarch }}.tar.gz + mkdir -p package/bin + mv lssh.${{ matrix.goos }}_${{ matrix.goarch }} package/bin/lssh + mv lscp.${{ matrix.goos }}_${{ matrix.goarch }} package/bin/lscp + mv lsftp.${{ matrix.goos }}_${{ matrix.goarch }} package/bin/lsftp + ## mkdir -p package/man + ## cp man/lssh.1 package/man + cp -r completion package/ + ## sed -i is not used due to difference between macOS and Linux + perl -i -pe s/___VERSION___/${{ steps.package_version.outputs.version }}/ ./package/.tar2package.yml + ## tar czvf "$_TAR" -C "$PWD/package" completion bin man .tar2package.yml + tar czvf "$_TAR" -C "$PWD/package" completion bin .tar2package.yml + + # use: https://github.com/greymd/tar2package + - name: Build rpm + id: rpm + if: matrix.ext == 'rpm' + run: | + _TAR=lssh_${{ steps.package_version.outputs.version }}_${{ matrix.goos }}_${{ matrix.goarch }}.tar.gz + docker run -i "greymd/tar2rpm:1.0.1" < "$_TAR" > lssh_${{ steps.package_version.outputs.version }}_${{ matrix.goos }}_${{ matrix.goarch }}.rpm + echo ::set-output name=sha256::$( sha256sum lssh_${{ steps.package_version.outputs.version }}_${{ matrix.goos }}_${{ matrix.goarch }}.rpm | awk '{print $1}' ) + + # use: https://github.com/greymd/tar2package + - name: Build deb + id: deb + if: matrix.ext == 'deb' + run: | + _TAR=lssh_${{ steps.package_version.outputs.version }}_${{ matrix.goos }}_${{ matrix.goarch }}.tar.gz + docker run -i "greymd/tar2deb:1.0.1" < "$_TAR" > lssh_${{ steps.package_version.outputs.version }}_${{ matrix.goos }}_${{ matrix.goarch }}.deb + echo ::set-output name=sha256::$( sha256sum lssh_${{ steps.package_version.outputs.version }}_${{ matrix.goos }}_${{ matrix.goarch }}.deb | awk '{print $1}' ) + + - name: README for rpm + if: matrix.ext == 'rpm' + run: | + _TAR=lssh_${{ steps.package_version.outputs.version }}_${{ matrix.goos }}_${{ matrix.goarch }}.rpm + + - name: Upload artifact + if: matrix.ext == 'rpm' + uses: actions/upload-artifact@v1 + with: + name: build-${{ matrix.goos }}_${{ matrix.goarch }} + path: lssh_${{ steps.package_version.outputs.version }}_${{ matrix.goos }}_${{ matrix.goarch }}.rpm + + - name: README for deb + if: matrix.ext == 'deb' + run: | + _TAR=lssh_${{ steps.package_version.outputs.version }}_${{ matrix.goos }}_${{ matrix.goarch }}.deb + + - name: Upload artifact + if: matrix.ext == 'deb' + uses: actions/upload-artifact@v1 + with: + name: build-${{ matrix.goos }}_${{ matrix.goarch }} + path: lssh_${{ steps.package_version.outputs.version }}_${{ matrix.goos }}_${{ matrix.goarch }}.deb + + - name: Upload artifact + if: matrix.ext == 'tar.gz' + uses: actions/upload-artifact@v1 + with: + name: build-${{ matrix.goos }}_${{ matrix.goarch }} + path: lssh_${{ steps.package_version.outputs.version }}_${{ matrix.goos }}_${{ matrix.goarch }}.tar.gz + + # create package release + create-release: + needs: + - build + runs-on: ubuntu-latest + outputs: + version: ${{ steps.package_version.outputs.version }} + steps: + - uses: actions/checkout@v1 + + - name: Get version + id: package_version + shell: bash + run: | + VERSION="$(go run ./cmd/lssh/ --version | awk '{print $NF}')" + echo "::set-output name=version::$VERSION" + + - id: create-release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: v${{ steps.package_version.outputs.version }} + release_name: Version ${{ steps.package_version.outputs.version }} + draft: true + prerelease: false + + - run: | + echo '${{ steps.create-release.outputs.upload_url }}' > release_upload_url.txt + + - uses: actions/upload-artifact@v1 + with: + name: create-release + path: release_upload_url.txt + + upload-release: + strategy: + matrix: + include: + - goos: linux + goarch: amd64 + os: ubuntu-latest + ext: tar.gz + - goos: linux + goarch: amd64 + os: ubuntu-latest + ext: rpm + - goos: linux + goarch: amd64 + os: ubuntu-latest + ext: deb + - goos: darwin + goarch: amd64 + os: macos-latest + ext: tar.gz + needs: [create-release] + runs-on: ubuntu-latest + steps: + - uses: actions/download-artifact@v1 + with: + name: create-release + + - id: upload-url + run: | + echo "::set-output name=url::$(cat create-release/release_upload_url.txt)" + + - uses: actions/download-artifact@v1 + with: + name: build-${{ matrix.goos }}_${{ matrix.goarch }} + + - uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.upload-url.outputs.url }} + asset_path: ./build-${{ matrix.goos }}_${{ matrix.goarch }}/lssh_${{ needs.create-release.outputs.version }}_${{ matrix.goos }}_${{ matrix.goarch }}.${{ matrix.ext }} + asset_name: lssh_${{ needs.create-release.outputs.version }}_${{ matrix.goos }}_${{ matrix.goarch }}.${{ matrix.ext }} + asset_content_type: application/octet-stream diff --git a/README.md b/README.md index a598f07a..c60b87be 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,15 @@ TUI list select ssh/scp/sftp client tools. ## Description -command to read a prepared list in advance and connect ssh/scp/sftp the selected host. List file is set in yaml format. When selecting a host, you can filter by keywords. Can execute commands concurrently to multiple hosts. Supported multiple ssh proxy, http/socks5 proxy, x11 forward, and port forwarding. +This command utility to read a prepared list in advance and connect ssh/scp/sftp the selected host. +List file is set in yaml format. +When selecting a host, you can filter by keywords. +Can execute commands concurrently to multiple hosts. + +lssh also has a shell (parallel shell) that connects to multiple hosts at the same time and pipes the execution results of local commands and remote hosts. +In addition, lsftp also has a shell that can be connected in parallel. + +Supported multiple ssh proxy, http/socks5 proxy, x11 forward, and port forwarding. ## Features @@ -102,7 +110,7 @@ option(lssh) blacknon(blacknon@orebibou.com) VERSION: - 0.6.4 + 0.6.5 USAGE: # connect ssh @@ -143,7 +151,7 @@ option(lscp) blacknon(blacknon@orebibou.com) VERSION: - 0.6.4 + 0.6.5 USAGE: # local to remote scp @@ -178,7 +186,7 @@ option(lsftp) blacknon(blacknon@orebibou.com) VERSION: - 0.6.4 + 0.6.5 USAGE: # start lsftp shell diff --git a/cmd/lscp/args.go b/cmd/lscp/args.go index 2083f0fe..c4b6634b 100644 --- a/cmd/lscp/args.go +++ b/cmd/lscp/args.go @@ -60,7 +60,7 @@ USAGE: app.Name = "lscp" app.Usage = "TUI list select and parallel scp client command." app.Copyright = "blacknon(blacknon@orebibou.com)" - app.Version = "0.6.4" + app.Version = "0.6.5" // options // TODO(blacknon): オプションの追加(0.7.0) diff --git a/cmd/lsftp/args.go b/cmd/lsftp/args.go index 16ca0aaa..4cb104ae 100644 --- a/cmd/lsftp/args.go +++ b/cmd/lsftp/args.go @@ -51,7 +51,7 @@ USAGE: app.Name = "lsftp" app.Usage = "TUI list select and parallel sftp client command." app.Copyright = "blacknon(blacknon@orebibou.com)" - app.Version = "0.6.4" + app.Version = "0.6.5" app.Flags = []cli.Flag{ cli.StringFlag{Name: "file,F", Value: defConf, Usage: "config file path"}, diff --git a/cmd/lssh/args.go b/cmd/lssh/args.go index b8179c53..63bafee4 100644 --- a/cmd/lssh/args.go +++ b/cmd/lssh/args.go @@ -65,7 +65,7 @@ USAGE: app.Name = "lssh" app.Usage = "TUI list select and parallel ssh client command." app.Copyright = "blacknon(blacknon@orebibou.com)" - app.Version = "0.6.4" + app.Version = "0.6.5" // TODO(blacknon): オプションの追加 // -f ... バックグラウンドでの接続(X11接続やport forwardingをバックグラウンドで実行する場合など)。 diff --git a/misc/completions/zsh/_lssh b/completion/zsh/_lssh similarity index 100% rename from misc/completions/zsh/_lssh rename to completion/zsh/_lssh diff --git a/conf/conf.go b/conf/conf.go index 9ed84487..e7af8fc0 100644 --- a/conf/conf.go +++ b/conf/conf.go @@ -108,34 +108,46 @@ type ServerConfig struct { PKCS11Provider string `toml:"pkcs11provider"` // PKCS11 Provider PATH PKCS11PIN string `toml:"pkcs11pin"` // PKCS11 PIN code - // pre | post command setting - PreCmd string `toml:"pre_cmd"` + // pre execute command + PreCmd string `toml:"pre_cmd"` + + // post execute command PostCmd string `toml:"post_cmd"` // proxy setting - ProxyType string `toml:"proxy_type"` - Proxy string `toml:"proxy"` - ProxyCommand string `toml:"proxy_cmd"` // OpenSSH type proxy setting + ProxyType string `toml:"proxy_type"` + + Proxy string `toml:"proxy"` + + // OpenSSH type proxy setting + ProxyCommand string `toml:"proxy_cmd"` // local rcfile setting - LocalRcUse string `toml:"local_rc"` // yes|no (default: yes) + // yes|no (default: yes) + LocalRcUse string `toml:"local_rc"` LocalRcPath []string `toml:"local_rc_file"` LocalRcDecodeCmd string `toml:"local_rc_decode_cmd"` - // local/remote port forwarding setting - PortForwardMode string `toml:"port_forward"` // [`L`,`l`,`LOCAL`,`local`]|[`R`,`r`,`REMOTE`,`remote`] - PortForwardLocal string `toml:"port_forward_local"` // port forward (local). "host:port" - PortForwardRemote string `toml:"port_forward_remote"` // port forward (remote). "host:port" + // local/remote port forwarding setting. + // ex. [`L`,`l`,`LOCAL`,`local`]|[`R`,`r`,`REMOTE`,`remote`] + PortForwardMode string `toml:"port_forward"` + + // port forward (local). "host:port" + PortForwardLocal string `toml:"port_forward_local"` + + // port forward (remote). "host:port" + PortForwardRemote string `toml:"port_forward_remote"` // local/remote port forwarding settings - // {[`L`,`l`,`LOCAL`,`local`]|[`R`,`r`,`REMOTE`,`remote`]}:[localaddress]:[localport]:[remoteaddress]:[remoteport] + // ex. {[`L`,`l`,`LOCAL`,`local`]|[`R`,`r`,`REMOTE`,`remote`]}:[localaddress]:[localport]:[remoteaddress]:[remoteport] PortForwards []string `toml:"port_forwards"` // local/remote Port Forwarding slice. Forwards []*PortForward // Dynamic Port Forwarding setting - DynamicPortForward string `toml:"dynamic_port_forward"` // ex.) "11080" + // ex.) "11080" + DynamicPortForward string `toml:"dynamic_port_forward"` // x11 forwarding setting X11 bool `toml:"x11"` @@ -177,7 +189,8 @@ type PortForward struct { } // ReadConf load configuration file and return Config structure -// TODO(blacknon): リファクタリング!(v0.6.1) 外出しや処理のまとめなど +// TODO(blacknon): リファクタリング!(v0.6.5) 外出しや処理のまとめなど +// TODO(blacknon): ~/.lssh.confがなくても、openssh用のファイルがアレばそれをみるように処理 func ReadConf(confPath string) (config Config) { // user path usr, _ := user.Current() diff --git a/go.mod b/go.mod index 0145a1d9..5b141581 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ require ( github.com/BurntSushi/toml v0.3.1 github.com/blacknon/go-sshlib v0.1.5 github.com/blacknon/textcol v0.0.1 - github.com/c-bata/go-prompt v0.2.5 + github.com/c-bata/go-prompt v0.2.6 github.com/dustin/go-humanize v1.0.0 github.com/kevinburke/ssh_config v0.0.0-20190724205821-6cfae18c12b8 github.com/mattn/go-runewidth v0.0.13 @@ -36,7 +36,7 @@ require ( github.com/mattn/go-tty v0.0.3 // indirect github.com/miekg/pkcs11 v1.1.1 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pkg/term v1.1.0 // indirect + github.com/pkg/term v1.2.0-beta.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/thales-e-security/pool v0.0.2 // indirect diff --git a/go.sum b/go.sum index 5dcc7d40..feb905d7 100644 --- a/go.sum +++ b/go.sum @@ -14,8 +14,8 @@ github.com/blacknon/go-sshlib v0.1.5 h1:nHuIi022DS72kf5/WTBRE15NHW43Qb+1umM76Gms github.com/blacknon/go-sshlib v0.1.5/go.mod h1:sgMpYTYseacjT4Bt9pPwjMd+eMXsLGCjDtoFugXKYDE= github.com/blacknon/textcol v0.0.1 h1:x9h7yLPGyr8Pdz12XJ30h7Iz5mJlKd0CzfGYxhrmnk8= github.com/blacknon/textcol v0.0.1/go.mod h1:1x1tHA4cEgiQ8BsKysc60OALSZMG9WjmbjmJvPqIInQ= -github.com/c-bata/go-prompt v0.2.5 h1:3zg6PecEywxNn0xiqcXHD96fkbxghD+gdB2tbsYfl+Y= -github.com/c-bata/go-prompt v0.2.5/go.mod h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7FVlAwDAVw= +github.com/c-bata/go-prompt v0.2.6 h1:POP+nrHE+DfLYx370bedwNhsqmpCUynWPxuHi0C5vZI= +github.com/c-bata/go-prompt v0.2.6/go.mod h1:/LMAke8wD2FsNu9EXNdHxNLbd9MedkPnCdfpU9wwHfY= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dchest/bcrypt_pbkdf v0.0.0-20150205184540-83f37f9c154a h1:saTgr5tMLFnmy/yg3qDTft4rE5DY2uJ/cCxCe3q0XTU= @@ -58,8 +58,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.10.1 h1:VasscCm72135zRysgrJDKsntdmPN+OuU3+nnHYA9wyc= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= -github.com/pkg/term v1.1.0 h1:xIAAdCMh3QIAy+5FrE8Ad8XoDhEU4ufwbaSozViP9kk= -github.com/pkg/term v1.1.0/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw= +github.com/pkg/term v1.2.0-beta.2 h1:L3y/h2jkuBVFdWiJvNfYfKmzcCnILw7mJWm2JQuMppw= +github.com/pkg/term v1.2.0-beta.2/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw= 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= diff --git a/output/output.go b/output/output.go index 6d4fd895..893e3014 100644 --- a/output/output.go +++ b/output/output.go @@ -218,8 +218,8 @@ func OutColorStrings(num int, inStrings string) (str string) { return } -// PushPipeWriter is PipeReader to []io.WriteCloser. -func PushPipeWriter(isExit <-chan bool, output []io.WriteCloser, input io.Reader) { +// PushInput is Reader([io.PipeReader, os.Stdin]) to []io.WriteCloser. +func PushInput(isExit <-chan bool, output []io.WriteCloser, input io.Reader) { rd := bufio.NewReader(input) loop: for { @@ -235,37 +235,12 @@ loop: } } - switch err { - case nil: - continue - case io.ErrClosedPipe, io.EOF: - break loop - } - - select { - case <-isExit: - break loop - case <-time.After(10 * time.Millisecond): - continue - } - } - - // close output - for _, w := range output { - w.Close() - } -} - -// PushInput is send input to ssh Session Stdin -func PushInput(isExit <-chan bool, output []io.WriteCloser, inputChar byte) { - rd := bufio.NewReader(os.Stdin) -loop: - for { - data, _ := rd.ReadBytes(inputChar) - - if len(data) > 0 { - for _, w := range output { - w.Write(data) + if input != os.Stdin { + switch err { + case nil: + continue + case io.ErrClosedPipe, io.EOF: + break loop } } @@ -275,8 +250,8 @@ loop: case <-time.After(10 * time.Millisecond): continue } - } + // close output for _, w := range output { w.Close() diff --git a/package/.tar2package.yml b/package/.tar2package.yml new file mode 100644 index 00000000..b0c802ad --- /dev/null +++ b/package/.tar2package.yml @@ -0,0 +1,10 @@ +name : lssh +cmdname : lssh +summary : List selection type alternative ssh/scp/sftp client. +description : List selection type alternative ssh/scp/sftp client. parallel connect ssh, local bashrc use connext etc. +version : ___VERSION___ +changelog : See https://github.com/blacknon/lssh/releases +url : https://github.com/blacknon/lssh +author : blacknon +email : blacknon@orebibou.com +libdir : null diff --git a/ssh/cmd.go b/ssh/cmd.go index c9c3df76..8953c430 100644 --- a/ssh/cmd.go +++ b/ssh/cmd.go @@ -132,11 +132,8 @@ func (r *Run) cmd() (err error) { var stdinData []byte switch { case r.IsParallel && len(r.ServerList) > 1: - if r.isStdinPipe { - go output.PushPipeWriter(exitInput, writers, os.Stdin) - } else { - go output.PushInput(exitInput, writers, byte('\n')) - } + go output.PushInput(exitInput, writers, os.Stdin) + case !r.IsParallel && len(r.ServerList) > 1: if r.isStdinPipe { stdinData, _ = ioutil.ReadAll(os.Stdin) diff --git a/ssh/pshell_cmd.go b/ssh/pshell_cmd.go index c8040a5c..39cb3ff1 100644 --- a/ssh/pshell_cmd.go +++ b/ssh/pshell_cmd.go @@ -302,10 +302,11 @@ func (ps *pShell) executeRemotePipeLine(pline pipeLine, in *io.PipeReader, out * // push input to pararell session // (Only when input is os.Stdin and output is os.Stdout). if stdout == os.Stdout { - go output.PushInput(exitInput, writers, byte('\n')) + // go output.PushInput(exitInput, writers, byte('\n')) + go output.PushInput(exitInput, writers, stdin) } case *io.PipeReader: - go output.PushPipeWriter(exitInput, writers, stdin) + go output.PushInput(exitInput, writers, stdin) } // run command @@ -338,16 +339,14 @@ func (ps *pShell) executeRemotePipeLine(pline pipeLine, in *io.PipeReader, out * // wait time (0.500 sec) time.Sleep(500 * time.Millisecond) - // Print message `Please input enter` (Only when input is os.Stdin and output is os.Stdout). - // Note: This necessary for using Blocking.IO. + // send exit + ch <- true + + // exit input. if stdin == os.Stdin && stdout == os.Stdout { - fmt.Fprintf(os.Stderr, "\n---\n%s\n", "Command exit. Please input Enter key.") exitInput <- true } - // send exit - ch <- true - // close out switch stdout.(type) { case *io.PipeWriter: @@ -430,7 +429,7 @@ func (ps *pShell) wait(num int, ch <-chan bool) { } // setInput -func setInput(in io.ReadCloser) (stdin io.Reader) { +func setInput(in io.ReadCloser) (stdin io.ReadCloser) { if reflect.ValueOf(in).IsNil() { stdin = os.Stdin } else { @@ -441,7 +440,7 @@ func setInput(in io.ReadCloser) (stdin io.Reader) { } // setOutput -func setOutput(out io.WriteCloser) (stdout io.Writer) { +func setOutput(out io.WriteCloser) (stdout io.WriteCloser) { if reflect.ValueOf(out).IsNil() { stdout = os.Stdout } else { diff --git a/vendor/github.com/c-bata/go-prompt/README.md b/vendor/github.com/c-bata/go-prompt/README.md index e3b34723..cfcd7a39 100644 --- a/vendor/github.com/c-bata/go-prompt/README.md +++ b/vendor/github.com/c-bata/go-prompt/README.md @@ -51,6 +51,8 @@ func main() { * [docker-slim/docker-slim: Don't change anything in your Docker container image and minify it by up to 30x (and for compiled languages even more) making it secure too! (free and open source)](https://github.com/docker-slim/docker-slim) * [rueyaa332266/ezcron: Ezcron is a CLI tool, helping you deal with cron expression easier.](https://github.com/rueyaa332266/ezcron) * [qingstor/qsctl: Advanced command line tool for QingStor Object Storage.](https://github.com/qingstor/qsctl) +* [segmentio/topicctl: Tool for declarative management of Kafka topics](https://github.com/segmentio/topicctl) +* [chriswalz/bit: Bit is a modern Git CLI](https://github.com/chriswalz/bit) * (If you create a CLI utility using go-prompt and want your own project to be listed here, please submit a GitHub issue.) ## Features diff --git a/vendor/github.com/c-bata/go-prompt/internal/term/raw.go b/vendor/github.com/c-bata/go-prompt/internal/term/raw.go index e2a4a7b8..7aa3ed8d 100644 --- a/vendor/github.com/c-bata/go-prompt/internal/term/raw.go +++ b/vendor/github.com/c-bata/go-prompt/internal/term/raw.go @@ -25,5 +25,5 @@ func SetRaw(fd int) error { n.Cc[syscall.VMIN] = 1 n.Cc[syscall.VTIME] = 0 - return termios.Tcsetattr(uintptr(fd), termios.TCSANOW, (*unix.Termios)(&n)) + return termios.Tcsetattr(uintptr(fd), termios.TCSANOW, (*unix.Termios)(n)) } diff --git a/vendor/github.com/c-bata/go-prompt/internal/term/term.go b/vendor/github.com/c-bata/go-prompt/internal/term/term.go index f6dc3cd4..3f3a53c0 100644 --- a/vendor/github.com/c-bata/go-prompt/internal/term/term.go +++ b/vendor/github.com/c-bata/go-prompt/internal/term/term.go @@ -10,16 +10,16 @@ import ( ) var ( - saveTermios unix.Termios + saveTermios *unix.Termios saveTermiosFD int saveTermiosOnce sync.Once ) -func getOriginalTermios(fd int) (unix.Termios, error) { +func getOriginalTermios(fd int) (*unix.Termios, error) { var err error saveTermiosOnce.Do(func() { saveTermiosFD = fd - err = termios.Tcgetattr(uintptr(fd), &saveTermios) + saveTermios, err = termios.Tcgetattr(uintptr(fd)) }) return saveTermios, err } @@ -30,5 +30,5 @@ func Restore() error { if err != nil { return err } - return termios.Tcsetattr(uintptr(saveTermiosFD), termios.TCSANOW, &o) + return termios.Tcsetattr(uintptr(saveTermiosFD), termios.TCSANOW, o) } diff --git a/vendor/github.com/pkg/term/termios/ioctl.go b/vendor/github.com/pkg/term/termios/ioctl.go index ce37d78f..10aa2b13 100644 --- a/vendor/github.com/pkg/term/termios/ioctl.go +++ b/vendor/github.com/pkg/term/termios/ioctl.go @@ -1,16 +1,9 @@ -// +build !windows,!solaris +// +build !windows package termios -import ( - "syscall" - - "golang.org/x/sys/unix" -) +import "golang.org/x/sys/unix" func ioctl(fd, request, argp uintptr) error { - if _, _, e := unix.Syscall6(syscall.SYS_IOCTL, fd, request, argp, 0, 0, 0); e != 0 { - return e - } - return nil + return unix.IoctlSetInt(int(fd), uint(request), int(argp)) } diff --git a/vendor/github.com/pkg/term/termios/ioctl_darwin.go b/vendor/github.com/pkg/term/termios/ioctl_darwin.go deleted file mode 100644 index 5d9b91ab..00000000 --- a/vendor/github.com/pkg/term/termios/ioctl_darwin.go +++ /dev/null @@ -1,10 +0,0 @@ -package termios - -const ( - _IOC_PARAM_SHIFT = 13 - _IOC_PARAM_MASK = (1 << _IOC_PARAM_SHIFT) - 1 -) - -func _IOC_PARM_LEN(ioctl uintptr) uintptr { - return (ioctl >> 16) & _IOC_PARAM_MASK -} diff --git a/vendor/github.com/pkg/term/termios/ioctl_solaris.go b/vendor/github.com/pkg/term/termios/ioctl_solaris.go deleted file mode 100644 index 95c40ea8..00000000 --- a/vendor/github.com/pkg/term/termios/ioctl_solaris.go +++ /dev/null @@ -1,7 +0,0 @@ -package termios - -import "golang.org/x/sys/unix" - -func ioctl(fd, request, argp uintptr) error { - return unix.IoctlSetInt(int(fd), uint(request), int(argp)) -} diff --git a/vendor/github.com/pkg/term/termios/pty_bsd.go b/vendor/github.com/pkg/term/termios/pty_cgo.go similarity index 94% rename from vendor/github.com/pkg/term/termios/pty_bsd.go rename to vendor/github.com/pkg/term/termios/pty_cgo.go index 45336d41..568f9cf5 100644 --- a/vendor/github.com/pkg/term/termios/pty_bsd.go +++ b/vendor/github.com/pkg/term/termios/pty_cgo.go @@ -1,4 +1,4 @@ -// +build dragonfly openbsd +// +build dragonfly openbsd solaris package termios diff --git a/vendor/github.com/pkg/term/termios/pty_darwin.go b/vendor/github.com/pkg/term/termios/pty_darwin.go index 9377112b..a57357a9 100644 --- a/vendor/github.com/pkg/term/termios/pty_darwin.go +++ b/vendor/github.com/pkg/term/termios/pty_darwin.go @@ -11,6 +11,15 @@ func open_pty_master() (uintptr, error) { return open_device("/dev/ptmx") } +const ( + _IOC_PARAM_SHIFT = 13 + _IOC_PARAM_MASK = (1 << _IOC_PARAM_SHIFT) - 1 +) + +func _IOC_PARM_LEN(ioctl uintptr) uintptr { + return (ioctl >> 16) & _IOC_PARAM_MASK +} + func Ptsname(fd uintptr) (string, error) { n := make([]byte, _IOC_PARM_LEN(unix.TIOCPTYGNAME)) diff --git a/vendor/github.com/pkg/term/termios/pty_freebsd.go b/vendor/github.com/pkg/term/termios/pty_freebsd.go index d449fbf4..f7bf882b 100644 --- a/vendor/github.com/pkg/term/termios/pty_freebsd.go +++ b/vendor/github.com/pkg/term/termios/pty_freebsd.go @@ -2,7 +2,8 @@ package termios import ( "fmt" - "unsafe" + + "golang.org/x/sys/unix" ) func posix_openpt(oflag int) (fd uintptr, err error) { @@ -20,17 +21,12 @@ func open_pty_master() (uintptr, error) { } func Ptsname(fd uintptr) (string, error) { - var n uintptr - err := ioctl(fd, unix.TIOCGPTN, uintptr(unsafe.Pointer(&n))) - if err != nil { - return "", err - } - return fmt.Sprintf("/dev/pts/%d", n), nil + n, err := unix.IoctlGetInt(int(fd), unix.TIOCGPTN) + return fmt.Sprintf("/dev/pts/%d", n), err } func grantpt(fd uintptr) error { - var n uintptr - return ioctl(fd, unix.TIOCGPTN, uintptr(unsafe.Pointer(&n))) + return unix.IoctlSetInt(int(fd), unix.TIOCGPTN, 0) } func unlockpt(fd uintptr) error { diff --git a/vendor/github.com/pkg/term/termios/pty_linux.go b/vendor/github.com/pkg/term/termios/pty_linux.go index fc9954ef..018511c1 100644 --- a/vendor/github.com/pkg/term/termios/pty_linux.go +++ b/vendor/github.com/pkg/term/termios/pty_linux.go @@ -12,12 +12,8 @@ func open_pty_master() (uintptr, error) { } func Ptsname(fd uintptr) (string, error) { - var n uintptr - err := ioctl(fd, unix.TIOCGPTN, uintptr(unsafe.Pointer(&n))) - if err != nil { - return "", err - } - return fmt.Sprintf("/dev/pts/%d", n), nil + n, err := unix.IoctlGetInt(int(fd), unix.TIOCGPTN) + return fmt.Sprintf("/dev/pts/%d", n), err } func grantpt(fd uintptr) error { diff --git a/vendor/github.com/pkg/term/termios/pty_netbsd.go b/vendor/github.com/pkg/term/termios/pty_netbsd.go index a40e7f9a..c921017b 100644 --- a/vendor/github.com/pkg/term/termios/pty_netbsd.go +++ b/vendor/github.com/pkg/term/termios/pty_netbsd.go @@ -7,11 +7,7 @@ import ( ) func open_pty_master() (uintptr, error) { - fd, err := unix.Open("/dev/ptmx", unix.O_NOCTTY|unix.O_RDWR, 0666) - if err != nil { - return 0, err - } - return uintptr(fd), nil + return open_device("/dev/ptmx") } func Ptsname(fd uintptr) (string, error) { diff --git a/vendor/github.com/pkg/term/termios/pty_solaris.go b/vendor/github.com/pkg/term/termios/pty_solaris.go deleted file mode 100644 index 6fccd1ee..00000000 --- a/vendor/github.com/pkg/term/termios/pty_solaris.go +++ /dev/null @@ -1,33 +0,0 @@ -package termios - -// #include -import "C" - -import "syscall" - -func open_pty_master() (uintptr, error) { - return open_device("/dev/ptmx") -} - -func Ptsname(fd uintptr) (string, error) { - slavename := C.GoString(C.ptsname(C.int(fd))) - return slavename, nil -} - -func grantpt(fd uintptr) error { - rc := C.grantpt(C.int(fd)) - if rc == 0 { - return nil - } else { - return syscall.Errno(rc) - } -} - -func unlockpt(fd uintptr) error { - rc := C.unlockpt(C.int(fd)) - if rc == 0 { - return nil - } else { - return syscall.Errno(rc) - } -} diff --git a/vendor/github.com/pkg/term/termios/termios.go b/vendor/github.com/pkg/term/termios/termios.go index a69c1f0d..8ef8ea2c 100644 --- a/vendor/github.com/pkg/term/termios/termios.go +++ b/vendor/github.com/pkg/term/termios/termios.go @@ -26,6 +26,11 @@ func Tiocmbic(fd uintptr, status int) error { return unix.IoctlSetPointerInt(int(fd), unix.TIOCMBIC, status) } +// Tiocoutq return the number of bytes in the output buffer. +func Tiocoutq(fd uintptr) (int, error) { + return unix.IoctlGetInt(int(fd), unix.TIOCOUTQ) +} + // Cfmakecbreak modifies attr for cbreak mode. func Cfmakecbreak(attr *unix.Termios) { attr.Lflag &^= unix.ECHO | unix.ICANON diff --git a/vendor/github.com/pkg/term/termios/termios_bsd.go b/vendor/github.com/pkg/term/termios/termios_bsd.go index f433f375..86221c20 100644 --- a/vendor/github.com/pkg/term/termios/termios_bsd.go +++ b/vendor/github.com/pkg/term/termios/termios_bsd.go @@ -9,9 +9,6 @@ import ( ) const ( - FREAD = 0x0001 - FWRITE = 0x0002 - IXON = 0x00000200 IXOFF = 0x00000400 IXANY = 0x00000800 @@ -21,8 +18,8 @@ const ( ) // Tcgetattr gets the current serial port settings. -func Tcgetattr(fd uintptr, argp *unix.Termios) error { - return unix.IoctlSetTermios(int(fd), unix.TIOCGETA, argp) +func Tcgetattr(fd uintptr) (*unix.Termios, error) { + return unix.IoctlGetTermios(int(fd), unix.TIOCGETA) } // Tcsetattr sets the current serial port settings. @@ -43,7 +40,7 @@ func Tcsetattr(fd, opt uintptr, argp *unix.Termios) error { // Tcsendbreak function transmits a continuous stream of zero-valued bits for // four-tenths of a second to the terminal referenced by fildes. The duration // parameter is ignored in this implementation. -func Tcsendbreak(fd, duration uintptr) error { +func Tcsendbreak(fd uintptr, duration int) error { if err := unix.IoctlSetInt(int(fd), unix.TIOCSBRK, 0); err != nil { return err } @@ -58,18 +55,7 @@ func Tcdrain(fd uintptr) error { // Tcflush discards data written to the object referred to by fd but not transmitted, or data received but not read, depending on the value of which. func Tcflush(fd, which uintptr) error { - var com int - switch which { - case unix.TCIFLUSH: - com = FREAD - case unix.TCOFLUSH: - com = FWRITE - case unix.TCIOFLUSH: - com = FREAD | FWRITE - default: - return unix.EINVAL - } - return unix.IoctlSetPointerInt(int(fd), unix.TIOCFLUSH, com) + return unix.IoctlSetPointerInt(int(fd), unix.TIOCFLUSH, int(which)) } // Cfgetispeed returns the input baud rate stored in the termios structure. @@ -82,8 +68,3 @@ func Cfgetospeed(attr *unix.Termios) uint32 { return uint32(attr.Ospeed) } func Tiocinq(fd uintptr) (int, error) { return 0, nil } - -// Tiocoutq return the number of bytes in the output buffer. -func Tiocoutq(fd uintptr) (int, error) { - return unix.IoctlGetInt(int(fd), unix.TIOCOUTQ) -} diff --git a/vendor/github.com/pkg/term/termios/termios_linux.go b/vendor/github.com/pkg/term/termios/termios_linux.go index 9315fe4c..131a64b7 100644 --- a/vendor/github.com/pkg/term/termios/termios_linux.go +++ b/vendor/github.com/pkg/term/termios/termios_linux.go @@ -5,13 +5,6 @@ import ( ) const ( - TCSETS = 0x5402 - TCSETSW = 0x5403 - TCSETSF = 0x5404 - TCFLSH = 0x540B - TCSBRK = 0x5409 - TCSBRKP = 0x5425 - IXON = 0x00000400 IXANY = 0x00000800 IXOFF = 0x00001000 @@ -19,8 +12,8 @@ const ( ) // Tcgetattr gets the current serial port settings. -func Tcgetattr(fd uintptr, argp *unix.Termios) error { - return unix.IoctlSetTermios(int(fd), unix.TCGETS, argp) +func Tcgetattr(fd uintptr) (*unix.Termios, error) { + return unix.IoctlGetTermios(int(fd), unix.TCGETS) } // Tcsetattr sets the current serial port settings. @@ -28,11 +21,11 @@ func Tcsetattr(fd, action uintptr, argp *unix.Termios) error { var request uintptr switch action { case TCSANOW: - request = TCSETS + request = unix.TCSETS case TCSADRAIN: - request = TCSETSW + request = unix.TCSETSW case TCSAFLUSH: - request = TCSETSF + request = unix.TCSETSF default: return unix.EINVAL } @@ -44,23 +37,23 @@ func Tcsetattr(fd, action uintptr, argp *unix.Termios) error { // duration is zero, it transmits zero-valued bits for at least 0.25 seconds, and not more that 0.5 seconds. // If duration is not zero, it sends zero-valued bits for some // implementation-defined length of time. -func Tcsendbreak(fd, duration uintptr) error { - return ioctl(fd, TCSBRKP, duration) +func Tcsendbreak(fd uintptr, duration int) error { + return unix.IoctlSetInt(int(fd), unix.TCSBRKP, duration) } // Tcdrain waits until all output written to the object referred to by fd has been transmitted. func Tcdrain(fd uintptr) error { // simulate drain with TCSADRAIN - var attr unix.Termios - if err := Tcgetattr(fd, &attr); err != nil { + attr, err := Tcgetattr(fd) + if err != nil { return err } - return Tcsetattr(fd, TCSADRAIN, &attr) + return Tcsetattr(fd, TCSADRAIN, attr) } // Tcflush discards data written to the object referred to by fd but not transmitted, or data received but not read, depending on the value of selector. func Tcflush(fd, selector uintptr) error { - return ioctl(fd, TCFLSH, selector) + return unix.IoctlSetInt(int(fd), unix.TCFLSH, int(selector)) } // Tiocinq returns the number of bytes in the input buffer. @@ -68,11 +61,6 @@ func Tiocinq(fd uintptr) (int, error) { return unix.IoctlGetInt(int(fd), unix.TIOCINQ) } -// Tiocoutq return the number of bytes in the output buffer. -func Tiocoutq(fd uintptr) (int, error) { - return unix.IoctlGetInt(int(fd), unix.TIOCOUTQ) -} - // Cfgetispeed returns the input baud rate stored in the termios structure. func Cfgetispeed(attr *unix.Termios) uint32 { return attr.Ispeed } diff --git a/vendor/github.com/pkg/term/termios/termios_solaris.go b/vendor/github.com/pkg/term/termios/termios_solaris.go index cea79f18..959ceb38 100644 --- a/vendor/github.com/pkg/term/termios/termios_solaris.go +++ b/vendor/github.com/pkg/term/termios/termios_solaris.go @@ -13,7 +13,6 @@ const ( TCSETS = 0x5402 TCSETSW = 0x5403 TCSETSF = 0x5404 - TCFLSH = 0x540B TCSBRK = 0x5409 TCSBRKP = 0x5425 @@ -23,14 +22,9 @@ const ( CRTSCTS = 0x80000000 ) -// See /usr/include/sys/termios.h -const FIORDCHK = C.FIORDCHK - // Tcgetattr gets the current serial port settings. -func Tcgetattr(fd uintptr, argp *unix.Termios) error { - termios, err := unix.IoctlGetTermios(int(fd), unix.TCGETS) - *argp = *(tiosTounix(termios)) - return err +func Tcgetattr(fd uintptr) (*unix.Termios, error) { + return unix.IoctlGetTermios(int(fd), unix.TCGETS) } // Tcsetattr sets the current serial port settings. @@ -43,8 +37,8 @@ func Tcsetattr(fd, action uintptr, argp *unix.Termios) error { // duration is zero, it transmits zero-valued bits for at least 0.25 seconds, and not more that 0.5 seconds. // If duration is not zero, it sends zero-valued bits for some // implementation-defined length of time. -func Tcsendbreak(fd, duration uintptr) error { - return ioctl(fd, TCSBRKP, duration) +func Tcsendbreak(fd uintptr, duration int) error { + return ioctl(fd, TCSBRKP, uintptr(duration)) } // Tcdrain waits until all output written to the object referred to by fd has been transmitted. @@ -59,18 +53,12 @@ func Tcdrain(fd uintptr) error { // Tcflush discards data written to the object referred to by fd but not transmitted, or data received but not read, depending on the value of selector. func Tcflush(fd, selector uintptr) error { - return ioctl(fd, TCFLSH, selector) + return ioctl(fd, unix.TCFLSH, selector) } // Tiocinq returns the number of bytes in the input buffer. -func Tiocinq(fd uintptr, argp *int) (err error) { - *argp, err = unix.IoctlGetInt(int(fd), FIORDCHK) - return err -} - -// Tiocoutq return the number of bytes in the output buffer. -func Tiocoutq(fd uintptr, argp *int) error { - return ioctl(fd, unix.TIOCOUTQ, uintptr(unsafe.Pointer(argp))) +func Tiocinq(fd uintptr) (int, error) { + return unix.IoctlGetInt(int(fd), unix.FIORDCHK) } // Cfgetispeed returns the input baud rate stored in the termios structure. diff --git a/vendor/github.com/pkg/term/termios/termios_windows.go b/vendor/github.com/pkg/term/termios/termios_windows.go deleted file mode 100644 index 884378cb..00000000 --- a/vendor/github.com/pkg/term/termios/termios_windows.go +++ /dev/null @@ -1 +0,0 @@ -package termios diff --git a/vendor/modules.txt b/vendor/modules.txt index 3aeaa3e0..158fda26 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -22,7 +22,7 @@ github.com/blacknon/go-sshlib # github.com/blacknon/textcol v0.0.1 ## explicit github.com/blacknon/textcol -# github.com/c-bata/go-prompt v0.2.5 +# github.com/c-bata/go-prompt v0.2.6 ## explicit; go 1.14 github.com/c-bata/go-prompt github.com/c-bata/go-prompt/completer @@ -78,7 +78,7 @@ github.com/pkg/errors # github.com/pkg/sftp v1.10.1 ## explicit; go 1.12 github.com/pkg/sftp -# github.com/pkg/term v1.1.0 +# github.com/pkg/term v1.2.0-beta.2 ## explicit; go 1.14 github.com/pkg/term/termios # github.com/pmezard/go-difflib v1.0.0