Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More powerful version cmd #1916

Merged
merged 13 commits into from
Jul 28, 2023
2 changes: 1 addition & 1 deletion .github/actions/save-logs/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ runs:
steps:
- name: Fix log permissions
run: |
stat -t /tmp/zarf-*.log >/dev/null 2>&1 && sudo chown $USER /tmp/zarf-*.log
sudo chown $USER /tmp/zarf-*.log || echo ""
shell: bash

- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
Expand Down
3 changes: 2 additions & 1 deletion docs/2-the-zarf-cli/100-cli-commands/zarf_version.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ zarf version [flags]
## Options

```
-h, --help help for version
-h, --help help for version
-o, --output string Output format (yaml|json)
```

## Options inherited from parent commands
Expand Down
64 changes: 62 additions & 2 deletions src/cmd/version.go
Noxsios marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,87 @@
package cmd

import (
"encoding/json"
"fmt"
"os"
"runtime"

"github.com/Masterminds/semver/v3"
"github.com/defenseunicorns/zarf/src/config"
"github.com/defenseunicorns/zarf/src/config/lang"
"github.com/spf13/cobra"

"runtime/debug"

goyaml "github.com/goccy/go-yaml"
)

var outputFormat string

var versionCmd = &cobra.Command{
Use: "version",
Aliases: []string{"v"},
PersistentPreRun: func(cmd *cobra.Command, args []string) {
config.SkipLogFile = true
cliSetup()
},
Short: lang.CmdVersionShort,
Long: lang.CmdVersionLong,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println(config.CLIVersion)
output := make(map[string]interface{})

buildInfo, ok := debug.ReadBuildInfo()
if !ok && outputFormat != "" {
fmt.Println("Failed to get build info")
return
}
depMap := map[string]string{}
for _, dep := range buildInfo.Deps {
if dep.Replace != nil {
depMap[dep.Path] = fmt.Sprintf("%s -> %s %s", dep.Version, dep.Replace.Path, dep.Replace.Version)
} else {
depMap[dep.Path] = dep.Version
}
}
output["dependencies"] = depMap

buildMap := make(map[string]interface{})
buildMap["platform"] = runtime.GOOS + "/" + runtime.GOARCH
buildMap["goVersion"] = runtime.Version()
ver, err := semver.NewVersion(config.CLIVersion)
if err != nil {
buildMap["minor"] = ""
buildMap["patch"] = ""
buildMap["prerelease"] = ""
} else {
buildMap["major"] = ver.Major()
buildMap["minor"] = ver.Minor()
buildMap["patch"] = ver.Patch()
buildMap["prerelease"] = ver.Prerelease()
}

output["version"] = config.CLIVersion

output["build"] = buildMap

switch outputFormat {
case "yaml":
text, _ := goyaml.Marshal(output)
fmt.Println(string(text))
case "json":
text, _ := json.Marshal(output)
fmt.Println(string(text))
default:
fmt.Println(config.CLIVersion)
}
},
}

func isVersionCmd() bool {
args := os.Args
return len(args) > 1 && (args[1] == "version" || args[1] == "v")
}

func init() {
versionCmd.Flags().StringVarP(&outputFormat, "output", "o", "", "Output format (yaml|json)")
rootCmd.AddCommand(versionCmd)
}
5 changes: 5 additions & 0 deletions src/cmd/viper.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ func initViper() {
return
}

// Skip for the version command
if isVersionCmd() {
return
}

// Specify an alternate config file
cfgFile := os.Getenv("ZARF_CONFIG")

Expand Down
21 changes: 17 additions & 4 deletions src/test/e2e/00_use_cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"os"
"path/filepath"
"runtime"
"strings"
"testing"

"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -50,10 +51,22 @@ func TestUseCLI(t *testing.T) {
t.Run("zarf version", func(t *testing.T) {
t.Parallel()
// Test `zarf version`
stdOut, _, err := e2e.Zarf("version")
version, _, err := e2e.Zarf("version")
require.NoError(t, err)
require.NotEqual(t, len(stdOut), 0, "Zarf version should not be an empty string")
require.NotEqual(t, stdOut, "UnknownVersion", "Zarf version should not be the default value")
require.NotEqual(t, len(version), 0, "Zarf version should not be an empty string")
version = strings.Trim(version, "\n")

// test `zarf version --output=json`
stdOut, _, err := e2e.Zarf("version", "--output=json")
require.NoError(t, err)
jsonVersion := fmt.Sprintf(",\"version\":\"%s\"}", version)
require.Contains(t, stdOut, jsonVersion, "Zarf version should be the same in all formats")

// test `zarf version --output=yaml`
stdOut, _, err = e2e.Zarf("version", "--output=yaml")
require.NoError(t, err)
yamlVersion := fmt.Sprintf("version: %s", version)
require.Contains(t, stdOut, yamlVersion, "Zarf version should be the same in all formats")
})

t.Run("zarf prepare find-images", func(t *testing.T) {
Expand Down Expand Up @@ -91,7 +104,7 @@ func TestUseCLI(t *testing.T) {
t.Run("changing log level", func(t *testing.T) {
t.Parallel()
// Test that changing the log level actually applies the requested level
_, stdErr, _ := e2e.Zarf("version", "--log-level=debug")
_, stdErr, _ := e2e.Zarf("internal", "crc32", "zarf", "--log-level=debug")
expectedOutString := "Log level set to debug"
require.Contains(t, stdErr, expectedOutString, "The log level should be changed to 'debug'")
})
Expand Down