This is an automated email from the ASF dual-hosted git repository.

hoshea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking-cli.git


The following commit(s) were added to refs/heads/master by this push:
     new c54499d  Support auto-completion for bash  and powershell (#108)
c54499d is described below

commit c54499dbc130dce02473b133f9dc9cb8be24e364
Author: Team317 <52828870+tom-da...@users.noreply.github.com>
AuthorDate: Mon Aug 16 20:03:12 2021 +0800

    Support auto-completion for bash  and powershell (#108)
---
 README.md                                  | 34 ++++++++++++++
 cmd/swctl/main.go                          |  8 ++++
 internal/commands/completion/bash.go       | 58 ++++++++++++++++++++++++
 internal/commands/completion/completion.go | 31 +++++++++++++
 internal/commands/completion/powershell.go | 71 ++++++++++++++++++++++++++++++
 5 files changed, 202 insertions(+)

diff --git a/README.md b/README.md
index 7db37e3..7b0efac 100644
--- a/README.md
+++ b/README.md
@@ -49,6 +49,40 @@ Then copy the 
`./bin/swctl-latest-(darwin|linux|windows)-amd64` to your `PATH` d
 
 You can also copy it to any directory you like, then add that directory to 
`PATH`. **We recommend you to rename the 
`swctl-latest-(darwin|linux|windows)-amd64` to `swctl`.**
 
+## Autocompletion
+
+`swctl` provides auto-completion support for bash and powershell, which can 
save you a lot of typing.
+
+### Bash
+
+The swctl completion script for bash can be generated with the command `swctl 
completion bash`. Sourcing the completion script in your shell enables swctl 
auto-completion:
+
+```shell
+swctl completion bash > bash_autocomplete &&
+    sudo cp ./bash_autocomplete /etc/bash_completion.d/swctl &&
+    echo >> ~/.bashrc &&
+    echo "export PROG=swctl" >> ~/.bashrc
+```
+
+After reloading your shell, swctl auto-completion should be working.
+
+### powershell
+
+Similarly, run the following command in your powershell terminal to enable 
auto-completion:
+
+```shell 
+set-executionpolicy remotesigned -Scope CurrentUser
+swctl completion powershell >> $profile
+```
+
+If you get an error like `OpenError: (:) [Out-File], 
DirectoryNotFoundException`, then you need to run the following command to 
create `$profile` file:
+
+```shell
+New-Item -Type file -Force $profile
+```
+
+After reloading your shell, swctl auto-completion should be working.
+
 
 # Commands
 Commands in SkyWalking CLI are organized into two levels, in the form of 
`swctl --option <level1> --option <level2> --option`,
diff --git a/cmd/swctl/main.go b/cmd/swctl/main.go
index 9d5b262..2ca1733 100644
--- a/cmd/swctl/main.go
+++ b/cmd/swctl/main.go
@@ -21,6 +21,7 @@ import (
        "io/ioutil"
        "os"
 
+       "github.com/apache/skywalking-cli/internal/commands/completion"
        "github.com/apache/skywalking-cli/internal/commands/dashboard"
        "github.com/apache/skywalking-cli/internal/commands/dependency"
        "github.com/apache/skywalking-cli/internal/commands/endpoint"
@@ -125,6 +126,7 @@ func main() {
                event.Command,
                logs.Command,
                profile.Command,
+               completion.Command,
                dependency.Command,
        }
 
@@ -137,6 +139,12 @@ func main() {
        app.Flags = flags
        app.CommandNotFound = util.CommandNotFound
 
+       // Enable auto-completion.
+       app.EnableBashCompletion = true
+       cli.BashCompletionFlag = cli.BoolFlag{
+               Name:   "auto_complete",
+               Hidden: true,
+       }
        if err := app.Run(os.Args); err != nil {
                log.Fatalln(err)
        }
diff --git a/internal/commands/completion/bash.go 
b/internal/commands/completion/bash.go
new file mode 100644
index 0000000..aed8075
--- /dev/null
+++ b/internal/commands/completion/bash.go
@@ -0,0 +1,58 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you under
+// the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package completion
+
+import (
+       "fmt"
+
+       "github.com/urfave/cli"
+)
+
+var bashCommand = cli.Command{
+       Name:      "bash",
+       Aliases:   []string{"b"},
+       Usage:     "Output shell completion code for bash",
+       ArgsUsage: "[parameters...]",
+       Action: func(ctx *cli.Context) error {
+               fmt.Print(bashScript)
+               return nil
+       },
+}
+
+const bashScript = `
+: ${PROG:=$(basename ${BASH_SOURCE})}
+
+_cli_bash_autocomplete() {
+  if [[ "${COMP_WORDS[0]}" != "source" ]]; then
+    local cur opts base
+    COMPREPLY=()
+    cur="${COMP_WORDS[COMP_CWORD]}"
+    if [[ "$cur" == "-"* ]]; then
+      opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} ${cur} --auto_complete )
+    else
+      opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --auto_complete )
+    fi
+    COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
+    return 0
+  fi
+}
+
+complete -o bashdefault -o default -o nospace -F _cli_bash_autocomplete $PROG
+unset PROG
+
+`
diff --git a/internal/commands/completion/completion.go 
b/internal/commands/completion/completion.go
new file mode 100644
index 0000000..c5733e4
--- /dev/null
+++ b/internal/commands/completion/completion.go
@@ -0,0 +1,31 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you under
+// the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package completion
+
+import (
+       "github.com/urfave/cli"
+)
+
+var Command = cli.Command{
+       Name:  "completion",
+       Usage: "Output shell completion code for bash and powershell",
+       Subcommands: []cli.Command{
+               bashCommand,
+               powershellCommand,
+       },
+}
diff --git a/internal/commands/completion/powershell.go 
b/internal/commands/completion/powershell.go
new file mode 100644
index 0000000..1c08123
--- /dev/null
+++ b/internal/commands/completion/powershell.go
@@ -0,0 +1,71 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you under
+// the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package completion
+
+import (
+       "fmt"
+
+       "github.com/urfave/cli"
+)
+
+var powershellCommand = cli.Command{
+       Name:      "powershell",
+       Aliases:   []string{"p"},
+       Usage:     "Output shell completion code for powershell",
+       ArgsUsage: "[parameters...]",
+       Action: func(ctx *cli.Context) error {
+               fmt.Print(powershellScript)
+               return nil
+       },
+}
+
+const powershellScript = `
+Register-ArgumentCompleter -Native -CommandName swctl -ScriptBlock {
+       param($commandName, $commands, $cursorPosition)
+
+       $match = $($(complete $commands $cursorPosition) -split " ")
+       # Output matched commands one by one.
+       for($i=0; $i -lt ($match.Length-1); $i+=1){
+                 Write-Output $match[$i]
+       }
+}
+# Find all matching commands.
+function complete($commands, $cursorPosition){
+       # Get command line parameters.
+       $parameters = $($commands -split " ")
+       # Uncompleted parameters.
+       $uncomplete = $parameters[-1]
+
+       # Get the parameters before $uncomplete.
+       $len = $parameters.Length-2
+       if ("$commands".Length -ne $cursorPosition) { return "" }
+       $beforeCommands = $parameters[0..($len)]
+
+       # Find the command prefixed with $uncomplete.
+       $match = ""
+       Invoke-Expression "$beforeCommands --auto_complete" | ForEach-Object {
+                 $flag = 1
+                 for ($i=0; $i -lt $uncomplete.Length; $i = $i +1){
+                               if ($_[$i] -ne $uncomplete[$i]) { $flag = 0 }
+                 }
+                 if ($flag -eq 1) {  $match+="$_ " }
+       }
+       return $match
+}
+
+`

Reply via email to