Skip to content

Commit

Permalink
improve version parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
idelchi committed Dec 16, 2024
1 parent fae3a95 commit 793dd5c
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 15 deletions.
1 change: 1 addition & 0 deletions internal/commands/logic.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ func (app *App) processResult(res result) {
// handleToolError logs errors encountered during tool processing.
func (app *App) handleToolError(tool *tools.Tool, err error, msg string) {
if errors.Is(err, tools.ErrAlreadyExists) ||
errors.Is(err, tools.ErrUpToDate) ||
errors.Is(err, tools.ErrDoesNotHaveTags) ||
errors.Is(err, tools.ErrDoesHaveTags) ||
errors.Is(err, tools.ErrSkipped) {
Expand Down
18 changes: 15 additions & 3 deletions internal/tools/strategy.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package tools

import (
"fmt"

"github.com/idelchi/godyl/internal/version"
)

Expand Down Expand Up @@ -42,15 +44,25 @@ func (s Strategy) Upgrade(t *Tool) error {
case Upgrade:
// Parse the version of the existing tool.
exe := version.NewExecutable(t.Output, t.Exe.Name)
err := exe.ParseVersion()
if err != nil {

parser := version.NewDefaultVersionParser()
if t.VersionParse != "" {
parser.Commands = []string{t.VersionParse}
}

if t.VersionParse == "-" {
return nil
}

if err := exe.ParseVersion(parser); err != nil {
return nil
}

// Parse the desired version of the tool.
if version, err := version.NewDefaultVersionParser().ParseString(t.Version); err == nil {
// If the versions match, return an error indicating the tool is already up to date.
if exe.Version == version {
return ErrAlreadyExists
return fmt.Errorf("%w: current version %q and target version %q match", ErrUpToDate, exe.Version, version)
}
}
return nil
Expand Down
4 changes: 3 additions & 1 deletion internal/tools/tool.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ type Tool struct {
Env env.Env
// Check defines a set of instructions for verifying the tool's integrity or functionality.
Check Checker
//
// VersionParse defines the strategy for parsing the version of the tool.
VersionParse string `yaml:"parse"`
// NoVerifySSL specifies whether SSL verification should be disabled when fetching the tool.
NoVerifySSL bool `json:"-" mapstructure:"-" yaml:"-"`
}

Expand Down
2 changes: 2 additions & 0 deletions internal/tools/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import (
var (
// ErrAlreadyExists indicates that the tool already exists in the system.
ErrAlreadyExists = fmt.Errorf("tool already exists")
// ErrUpToDate indicates that the tool is already up to date.
ErrUpToDate = fmt.Errorf("tool is up to date")
// ErrDoesHaveTags indicates that the tool has tags that are in the excluded tags list.
ErrDoesHaveTags = fmt.Errorf("tool contains excluded tags")
// ErrDoesNotHaveTags indicates that the tool does not contain required tags.
Expand Down
10 changes: 5 additions & 5 deletions internal/version/executable.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"context"
"errors"
"os"
"os/exec"
"strings"
"time"
Expand Down Expand Up @@ -33,6 +34,7 @@ func (e Executable) Command(ctx context.Context, cmdArgs []string) (string, erro
cmd := exec.CommandContext(ctx, e.File.Name(), cmdArgs...)
cmd.Stdout = &out
cmd.Stderr = &out
cmd.Stdin = os.Stdin

err := cmd.Run()

Expand All @@ -42,19 +44,17 @@ func (e Executable) Command(ctx context.Context, cmdArgs []string) (string, erro
// ParseVersion attempts to parse the version of the executable using the provided Version object.
// It iterates over predefined command strategies and tries to parse the version from the command output.
// If successful, it sets the Version field of Executable; otherwise, it returns an error.
func (e *Executable) ParseVersion() error {
timeout := 30 * time.Second
func (e *Executable) ParseVersion(version *Version) error {
timeout := 5 * time.Second

// Create a context with a timeout to prevent hanging
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()

version := NewDefaultVersionParser()

// Iterate through each command strategy
for _, cmdArgs := range version.Commands {
// Get the output of the command
output, err := e.Command(ctx, cmdArgs)
output, err := e.Command(ctx, []string{cmdArgs})
if err != nil {
// Many tools will have an exit 1 status when the version flag is used
}
Expand Down
12 changes: 6 additions & 6 deletions internal/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type Version struct {
// Patterns contains the list of regex patterns for parsing the version from output strings.
Patterns []*regexp.Regexp
// Commands contains the list of command strategies used to extract the version.
Commands [][]string
Commands []string
// String holds the string representation of the parsed version.
String string
}
Expand All @@ -27,11 +27,11 @@ func NewDefaultVersionParser() *Version {
// Pattern for versions formatted as X.X, surrounded by any characters.
regexp.MustCompile(`.*?(\d+\.\d+).*`),
},
Commands: [][]string{
{"--version"}, // Attempt to get version with --version flag.
{"version"}, // Attempt to get version with version command.
{"-version"}, // Attempt to get version with -version flag.
{"-v"}, // Attempt to get version with -v flag.
Commands: []string{
"--version", // Attempt to get version with --version flag.
"-v", // Attempt to get version with -v flag.
"-version", // Attempt to get version with -version flag.
"version", // Attempt to get version with version command.
},
}
}
Expand Down
4 changes: 4 additions & 0 deletions tools.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@

- name: traefik/traefik
description: The Cloud Native Application Proxy
parse: version
tags:
- automation

Expand Down Expand Up @@ -143,6 +144,7 @@

- name: rs/curlie
description: The power of curl, the ease of use of httpie
parse: version
tags:
- terminal

Expand Down Expand Up @@ -225,6 +227,7 @@
condition: '{{ eq .OS "windows" }}'
fallbacks:
- go
parse: "-"
tags:
- automation

Expand All @@ -240,6 +243,7 @@
hints:
- pattern: "{{ .OS }}"
must: true
parse: "-"
tags:
- terminal

Expand Down

0 comments on commit 793dd5c

Please sign in to comment.