Improved error message for remote version package output

This commit is contained in:
Andrew Woodlee 2025-07-09 23:20:11 -05:00
parent b91cf18b04
commit 47b2aabd9f
8 changed files with 45 additions and 25 deletions

View File

@ -21,4 +21,4 @@ description: >
## exec host subcommand ## exec host subcommand
Backy has a subcommand `exec host`. This subcommand takes the flags of `-m host1 -m host2`. For now these hosts need to be defined in the config file. Backy has a subcommand `exec host`. This subcommand takes the flags of `-m host1 -m host2`. The commands can also be specified by `-c command1 -c command2`.

View File

@ -124,9 +124,9 @@ notifications:
### Logging ### Logging
cmd-std-out controls whether commands output is echoed to StdOut. `cmd-std-out` controls whether commands output is echoed to StdOut.
If logfile is not defined, the log file will be written to the config directory in the file `backy.log`. If `logfile` is not defined, the log file will be written to the config directory in the file `backy.log`.
`console-disabled` controls whether the logging messages are echoed to StdOut. Default is false. `console-disabled` controls whether the logging messages are echoed to StdOut. Default is false.

View File

@ -333,11 +333,12 @@ func getCommandTypeAndSetCommandInfo(command *Command) *Command {
func parsePackageVersion(output string, cmdCtxLogger zerolog.Logger, command *Command, cmdOutBuf bytes.Buffer) ([]string, error) { func parsePackageVersion(output string, cmdCtxLogger zerolog.Logger, command *Command, cmdOutBuf bytes.Buffer) ([]string, error) {
var err error
var errs []error var errs []error
pkgVersionOnSystem, errs := command.pkgMan.ParseRemotePackageManagerVersionOutput(output) pkgVersionOnSystem, err := command.pkgMan.ParseRemotePackageManagerVersionOutput(output)
if errs != nil { if err != nil {
cmdCtxLogger.Error().Errs("Error parsing package version output", errs).Send() cmdCtxLogger.Error().AnErr("Error parsing package version output", err).Send()
return collectOutput(&cmdOutBuf, command.Name, cmdCtxLogger, command.Output.ToLog), fmt.Errorf("error parsing package version output: %v", errs) return collectOutput(&cmdOutBuf, command.Name, cmdCtxLogger, command.Output.ToLog), fmt.Errorf("error parsing package version output: %v", err)
} }
for _, p := range pkgVersionOnSystem { for _, p := range pkgVersionOnSystem {

View File

@ -109,7 +109,7 @@ func (a *AptManager) SetAuthCommand(authCommand string) {
} }
// Parse parses the apt-cache policy output to extract Installed and Candidate versions. // Parse parses the apt-cache policy output to extract Installed and Candidate versions.
func (a *AptManager) ParseRemotePackageManagerVersionOutput(output string) ([]packagemanagercommon.Package, []error) { func (a *AptManager) ParseRemotePackageManagerVersionOutput(output string) ([]packagemanagercommon.Package, error) {
var ( var (
packageName string packageName string
installedString string installedString string
@ -118,11 +118,12 @@ func (a *AptManager) ParseRemotePackageManagerVersionOutput(output string) ([]pa
) )
// Check for error message in the output // Check for error message in the output
if strings.Contains(output, "Unable to locate package") { if strings.Contains(output, "Unable to locate package") {
return nil, []error{fmt.Errorf("error: %s", strings.TrimSpace(output))} return nil, fmt.Errorf("error: %s", strings.TrimSpace(output))
} }
packages := []packagemanagercommon.Package{} packages := []packagemanagercommon.Package{}
outputBuf := bytes.NewBufferString(output) outputBuf := bytes.NewBufferString(output)
outputScan := bufio.NewScanner(outputBuf) outputScan := bufio.NewScanner(outputBuf)
var packageCount uint
for outputScan.Scan() { for outputScan.Scan() {
line := outputScan.Text() line := outputScan.Text()
if !strings.HasPrefix(line, " ") && strings.HasSuffix(line, ":") { if !strings.HasPrefix(line, " ") && strings.HasSuffix(line, ":") {
@ -141,17 +142,24 @@ func (a *AptManager) ParseRemotePackageManagerVersionOutput(output string) ([]pa
if countRelevantLines == 2 { if countRelevantLines == 2 {
countRelevantLines = 0 countRelevantLines = 0
packages = append(packages, packagemanagercommon.Package{ if !strings.Contains(installedString, " (none)") {
Name: packageName, packageCount++
VersionCheck: packagemanagercommon.PackageVersion{ packages = append(packages, packagemanagercommon.Package{
Installed: strings.TrimSpace(installedString), Name: packageName,
Candidate: strings.TrimSpace(candidateString), VersionCheck: packagemanagercommon.PackageVersion{
Match: installedString == candidateString, Installed: strings.TrimSpace(installedString),
}}, Candidate: strings.TrimSpace(candidateString),
) Match: installedString == candidateString,
}},
)
}
} }
} }
if packageCount == 0 {
return nil, fmt.Errorf("no packages found")
}
return packages, nil return packages, nil
} }

View File

@ -92,11 +92,11 @@ func (d *DnfManager) CheckVersion(pkgs []packagemanagercommon.Package) (string,
} }
// Parse parses the dnf info output to extract Installed and Candidate versions. // Parse parses the dnf info output to extract Installed and Candidate versions.
func (d DnfManager) ParseRemotePackageManagerVersionOutput(output string) ([]packagemanagercommon.Package, []error) { func (d DnfManager) ParseRemotePackageManagerVersionOutput(output string) ([]packagemanagercommon.Package, error) {
// Check for error message in the output // Check for error message in the output
if strings.Contains(output, "No matching packages to list") { if strings.Contains(output, "No matching packages to list") {
return nil, []error{fmt.Errorf("error: package not listed")} return nil, fmt.Errorf("error: package not listed")
} }
// Define regular expressions to capture installed and available versions // Define regular expressions to capture installed and available versions
@ -118,7 +118,7 @@ func (d DnfManager) ParseRemotePackageManagerVersionOutput(output string) ([]pac
} }
if installedVersion == "" && candidateVersion == "" { if installedVersion == "" && candidateVersion == "" {
return nil, []error{fmt.Errorf("failed to parse versions from dnf output")} return nil, fmt.Errorf("failed to parse versions from dnf output")
} }
return nil, nil return nil, nil

View File

@ -16,7 +16,7 @@ type PackageManager interface {
Upgrade(pkgs []packagemanagercommon.Package) (string, []string) // Upgrade a specific package Upgrade(pkgs []packagemanagercommon.Package) (string, []string) // Upgrade a specific package
UpgradeAll() (string, []string) UpgradeAll() (string, []string)
CheckVersion(pkgs []packagemanagercommon.Package) (string, []string) CheckVersion(pkgs []packagemanagercommon.Package) (string, []string)
ParseRemotePackageManagerVersionOutput(output string) ([]packagemanagercommon.Package, []error) ParseRemotePackageManagerVersionOutput(output string) ([]packagemanagercommon.Package, error)
// Configure applies functional options to customize the package manager. // Configure applies functional options to customize the package manager.
Configure(options ...packagemanagercommon.PackageManagerOption) Configure(options ...packagemanagercommon.PackageManagerOption)
} }

View File

@ -90,11 +90,11 @@ func (y *YumManager) CheckVersion(pkgs []packagemanagercommon.Package) (string,
} }
// Parse parses the dnf info output to extract Installed and Candidate versions. // Parse parses the dnf info output to extract Installed and Candidate versions.
func (y YumManager) ParseRemotePackageManagerVersionOutput(output string) ([]packagemanagercommon.Package, []error) { func (y YumManager) ParseRemotePackageManagerVersionOutput(output string) ([]packagemanagercommon.Package, error) {
// Check for error message in the output // Check for error message in the output
if strings.Contains(output, "No matching packages to list") { if strings.Contains(output, "No matching packages to list") {
return nil, []error{fmt.Errorf("error: package not listed")} return nil, fmt.Errorf("error: package not listed")
} }
// Define regular expressions to capture installed and available versions // Define regular expressions to capture installed and available versions
@ -116,7 +116,7 @@ func (y YumManager) ParseRemotePackageManagerVersionOutput(output string) ([]pac
} }
if installedVersion == "" && candidateVersion == "" { if installedVersion == "" && candidateVersion == "" {
return nil, []error{fmt.Errorf("failed to parse versions from dnf output")} return nil, fmt.Errorf("failed to parse versions from dnf output")
} }
return nil, nil return nil, nil

View File

@ -8,6 +8,14 @@ commands:
packageManager: apt packageManager: apt
packageOperation: checkVersion packageOperation: checkVersion
checkAptNoVersion:
type: package
shell: zsh
packages:
- name: "apt"
packageManager: apt
packageOperation: checkVersion
checkDockerPartialVersionWithoutRegex: checkDockerPartialVersionWithoutRegex:
type: package type: package
shell: zsh shell: zsh
@ -51,3 +59,6 @@ cmdLists:
- checkDockerPartialVersionWithRegex - checkDockerPartialVersionWithRegex
- checkDockerVersionWithInvalidRegex - checkDockerVersionWithInvalidRegex
- checkDockerNoVersion - checkDockerNoVersion
logging:
verbose: true