SEBA-580 Add bash completion;
Add Git Dirty to version;
Add config comamnd
Change-Id: I847dc309a41d74d80e427106bcc839b8db3f9a2c
diff --git a/Makefile b/Makefile
index 297c16b..c7ca017 100644
--- a/Makefile
+++ b/Makefile
@@ -4,6 +4,11 @@
VERSION=$(shell cat $(GOPATH)/src/github.com/opencord/cordctl/VERSION)
GITCOMMIT=$(shell git log --pretty=format:"%h" -n 1)
+ifeq ($(shell git ls-files --others --modified --exclude-standard 2>/dev/null | wc -l | sed -e 's/ //g'),0)
+GITDIRTY=false
+else
+GITDIRTY=true
+endif
GOVERSION=$(shell go version 2>&1 | sed -E 's/.*(go[0-9]+\.[0-9]+\.[0-9]+).*/\1/g')
OSTYPE=$(shell uname -s | tr A-Z a-z)
OSARCH=$(shell uname -p | tr A-Z a-z)
@@ -12,10 +17,11 @@
LDFLAGS=-ldflags \
'-X "github.com/opencord/cordctl/cli/version.Version=$(VERSION)" \
-X "github.com/opencord/cordctl/cli/version.GitCommit=$(GITCOMMIT)" \
+ -X "github.com/opencord/cordctl/cli/version.GitDirty=$(GITDIRTY)" \
-X "github.com/opencord/cordctl/cli/version.GoVersion=$(GOVERSION)" \
-X "github.com/opencord/cordctl/cli/version.Os=$(OSTYPE)" \
-X "github.com/opencord/cordctl/cli/version.Arch=$(OSARCH)" \
- -X "github.com/opencord/cordctl/cli/version.BuildTime=$(BUILDTIME)"' \
+ -X "github.com/opencord/cordctl/cli/version.BuildTime=$(BUILDTIME)"'
help:
diff --git a/README.md b/README.md
index 346a244..22361e6 100644
--- a/README.md
+++ b/README.md
@@ -32,6 +32,26 @@
./cordctl model list -h
```
+## Shell Completion
+`cordctl` supports shell completion for the `bash` shell. To enable
+shell Completion you can use the following command on *most* \*nix based system.
+```bash
+source <(cordctl completion bash)
+```
+
+If this does not work on your system, as is the case with the standard
+bash shell on MacOS, then you can try the following command:
+```bash
+source /dev/stdin <<<"$(cordctl completion bash)"
+```
+
+If you which to make `bash` shell completion automatic when you login to
+your account you can append the output of `cordctl completion bash` to
+your `$HOME/.bashrc`:
+```bash
+cordctl completion bash >> $HOME/.bashrc
+```
+
## Development Environment
To run unit tests, `go-junit-report` and `gocover-obertura` tools must be installed. One way to do this is to install them with `go get`, and then ensure your `GOPATH` is part of your `PATH` (editing your `~/.profile` as necessary).
diff --git a/cli/version/version.go b/cli/version/version.go
index dcae592..21880bb 100644
--- a/cli/version/version.go
+++ b/cli/version/version.go
@@ -22,7 +22,8 @@
var (
Version = "unknown-version"
GoVersion = "unknown-goversion"
- GitCommit = "unknown-commit"
+ GitCommit = "unknown-gitcommit"
+ GitDirty = "unknown-gitdirty"
BuildTime = "unknown-buildtime"
Os = "unknown-os"
Arch = "unknown-arch"
diff --git a/cmd/cordctl.go b/cmd/cordctl.go
index b4e3c0d..53daf9b 100644
--- a/cmd/cordctl.go
+++ b/cmd/cordctl.go
@@ -35,6 +35,8 @@
commands.RegisterServiceCommands(parser)
commands.RegisterTransferCommands(parser)
commands.RegisterVersionCommands(parser)
+ commands.RegisterCompletionCommands(parser)
+ commands.RegisterConfigCommands(parser)
_, err = parser.ParseArgs(os.Args[1:])
if err != nil {
diff --git a/commands/command.go b/commands/command.go
index 9741e51..6a8d663 100644
--- a/commands/command.go
+++ b/commands/command.go
@@ -111,16 +111,12 @@
Server string `yaml:"server"`
}
-func NewConnection() (*grpc.ClientConn, error) {
+func ProcessGlobalOptions() {
if len(GlobalOptions.Config) == 0 {
- home := os.Getenv("HOME")
- // TODO: Replace after Jenkins updated to go 1.12
- /*
- home, err := os.UserHomeDir()
- if err != nil {
- log.Printf("Unable to discover they users home directory: %s\n", err)
- }
- */
+ home, err := os.UserHomeDir()
+ if err != nil {
+ log.Printf("Unable to discover the users home directory: %s\n", err)
+ }
GlobalOptions.Config = fmt.Sprintf("%s/.cord/config", home)
}
@@ -147,6 +143,19 @@
GlobalConfig.Password = GlobalOptions.Password
}
+ if GlobalConfig.Server == "" {
+ log.Fatal("Server is not set. Please update config file or use the -s option")
+ }
+ if GlobalConfig.Username == "" {
+ log.Fatal("Username is not set. Please update config file or use the -u option")
+ }
+ if GlobalConfig.Password == "" {
+ log.Fatal("Password is not set. Please update config file or use the -p option")
+ }
+}
+
+func NewConnection() (*grpc.ClientConn, error) {
+ ProcessGlobalOptions()
return grpc.Dial(GlobalConfig.Server, grpc.WithInsecure())
}
diff --git a/commands/completion.go b/commands/completion.go
new file mode 100644
index 0000000..67c7ad3
--- /dev/null
+++ b/commands/completion.go
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2019-present Ciena Corporation
+ *
+ * Licensed 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 commands
+
+import (
+ "fmt"
+ flags "github.com/jessevdk/go-flags"
+ "github.com/opencord/cordctl/completion"
+)
+
+type BashOptions struct{}
+
+type CompletionOptions struct {
+ BashOptions `command:"bash"`
+}
+
+func RegisterCompletionCommands(parent *flags.Parser) {
+ parent.AddCommand("completion", "generate shell compleition", "Commands to generate shell completion information", &CompletionOptions{})
+}
+
+func (options *BashOptions) Execute(args []string) error {
+ fmt.Println(completion.Bash)
+ return nil
+}
diff --git a/commands/config.go b/commands/config.go
new file mode 100644
index 0000000..81875a5
--- /dev/null
+++ b/commands/config.go
@@ -0,0 +1,60 @@
+/*
+ * Portions copyright 2019-present Open Networking Foundation
+ * Original copyright 2019-present Ciena Corporation
+ *
+ * Licensed 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 commands
+
+import (
+ "fmt"
+ flags "github.com/jessevdk/go-flags"
+ "gopkg.in/yaml.v2"
+)
+
+const copyrightNotice = `
+# Portions copyright 2019-present Open Networking Foundation
+# Original copyright 2019-present Ciena Corporation
+#
+# Licensed 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.
+#
+`
+
+type ConfigOptions struct {
+}
+
+func RegisterConfigCommands(parent *flags.Parser) {
+ parent.AddCommand("config", "generate cordctl configuration", "Commands to generate cordctl configuration", &ConfigOptions{})
+}
+
+func (options *ConfigOptions) Execute(args []string) error {
+ //GlobalConfig
+ ProcessGlobalOptions()
+ b, err := yaml.Marshal(GlobalConfig)
+ if err != nil {
+ return err
+ }
+ fmt.Println(copyrightNotice)
+ fmt.Println(string(b))
+ return nil
+}
diff --git a/commands/models.go b/commands/models.go
index 92a7b2c..f7a1963 100644
--- a/commands/models.go
+++ b/commands/models.go
@@ -31,13 +31,15 @@
DEFAULT_MODEL_AVAILABLE_FORMAT = "{{ . }}"
)
+type ModelNameString string
+
type ModelList struct {
OutputOptions
ShowHidden bool `long:"showhidden" description:"Show hidden fields in default output"`
ShowFeedback bool `long:"showfeedback" description:"Show feedback fields in default output"`
ShowBookkeeping bool `long:"showbookkeeping" description:"Show bookkeeping fields in default output"`
Args struct {
- ModelName string
+ ModelName ModelNameString
} `positional-args:"yes" required:"yes"`
}
@@ -100,12 +102,12 @@
defer conn.Close()
- err = CheckModelName(descriptor, options.Args.ModelName)
+ err = CheckModelName(descriptor, string(options.Args.ModelName))
if err != nil {
return err
}
- method := "xos.xos/List" + options.Args.ModelName
+ method := "xos.xos/List" + string(options.Args.ModelName)
ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
defer cancel()
@@ -195,3 +197,26 @@
GenerateOutput(&result)
return nil
}
+
+func (modelName *ModelNameString) Complete(match string) []flags.Completion {
+ conn, descriptor, err := InitReflectionClient()
+ if err != nil {
+ return nil
+ }
+
+ defer conn.Close()
+
+ models, err := GetModelNames(descriptor)
+ if err != nil {
+ return nil
+ }
+
+ list := make([]flags.Completion, 0)
+ for k := range models {
+ if strings.HasPrefix(k, match) {
+ list = append(list, flags.Completion{Item: k})
+ }
+ }
+
+ return list
+}
diff --git a/commands/version.go b/commands/version.go
index 9cc8b05..4af5a8a 100644
--- a/commands/version.go
+++ b/commands/version.go
@@ -29,6 +29,7 @@
Version string `json:"version"`
GoVersion string `json:"goversion"`
GitCommit string `json:"gitcommit"`
+ GitDirty string `json:"gitdirty"`
BuildTime string `json:"buildtime"`
Os string `json:"os"`
Arch string `json:"arch"`
@@ -59,6 +60,7 @@
Version: version.Version,
GoVersion: version.GoVersion,
GitCommit: version.GitCommit,
+ GitDirty: version.GitDirty,
Os: version.Os,
Arch: version.Arch,
BuildTime: version.BuildTime,
@@ -81,6 +83,7 @@
Version {{.Client.Version}}
Go version: {{.Client.GoVersion}}
Git commit: {{.Client.GitCommit}}
+ Git dirty: {{.Client.GitDirty}}
Built: {{.Client.BuildTime}}
OS/Arch: {{.Client.Os}}/{{.Client.Arch}}
diff --git a/completion/bash.go b/completion/bash.go
new file mode 100644
index 0000000..4feb2a2
--- /dev/null
+++ b/completion/bash.go
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2019-present Ciena Corporation
+ *
+ * Licensed 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
+
+const Bash = `
+# Portions copyright 2019-present Open Networking Foundation
+# Original copyright 2019-present Ciena Corporation
+#
+# Licensed 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.
+#
+_cordctl() {
+ # All arguments except the first one
+ args=("${COMP_WORDS[@]:1:$COMP_CWORD}")
+ # Only split on newlines
+ local IFS=$'\n'
+ # Call completion (note that the first element of COMP_WORDS is
+ # the executable itself)
+ COMPREPLY=($(GO_FLAGS_COMPLETION=1 ${COMP_WORDS[0]} "${args[@]}"))
+ return 0
+}
+complete -F _cordctl cordctl
+`