Skip to content

Commit

Permalink
✨ root command testing, i18n
Browse files Browse the repository at this point in the history
  • Loading branch information
acidjazz committed Mar 29, 2024
1 parent 7582933 commit 782277b
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 34 deletions.
3 changes: 2 additions & 1 deletion pkg/cmd/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import (
"github.com/vulncheck-oss/cli/pkg/cmd/auth/login"
"github.com/vulncheck-oss/cli/pkg/cmd/auth/logout"
"github.com/vulncheck-oss/cli/pkg/cmd/auth/status"
"github.com/vulncheck-oss/cli/pkg/i18n"
"github.com/vulncheck-oss/cli/pkg/session"
)

func Command() *cobra.Command {
cmd := &cobra.Command{
Use: "auth <command>",
Short: "Authenticate vc with the VulnCheck portal",
Short: i18n.C.AuthShort,
GroupID: "core",
}

Expand Down
15 changes: 8 additions & 7 deletions pkg/cmd/backup/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"github.com/spf13/cobra"
"github.com/vulncheck-oss/cli/pkg/config"
"github.com/vulncheck-oss/cli/pkg/i18n"
"github.com/vulncheck-oss/cli/pkg/session"
"github.com/vulncheck-oss/cli/pkg/ui"
"net/url"
Expand All @@ -15,12 +16,12 @@ func Command() *cobra.Command {

cmd := &cobra.Command{
Use: "backup <command>",
Short: "Download a backup of a specified index",
Short: i18n.C.BackupShort,
}

cmdUrl := &cobra.Command{
Use: "url <index>",
Short: "Get the temporary signed URL of the backup of an index",
Short: i18n.C.BackupUrlShort,
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
return ui.Error("index name is required")
Expand All @@ -36,10 +37,10 @@ func Command() *cobra.Command {

cmdDownload := &cobra.Command{
Use: "download <index>",
Short: "Download the backup of an index",
Short: i18n.C.BackupDownloadShort,
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
return ui.Error("index name is required")
return ui.Error(i18n.C.ErrorIndexRequired)
}
response, err := session.Connect(config.Token()).GetIndexBackup(args[0])
if err != nil {
Expand All @@ -50,12 +51,12 @@ func Command() *cobra.Command {

date := parseDate(response.GetData()[0].DateAdded)

ui.Info(fmt.Sprintf("Backup of %s found, created on %s", args[0], date))
ui.Info(fmt.Sprintf("Downloading backup as %s ", file))
ui.Info(fmt.Sprintf(i18n.C.BackupDownloadInfo, args[0], date))
ui.Info(fmt.Sprintf(i18n.C.BackupDownloadProgress, file))
if err := ui.Download(response.GetData()[0].URL, file); err != nil {
return err
}
ui.Success("Backup downloaded successfully")
ui.Success(i18n.C.BackupDownloadComplete)
return nil
},
}
Expand Down
11 changes: 6 additions & 5 deletions pkg/cmd/index/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package index
import (
"github.com/spf13/cobra"
"github.com/vulncheck-oss/cli/pkg/config"
"github.com/vulncheck-oss/cli/pkg/i18n"
"github.com/vulncheck-oss/cli/pkg/session"
"github.com/vulncheck-oss/cli/pkg/ui"
)
Expand All @@ -11,15 +12,15 @@ func Command() *cobra.Command {

cmd := &cobra.Command{
Use: "index <command>",
Short: "Browse or list an index",
Short: i18n.C.IndexShort,
}

cmdList := &cobra.Command{
Use: "list <index>",
Short: "List documents of a specified index",
Short: i18n.C.IndexListShort,
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
return ui.Error("index name is required")
return ui.Error(i18n.C.ErrorIndexRequired)
}
response, err := session.Connect(config.Token()).GetIndex(args[0])
if err != nil {
Expand All @@ -32,10 +33,10 @@ func Command() *cobra.Command {

cmdBrowse := &cobra.Command{
Use: "browse <index>",
Short: "Browse documents of an index interactively",
Short: i18n.C.IndexBrowseShort,
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
return ui.Error("index name is required")
return ui.Error(i18n.C.ErrorIndexRequired)
}
response, err := session.Connect(config.Token()).GetIndex(args[0])
if err != nil {
Expand Down
15 changes: 8 additions & 7 deletions pkg/cmd/indices/indices.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import (
"fmt"
"github.com/spf13/cobra"
"github.com/vulncheck-oss/cli/pkg/config"
"github.com/vulncheck-oss/cli/pkg/i18n"
"github.com/vulncheck-oss/cli/pkg/session"
"github.com/vulncheck-oss/cli/pkg/ui"
)

func Command() *cobra.Command {
cmd := &cobra.Command{
Use: "indices <command>",
Short: "Manage indices",
Short: i18n.C.IndicesShort,
}

cmd.AddCommand(List())
Expand All @@ -32,18 +33,18 @@ func List() *cobra.Command {

cmd := &cobra.Command{
Use: "list <search>",
Short: "List indices",
Short: i18n.C.ListIndicesShort,
RunE: func(cmd *cobra.Command, args []string) error {
response, err := session.Connect(config.Token()).GetIndices()
if err != nil {
return err
}
if len(args) > 0 && args[0] != "" {
indices := response.GetData()
ui.Info(fmt.Sprintf("Listing %d indices searching for \"%s\"", len(ui.IndicesRows(indices, args[0])), args[0]))
ui.Info(fmt.Sprintf(i18n.C.ListIndicesSearch, len(ui.IndicesRows(indices, args[0])), args[0]))
return ui.IndicesList(indices, args[0])
}
ui.Info(fmt.Sprintf("Listing %d indices", len(response.GetData())))
ui.Info(fmt.Sprintf(i18n.C.ListIndicesFull, len(response.GetData())))
if opts.Json {
ui.Json(response.GetData())
return nil
Expand All @@ -63,7 +64,7 @@ func Browse() *cobra.Command {

return &cobra.Command{
Use: "browse <search>",
Short: "Browse indices",
Short: i18n.C.BrowseIndicesShort,
RunE: func(cmd *cobra.Command, args []string) error {

action := func(index string) error {
Expand All @@ -81,11 +82,11 @@ func Browse() *cobra.Command {
}
if len(args) > 0 && args[0] != "" {
indices := response.GetData()
ui.Info(fmt.Sprintf("Browsing %d indices searching for \"%s\"", len(ui.IndicesRows(indices, args[0])), args[0]))
ui.Info(fmt.Sprintf(i18n.C.BrowseIndicesSearch, len(ui.IndicesRows(indices, args[0])), args[0]))
return ui.IndicesBrowse(indices, args[0], action)
}

ui.Info(fmt.Sprintf("Browsing %d indices", len(response.GetData())))
ui.Info(fmt.Sprintf(i18n.C.BrowseIndicesFull, len(response.GetData())))
return ui.IndicesBrowse(response.GetData(), "", action)
},
}
Expand Down
18 changes: 5 additions & 13 deletions pkg/cmd/root/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"fmt"
"github.com/MakeNowJust/heredoc/v2"
"github.com/spf13/cobra"
"github.com/vulncheck-oss/cli/pkg/build"
"github.com/vulncheck-oss/cli/pkg/cmd/about"
"github.com/vulncheck-oss/cli/pkg/cmd/auth"
"github.com/vulncheck-oss/cli/pkg/cmd/backup"
Expand All @@ -17,6 +16,7 @@ import (
"github.com/vulncheck-oss/cli/pkg/cmd/version"
"github.com/vulncheck-oss/cli/pkg/config"
"github.com/vulncheck-oss/cli/pkg/environment"
"github.com/vulncheck-oss/cli/pkg/i18n"
"github.com/vulncheck-oss/cli/pkg/session"
"github.com/vulncheck-oss/cli/pkg/ui"
"github.com/vulncheck-oss/sdk"
Expand Down Expand Up @@ -44,29 +44,21 @@ func NewCmdRoot() *cobra.Command {
cmd := &cobra.Command{
Use: "vc <command> <subcommand> [flags]",
Short: "VulnCheck CLI.",
Long: "Work seamlessly with the VulnCheck API.",
Long: i18n.C.RootLong,
Example: heredoc.Doc(`
$ vc indices list
$ vc index abb
$ vc backup abb
`),
Annotations: map[string]string{
"versionInfo": session.VersionFormat(build.Version, build.Date),
"aboutInfo": heredoc.Doc(`
The VulnCheck CLI is a command-line interface for the VulnCheck API
For more information on our products, please visit https://vulncheck.com
For API Documentation, please visit https://docs.vulncheck.com
`),
"InteractiveOnly": "This command is interactive and cannot run in a CI environment, please try %s instead",
},
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {

environment.Init()
config.Init()
i18n.Init()

if session.IsAuthCheckEnabled(cmd) && !session.CheckAuth() {
fmt.Println(authHelp())
return ui.Error("No valid token found")
return ui.Error(i18n.C.ErrorNoToken)
}

return nil
Expand Down Expand Up @@ -99,7 +91,7 @@ func NewCmdRoot() *cobra.Command {
func Execute() {
if err := NewCmdRoot().Execute(); err != nil {
if errors.Is(err, sdk.ErrorUnauthorized) {
fmt.Println(ui.Danger("Error: Unauthorized, Try authenticating with: vc auth login"))
fmt.Println(ui.Danger(i18n.C.ErrorUnauthorized))
} else {
fmt.Println(ui.Danger(err.Error()))
}
Expand Down
66 changes: 66 additions & 0 deletions pkg/cmd/root/root_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package root

import (
"bytes"
"github.com/spf13/cobra"
"github.com/vulncheck-oss/cli/pkg/i18n"
"strings"
"testing"
)

func Test_AuthCommand(t *testing.T) {
actual, root := setRootActual("auth")
root.SetArgs([]string{"auth"})
if err := root.Execute(); err != nil {
t.Errorf("expected no error but got %v", err)
}
if strings.HasPrefix(i18n.C.AuthShort, actual.String()) {
t.Errorf("expected %s but got %s", i18n.C.AuthShort, actual.String())
}
}

func Test_IndicesCommand(t *testing.T) {
actual, root := setRootActual("indices")
root.SetArgs([]string{"indices"})
if err := root.Execute(); err != nil {
t.Errorf("expected no error but got %v", err)
}
if strings.HasPrefix(i18n.C.IndicesShort, actual.String()) {
t.Errorf("expected %s but got %s", i18n.C.IndicesShort, actual.String())
}
}

func Test_IndexCommand(t *testing.T) {
actual, root := setRootActual("index")
root.SetArgs([]string{"index"})
if err := root.Execute(); err != nil {
t.Errorf("expected no error but got %v", err)
}
if strings.HasPrefix(i18n.C.IndexShort, actual.String()) {
t.Errorf("expected %s but got %s", i18n.C.IndexShort, actual.String())
}
}

func Test_BackupCommand(t *testing.T) {
actual, root := setRootActual("backup")
root.SetArgs([]string{"backup"})
if err := root.Execute(); err != nil {
t.Errorf("expected no error but got %v", err)
}
if strings.HasPrefix(i18n.C.BackupShort, actual.String()) {
t.Errorf("expected %s but got %s", i18n.C.BackupShort, actual.String())
}
}

func setRootActual(args ...string) (*bytes.Buffer, *cobra.Command) {
actual := new(bytes.Buffer)
root := NewCmdRoot()
root.SetOut(actual)
root.SetErr(actual)
var argsArray []string
for _, arg := range args {
argsArray = append(argsArray, arg)
}
root.SetArgs(argsArray)
return actual, root
}
3 changes: 2 additions & 1 deletion pkg/cmd/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package version
import (
"fmt"
"github.com/spf13/cobra"
"github.com/vulncheck-oss/cli/pkg/build"
"github.com/vulncheck-oss/cli/pkg/session"
)

Expand All @@ -11,7 +12,7 @@ func Command() *cobra.Command {
Use: "version",
Short: "Show the current version, build date, and changelog URL",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println(cmd.Root().Annotations["versionInfo"])
fmt.Println(session.VersionFormat(build.Version, build.Date))
},
}
session.DisableAuthCheck(cmd)
Expand Down
86 changes: 86 additions & 0 deletions pkg/i18n/i18n.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package i18n

import (
"github.com/MakeNowJust/heredoc/v2"
)

var lang = "en_US"

type Copy struct {
AboutInfo string
InteractiveOnly string
RootLong string

AuthShort string
IndicesShort string

ListIndicesShort string
ListIndicesSearch string
ListIndicesFull string

BrowseIndicesShort string
BrowseIndicesSearch string
BrowseIndicesFull string

IndexShort string
IndexListShort string
IndexBrowseShort string

BackupShort string
BackupUrlShort string
BackupDownloadShort string
BackupDownloadInfo string
BackupDownloadProgress string
BackupDownloadComplete string

ErrorNoToken string
ErrorUnauthorized string

ErrorIndexRequired string
}

var C Copy

func Init() {
C = En
// TODO: after a 2nd language is added, detect the system language and set the lang variable accordingly
// look at the LANG environment variable
// bonus: missing keys of the 2nd language fallback to En
}

var En = Copy{
AboutInfo: heredoc.Doc(`
The VulnCheck CLI is a command-line interface for the VulnCheck API
For more information on our products, please visit https://vulncheck.com
For API Documentation, please visit https://docs.vulncheck.com
`),
InteractiveOnly: "This command is interactive and cannot run in a CI environment, please try %s instead",
RootLong: "Work seamlessly with the VulnCheck API.",

AuthShort: "Authenticate vc with the VulnCheck portal",
IndicesShort: "View indices",

ListIndicesShort: "List indices",
ListIndicesSearch: "Listing %d indices searching for \"%s\"",
ListIndicesFull: "Listing %d indices",

BrowseIndicesShort: "Browse indices",
BrowseIndicesSearch: "Listing %d indices searching for \"%s\"",
BrowseIndicesFull: "Listing %d indices",

IndexShort: "Browse or list an index",
IndexListShort: "List documents of a specified index",
IndexBrowseShort: "Browse documents of an index interactively",

BackupShort: "Download a backup of a specified index",
BackupUrlShort: "Get the temporary signed URL of the backup of an index",
BackupDownloadShort: "Download the backup of an index",

BackupDownloadInfo: "Downloading backup of %s, created on %s",
BackupDownloadProgress: "Downloading backup as %s",
BackupDownloadComplete: "Backup downloaded successfully",

ErrorNoToken: "No valid token found",
ErrorUnauthorized: "Error: Unauthorized, Try authenticating with: vc auth login",
ErrorIndexRequired: "index name is required",
}

0 comments on commit 782277b

Please sign in to comment.