From 9410fc7c038f192c320c35f8325c34840a05cb3d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Erik=20Hedenstr=C3=B6m?= <erik@hedenstroem.com>
Date: Fri, 29 Sep 2023 18:02:15 +0000
Subject: [PATCH] feat: Update CI/CD, dependency versions, and command
 structure

- Remove unnecessary stages and scripts related to building and uploading to S3 in `.gitlab-ci.yml`
- Update Golang version to 1.21 in `.gitlab-ci.yml`
- Exclude `README.md` from secret detection in `.gitlab-ci.yml`
- Add constant import from `gitlab.hedenstroem.com/go/udm-query/constant` in `cmd/root.go`
- Remove `Execute` function in `cmd/root.go`
- Add `Version` field to `RootCmd` in `cmd/root.go`
- Add `DisableAutoGenTag` field to `RootCmd` and set it to `true` in `cmd/root.go`
- Remove `cmd/root.go` file from the root of the repository
- Added `.vscode/tasks.json` file containing tasks configuration in JSON format
- Tasks in `.vscode/tasks.json` include commands for installation, setting up zsh completion, and publishing a Fig spec
- Remove `github.com/hashicorp/consul/api` v1.12.0 dependency in `go.sum`
- Remove `github.com/sagikazarmark/crypt` v0.4.0 dependency in `go.sum`
- Add `github.com/withfig/autocomplete-tools/integrations/cobra` v1.2.1 dependency in `go.sum`
- Added a package registry link for all versions in `README.md`
- Added a new command "udm-query generate-fig-spec" in `docs/udm-query.md`
- Removed the command "udm-query version" in `docs/udm-query.md`
- Added `docs/udm-query_generate-fig-spec.md` file containing a command to generate a Fig spec for a Cobra CLI
- Updated Go version from 1.17 to 1.21 in `go.mod`
- Added new required module `github.com/withfig/autocomplete-tools/integrations/cobra@v1.2.1` in `go.mod`
- Added `cmd/generate_fig_spec.go` file with an `init` function and imported `cobracompletefig` package in `cmd/generate_fig_spec.go`
- Added a command to `RootCmd` in `cmd/generate_fig_spec.go`
- Updated `cmd.Execute()` to `cmd.RootCmd.Execute()` in `main.go`
- Ignore `main` and `udm-query` files in version control in `.gitignore`
- Exclude `.fig-spec.ts` file generated by vscode from version control in `.gitignore`
---
 .gitignore                          |  7 +++-
 .gitlab-ci.yml                      | 64 ++++-------------------------
 .vscode/tasks.json                  | 44 ++++++++++++++++++++
 README.md                           |  2 +
 cmd/generate_fig_spec.go            | 11 +++++
 cmd/root.go                         | 14 +++----
 cmd/version.go                      | 21 ----------
 docs/udm-query.md                   |  2 +-
 docs/udm-query_generate-fig-spec.md | 35 ++++++++++++++++
 go.mod                              |  3 +-
 go.sum                              |  6 +--
 main.go                             |  2 +-
 12 files changed, 117 insertions(+), 94 deletions(-)
 create mode 100644 .vscode/tasks.json
 create mode 100644 cmd/generate_fig_spec.go
 delete mode 100644 cmd/version.go
 create mode 100644 docs/udm-query_generate-fig-spec.md

diff --git a/.gitignore b/.gitignore
index f5da251..618c1e4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,11 +4,14 @@
 *.dll
 *.so
 *.dylib
+main
+udm-query
 
 # Test binary, build with `go test -c`
 *.test
 
 # Output of the go coverage tool, specifically when used with LiteIDE
 *.out
-main
-udm-query
+
+# Fig completion spec file generated by vscode task
+.fig-spec.ts
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 2b043df..eeeb073 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,55 +1,9 @@
-image: golang:1.17
-
-before_script:
-  - export GOPATH=${CI_PROJECT_DIR}/.cache
-
-stages:
-  - build
-  - upload
-
-.build: &build
-  stage: build
-  only:
-    - main
-    - /^\d+[.]\d+[.]\d+$/
-  cache:
-    key: build
-    paths:
-      - .cache
-  script:
-    - go generate constant/version.go
-    - CI_JOB_ARR=(${CI_JOB_NAME//-/ })
-    - GOOS=${CI_JOB_ARR[0]} GOARCH=${CI_JOB_ARR[1]} CGO_ENABLED=0 go build -tags netgo -ldflags '-s -w -extldflags "-static"' -o ${CI_PROJECT_NAME}-${CI_JOB_ARR[0]}-${CI_JOB_ARR[2]}
-  artifacts:
-    name: "$CI_PROJECT_NAME"
-    paths:
-      - $CI_PROJECT_NAME-*
-
-version.txt:
-  stage: build
-  only:
-    - /^\d+[.]\d+[.]\d+$/
-  script:
-    - git describe --tags --long --always > $CI_PROJECT_NAME-version.txt
-  artifacts:
-    name: "$CI_PROJECT_NAME-version"
-    paths:
-      - $CI_PROJECT_NAME-version.txt
-
-upload to s3:
-  image: amazon/aws-cli
-  stage: upload
-  only:
-    - /^\d+[.]\d+[.]\d+$/
-  script:
-    - aws s3 cp . s3://s3.hedenstroem.com/utils/$CI_PROJECT_NAME/ --recursive --exclude="*" --include="$CI_PROJECT_NAME-*"
-    - aws configure set preview.cloudfront true
-    - aws cloudfront create-invalidation --distribution-id $CLOUDFRONT_DISTRIBUTION_ID --paths "/utils/$CI_PROJECT_NAME/*"
-
-"darwin-arm64-arm64": *build
-"darwin-amd64-amd64": *build
-"linux-arm-arm": *build
-"linux-386-i386": *build
-"linux-amd64-amd64": *build
-"windows-386-i386.exe": *build
-"windows-amd64-x64.exe": *build
+variables:
+  GOLANG_VERSION: "1.21"
+  SECRET_DETECTION_EXCLUDED_PATHS: 'README.md'
+
+include:
+  - template: Security/SAST.gitlab-ci.yml
+  - template: Security/Secret-Detection.gitlab-ci.yml
+  - project: 'gitlab/templates'
+    file: 'Go-CLI.gitlab-ci.yml'
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644
index 0000000..2fed972
--- /dev/null
+++ b/.vscode/tasks.json
@@ -0,0 +1,44 @@
+{
+  // See https://go.microsoft.com/fwlink/?LinkId=733558
+  // for the documentation about the tasks.json format
+  "version": "2.0.0",
+  "tasks": [
+    {
+      "label": "Install locally",
+      "type": "shell",
+      "command": "go install",
+      "group": {
+        "kind": "build",
+        "isDefault": true
+      },
+      "presentation": {
+        "reveal": "silent"
+      }
+    },
+    {
+      "label": "Setup zsh completion",
+      "dependsOn": ["Install locally"],
+      "type": "shell",
+      "command": "mkdir -p $HOME/.zsh/completions && udm-query completion zsh > $HOME/.zsh/completions/_udm-query && rm -f $ZSH_COMPDUMP",
+      "group": {
+        "kind": "build",
+        "isDefault": false
+      },
+      "presentation": {
+        "reveal": "silent"
+      }
+    },
+    {
+      "label": "Publish fig spec",
+      "type": "shell",
+      "command": "go run main.go generate-fig-spec > .fig-spec.ts && npx --yes @fig/publish-spec -n udm-query -p .fig-spec.ts && rm -f .fig-spec.ts",
+      "group": {
+        "kind": "build",
+        "isDefault": false
+      },
+      "presentation": {
+        "reveal": "silent"
+      }
+    },
+  ]
+}
diff --git a/README.md b/README.md
index 4b80117..8ee87ba 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,8 @@ You can download one of the pre-compiled binaries from the list below.
 - [Windows (32-bit)](http://s3.hedenstroem.com/utils/udm-query/udm-query-windows-i386.exe)
 - [Windows (64-bit)](http://s3.hedenstroem.com/utils/udm-query/udm-query-windows-x64.exe)
 
+All versions are available via the [package registry](https://gitlab.hedenstroem.com/go/udm-query/-/packages).
+
 ## Configuration
 
 To avoid providing the password via a flag every time, you can define an environment variable named `SSH_PASSWORD` instead. The address to the UDM can also be set in the environment variable `SSH_ADDRESS`.
diff --git a/cmd/generate_fig_spec.go b/cmd/generate_fig_spec.go
new file mode 100644
index 0000000..9481d37
--- /dev/null
+++ b/cmd/generate_fig_spec.go
@@ -0,0 +1,11 @@
+package cmd
+
+import (
+	cobracompletefig "github.com/withfig/autocomplete-tools/integrations/cobra"
+)
+
+func init() {
+	cmd := cobracompletefig.CreateCompletionSpecCommand()
+	cmd.Hidden = false
+	RootCmd.AddCommand(cmd)
+}
diff --git a/cmd/root.go b/cmd/root.go
index 788bfb3..075da50 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -11,6 +11,7 @@ import (
 	"github.com/spf13/cobra"
 	"github.com/spf13/viper"
 	"github.com/thediveo/enumflag"
+	"gitlab.hedenstroem.com/go/udm-query/constant"
 	"gitlab.hedenstroem.com/go/udm-query/ssh"
 	"gitlab.hedenstroem.com/go/udm-query/utils"
 	"go.mongodb.org/mongo-driver/mongo"
@@ -29,8 +30,10 @@ var (
 )
 
 var RootCmd = &cobra.Command{
-	Use:   "udm-query",
-	Short: "Tool to query Ubiquiti UniFi Dream Machines",
+	Version:           constant.Version,
+	Use:               "udm-query",
+	Short:             "Tool to query Ubiquiti UniFi Dream Machines",
+	DisableAutoGenTag: true,
 	PersistentPreRunE: func(cmd *cobra.Command, args []string) (err error) {
 		tunnel := ssh.NewSSHTunnel(
 			viper.GetString("ADDRESS"),
@@ -49,13 +52,6 @@ var RootCmd = &cobra.Command{
 	PersistentPostRunE: func(cmd *cobra.Command, args []string) error {
 		return client.Disconnect(context.TODO())
 	},
-	DisableAutoGenTag: true,
-}
-
-func Execute() {
-	if err := RootCmd.Execute(); err != nil {
-		os.Exit(-1)
-	}
 }
 
 func init() {
diff --git a/cmd/version.go b/cmd/version.go
deleted file mode 100644
index 9401b05..0000000
--- a/cmd/version.go
+++ /dev/null
@@ -1,21 +0,0 @@
-package cmd
-
-import (
-	"fmt"
-
-	"github.com/spf13/cobra"
-	"gitlab.hedenstroem.com/go/udm-query/constant"
-)
-
-var versionCmd = &cobra.Command{
-	Use:   "version",
-	Short: "Display udm-query version",
-	Run: func(cmd *cobra.Command, args []string) {
-		fmt.Println(constant.Version)
-	},
-	DisableAutoGenTag: true,
-}
-
-func init() {
-	RootCmd.AddCommand(versionCmd)
-}
diff --git a/docs/udm-query.md b/docs/udm-query.md
index ee790b8..40670ec 100644
--- a/docs/udm-query.md
+++ b/docs/udm-query.md
@@ -17,7 +17,7 @@ Tool to query Ubiquiti UniFi Dream Machines
 * [udm-query completion](udm-query_completion.md)	 - Generate the autocompletion script for the specified shell
 * [udm-query devices](udm-query_devices.md)	 - Display UniFi devices
 * [udm-query dump](udm-query_dump.md)	 - Export collection to JSON or a table
+* [udm-query generate-fig-spec](udm-query_generate-fig-spec.md)	 - Generate a fig spec
 * [udm-query list](udm-query_list.md)	 - List databases and their collections
 * [udm-query ping](udm-query_ping.md)	 - Ping the database
-* [udm-query version](udm-query_version.md)	 - Display udm-query version
 
diff --git a/docs/udm-query_generate-fig-spec.md b/docs/udm-query_generate-fig-spec.md
new file mode 100644
index 0000000..19cf321
--- /dev/null
+++ b/docs/udm-query_generate-fig-spec.md
@@ -0,0 +1,35 @@
+## udm-query generate-fig-spec
+
+Generate a fig spec
+
+### Synopsis
+
+
+Fig is a tool for your command line that adds autocomplete.
+This command generates a TypeScript file with the skeleton
+Fig autocomplete spec for your Cobra CLI.
+
+
+```
+udm-query generate-fig-spec [flags]
+```
+
+### Options
+
+```
+  -h, --help             help for generate-fig-spec
+      --include-hidden   Include hidden commands in generated Fig autocomplete spec
+```
+
+### Options inherited from parent commands
+
+```
+  -a, --address string    Address to the UDM SSH server (default "192.168.1.1")
+      --debug             Show debug output
+  -p, --password string   SSH password
+```
+
+### SEE ALSO
+
+* [udm-query](udm-query.md)	 - Tool to query Ubiquiti UniFi Dream Machines
+
diff --git a/go.mod b/go.mod
index 6e21448..6e47fc0 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
 module gitlab.hedenstroem.com/go/udm-query
 
-go 1.17
+go 1.21
 
 require (
 	github.com/jedib0t/go-pretty/v6 v6.2.5
@@ -8,6 +8,7 @@ require (
 	github.com/spf13/cobra v1.3.0
 	github.com/spf13/viper v1.10.1
 	github.com/thediveo/enumflag v0.10.1
+	github.com/withfig/autocomplete-tools/integrations/cobra v1.2.1
 	go.mongodb.org/mongo-driver v1.8.3
 	golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
 )
diff --git a/go.sum b/go.sum
index 82767ad..337731f 100644
--- a/go.sum
+++ b/go.sum
@@ -213,7 +213,6 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf
 github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
 github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
 github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
-github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0=
 github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
 github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
 github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
@@ -362,7 +361,6 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
 github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig=
-github.com/sagikazarmark/crypt v0.4.0/go.mod h1:ALv2SRj7GxYV4HO9elxH9nS6M9gW+xDNxqmyJ6RfDFM=
 github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
 github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
@@ -408,6 +406,8 @@ github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhV
 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
 github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
 github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
+github.com/withfig/autocomplete-tools/integrations/cobra v1.2.1 h1:+dBg5k7nuTE38VVdoroRsT0Z88fmvdYrI2EjzJst35I=
+github.com/withfig/autocomplete-tools/integrations/cobra v1.2.1/go.mod h1:nmuySobZb4kFgFy6BptpXp/BBw+xFSyvVPP6auoJB4k=
 github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
 github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
 github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w=
@@ -745,7 +745,6 @@ google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdr
 google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU=
 google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=
 google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw=
-google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -844,7 +843,6 @@ google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD
 google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
 google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
 google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
-google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
diff --git a/main.go b/main.go
index 02c46d8..5c4258e 100644
--- a/main.go
+++ b/main.go
@@ -25,5 +25,5 @@ import (
 )
 
 func main() {
-	cmd.Execute()
+	cmd.RootCmd.Execute()
 }
-- 
GitLab