Skip to content

Commit

Permalink
feat: Add the --format option to the finch version command
Browse files Browse the repository at this point in the history
Currently, the `finch version` command does not support the `--format`
option.

However, a feature request has been submitted in the following issue to
add the `--format` option to the `finch version` command.

  - #199

Therefore, this fix introduces the `--format` option to the
`finch version` command.

Signed-off-by: Hayato Kiwata <[email protected]>
  • Loading branch information
haytok committed May 8, 2024
1 parent 5f51ce4 commit 3456abe
Show file tree
Hide file tree
Showing 6 changed files with 413 additions and 79 deletions.
134 changes: 107 additions & 27 deletions cmd/finch/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,48 @@
package main

import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"text/template"

"github.com/spf13/cobra"

"github.com/runfinch/finch/pkg/command"
"github.com/runfinch/finch/pkg/flog"
"github.com/runfinch/finch/pkg/lima"
"github.com/runfinch/finch/pkg/templates"
"github.com/runfinch/finch/pkg/version"
)

const defaultVersionTemplate = `{{with .Client -}}
Client:
Version: {{.Version}}
GitCommit: {{.GitCommit}}
{{with .NerdctlClient -}}
OS/Arch: {{.Os}}/{{.Arch}}
nerdctl:
Version: {{.Version}}
GitCommit: {{.GitCommit}}
{{- range $component := .Components}}
{{$component.Name}}:
Version: {{.Version}}
GitCommit: {{.Details.GitCommit}}
{{- end}}
{{- end}}
{{- end}}
{{with .Server -}}
Server:
{{- range $component := .Components}}
{{$component.Name}}:
Version: {{.Version}}
GitCommit: {{.Details.GitCommit}}
{{- end}}
{{- end}}`

func newVersionCommand(limaCmdCreator command.LimaCmdCreator, logger flog.Logger, stdOut io.Writer) *cobra.Command {
versionCommand := &cobra.Command{
Use: "version",
Expand All @@ -25,6 +54,8 @@ func newVersionCommand(limaCmdCreator command.LimaCmdCreator, logger flog.Logger
RunE: newVersionAction(limaCmdCreator, logger, stdOut).runAdapter,
}

versionCommand.Flags().StringP("format", "f", "", "Format the output using the given Go template, e.g, '{{json .}}'")

return versionCommand
}

Expand All @@ -40,6 +71,19 @@ type NerdctlVersionOutput struct {
Server NerdctlServerOutput `json:"Server"`
}

// FinchVersionOutput captures the finch version.
type FinchVersionOutput struct {
Client ClientVersionOutput `json:"Client"`
Server NerdctlServerOutput `json:"Server"`
}

// ClientVersionOutput captures the commit ID for finch and the nerdctl Client output.
type ClientVersionOutput struct {
Version string `json:"Version"`
GitCommit string `json:"GitCommit"`
NerdctlClient NerdctlClientOutput `json:"NerdctlClient"`
}

// NerdctlClientOutput captures the nerdctl Client output.
type NerdctlClientOutput struct {
Version string `json:"Version"`
Expand All @@ -50,11 +94,6 @@ type NerdctlClientOutput struct {
Components []NerdctlComponentsOutput `json:"Components"`
}

// NerdctlServerOutput captures the nerdctl Server output.
type NerdctlServerOutput struct {
Components []NerdctlComponentsOutput `json:"Components"`
}

// NerdctlComponentsOutput captures the nerdctl components output.
type NerdctlComponentsOutput struct {
Name string `json:"Name"`
Expand All @@ -64,23 +103,75 @@ type NerdctlComponentsOutput struct {
}
}

// NerdctlServerOutput captures the nerdctl Server output.
type NerdctlServerOutput struct {
Components []NerdctlComponentsOutput `json:"Components"`
}

func newVersionAction(creator command.LimaCmdCreator, logger flog.Logger, stdOut io.Writer) *versionAction {
return &versionAction{creator: creator, logger: logger, stdOut: stdOut}
}

func (va *versionAction) runAdapter(_ *cobra.Command, _ []string) error {
return va.run()
func (va *versionAction) runAdapter(cmd *cobra.Command, _ []string) error {
format, err := cmd.Flags().GetString("format")
if err != nil {
return err
}

return va.run(format)
}

func (va *versionAction) run() error {
if err := va.printVersion(); err != nil {
func (va *versionAction) run(format string) error {
if err := va.printVersion(format); err != nil {
fmt.Fprintf(va.stdOut, "Finch version:\t%s\n", version.Version)
return err
}
return nil
}

func (va *versionAction) printVersion() error {
func newVersionTemplate(templateFormat string) (*template.Template, error) {
switch templateFormat {
case "":
templateFormat = defaultVersionTemplate
case templates.JSONFormatKey:
templateFormat = templates.JSONFormat
}

tmpl := templates.New("version")
tmpl, err := tmpl.Parse(templateFormat)
if err != nil {
return nil, err
}

return tmpl, nil
}

func createFinchVersionOutput(nerdctlVersion NerdctlVersionOutput) FinchVersionOutput {
var finchVersionOutput FinchVersionOutput

finchVersionOutput.Client.Version = version.Version
finchVersionOutput.Client.GitCommit = version.GitCommit
finchVersionOutput.Client.NerdctlClient = nerdctlVersion.Client
finchVersionOutput.Server = nerdctlVersion.Server

return finchVersionOutput
}

func (va *versionAction) showVersionMessage(tmpl *template.Template, nerdctlVersion NerdctlVersionOutput) error {
var b bytes.Buffer

finchVersionOutput := createFinchVersionOutput(nerdctlVersion)
if err := tmpl.Execute(&b, finchVersionOutput); err != nil {
return err
}
if _, err := fmt.Fprintln(va.stdOut, b.String()); err != nil {
return err
}

return nil
}

func (va *versionAction) printVersion(format string) error {
status, err := lima.GetVMStatus(va.creator, va.logger, limaInstanceName)
if err != nil {
return fmt.Errorf("failed to get VM status: %w", err)
Expand All @@ -102,24 +193,13 @@ func (va *versionAction) printVersion() error {
return fmt.Errorf("failed to JSON-unmarshal the nerdctl version output: %w", err)
}

fmt.Fprintf(va.stdOut, "Client:\n")
fmt.Fprintf(va.stdOut, " Version:\t%s\n", version.Version)
fmt.Fprintf(va.stdOut, " OS/Arch:\t%s/%s\n", nerdctlVersion.Client.Os, nerdctlVersion.Client.Arch)
fmt.Fprintf(va.stdOut, " GitCommit:\t%s\n", version.GitCommit)
fmt.Fprintf(va.stdOut, " nerdctl:\n")
fmt.Fprintf(va.stdOut, " Version:\t%s\n", nerdctlVersion.Client.Version)
fmt.Fprintf(va.stdOut, " GitCommit:\t%s\n", nerdctlVersion.Client.GitCommit)
for _, compo := range nerdctlVersion.Client.Components {
fmt.Fprintf(va.stdOut, " %s:\n", compo.Name)
fmt.Fprintf(va.stdOut, " Version:\t%s\n", compo.Version)
fmt.Fprintf(va.stdOut, " GitCommit:\t%s\n", compo.Details.GitCommit)
tmpl, err := newVersionTemplate(format)
if err != nil {
return err
}
fmt.Fprintf(va.stdOut, "\n")
fmt.Fprintf(va.stdOut, "Server:\n")
for _, compo := range nerdctlVersion.Server.Components {
fmt.Fprintf(va.stdOut, " %s:\n", compo.Name)
fmt.Fprintf(va.stdOut, " Version:\t%s\n", compo.Version)
fmt.Fprintf(va.stdOut, " GitCommit:\t%s\n", compo.Details.GitCommit)
err = va.showVersionMessage(tmpl, nerdctlVersion)
if err != nil {
return err
}

return nil
Expand Down
Loading

0 comments on commit 3456abe

Please sign in to comment.