Hi.
After years of manually comparing package versions via yast2 I wrote a simple script in ruby for that (it just parses zypper’s output and summarizes it). I designed the output by FreeBSD’s pkg_version and named the script as such too
As I don’t know whether there is an “official” place for any useful scripts I’ll post the script here, sorry if it’s an improper place (if there’s a more proper place for posting the script, please let me know). Maybe someone else finds it useful too (I have seen such wish in Bugzilla or somewhere…).
Usage: pkg_version-zypper.rb (–filter|-f) (’<’|’>’|’=’)] (–all-repositories|-r)] (–upgrade|-u) -y]] (–help|-h)]
Options:
–filter show only package versions equal to the specified comparison operator (’>’ or ‘<’ or ‘=’)
–all-repositories compare versions from foreign repositories too
–upgrade upgrade all packages. If -r is set, upgrade packages from other repositories too.
–help show this help
-y upgrade without interaction (keep in mind that if any package upgrade fails, all fail)
Example: pkg_version-zypper.rb -f ‘<’ -r -u
#!/usr/bin/env ruby
# a script to compare package versions, excluding build versions
# by Silver Salonen <silver.salonen@gmail.com>
# license: GPL
# version 0.3 (30.Nov.2012)
require 'getoptlong'
def usage
print "Usage: pkg_version-zypper.rb (--filter|-f) ('<'|'>'|'=')] (--all-repositories|-r)] (--upgrade|-u) -y]] (--help|-h)]
"
print "
Options:
"
print " --filter show only package versions equal to the specified comparison operator ('>' or '<' or '=')
"
print " --all-repositories compare versions from foreign repositories too
"
print " --upgrade upgrade all packages. If -r is set, upgrade packages from other repositories too.
"
print " --help show this help
"
print " -y upgrade without interaction (keep in mind that if any package upgrade fails, all fail)
"
print "
Example: pkg_version-zypper.rb -f '<' -r -u
"
end
def zVersion(sVersion)
return sVersion.include?("-") ? sVersion.split('-').first() : sVersion
end
# returns:
# '>' -- if sVersion is bigger than compareTo
# '<' -- if sVersion is smaller than compareTo
# '=' -- if sVersion is equal to compareTo
def zBigger(sVersion, compareTo)
compareTo = compareTo.split('.').reverse()
sVersion.split('.').each do |num|
if compareTo.length == 0
return '>'
end
num_comp = compareTo.pop
if num.to_i > num_comp.to_i
return '>'
elsif num.to_i < num_comp.to_i
return '<'
end
end
# equal
return '='
end
opts = GetoptLong.new(
"--help", "-h", GetoptLong::OPTIONAL_ARGUMENT],
"--filter", "-f", GetoptLong::OPTIONAL_ARGUMENT],
"--all-repositories", "-r", GetoptLong::OPTIONAL_ARGUMENT],
"--upgrade", "-u", GetoptLong::OPTIONAL_ARGUMENT],
"-y", GetoptLong::OPTIONAL_ARGUMENT],
)
optHelp = false
optAllRepositories = false
optFilter = nil
optUpgrade = false
optUpgradeY = false
hUpgrade = {}
opts.each do |opt, arg|
case opt
when "--help", "-h"
optHelp = true
when "--all-repositories", "-r"
optAllRepositories = true
when "--filter", "-f"
optFilter = arg
when "--upgrade", "-u"
optUpgrade = true
when "--upgrade", "-y"
optUpgradeY = true
end
end
if optHelp
usage
exit
end
hPkgs = {}
`zypper se -s '' | grep '^[iv ] |'`.each_line do |pkg_line|
aPkg = pkg_line.split('|')
pkg_name = aPkg[1].strip()
pkg_status = aPkg[0].strip().length > 0 ? aPkg[0].strip() : "v"
pkg_type = aPkg[2].strip()
pkg_arch = aPkg[4].strip()
pkg_version = zVersion(aPkg[3].strip())
pkg_repository = aPkg[5].strip()
hPkgs[pkg_status] = {} if hPkgs[pkg_status].nil?
hPkgs[pkg_status][pkg_name] = {} if hPkgs[pkg_status][pkg_name].nil?
hPkgs[pkg_status][pkg_name][pkg_type] = {} if hPkgs[pkg_status][pkg_name][pkg_type].nil?
if !(hPkgs[pkg_status][pkg_name][pkg_type][pkg_arch] && hPkgs[pkg_status][pkg_name][pkg_type][pkg_arch]"version"] > pkg_version) && (optAllRepositories || !(hPkgs[pkg_status][pkg_name][pkg_type][pkg_arch] && hPkgs[pkg_status][pkg_name][pkg_type][pkg_arch]"repository"] != pkg_repository))
hPkgs[pkg_status][pkg_name][pkg_type][pkg_arch] = {"version" => pkg_version, "repository" => pkg_repository}
end
end
hPkgs"i"].each do |pkg_name, hPkg|
hPkg.each do |pkg_type, hArchs|
hArchs.each do |pkg_arch, pkg|
if !(hPkgs"v"][pkg_name] && hPkgs"v"][pkg_name][pkg_type] && hPkgs"v"][pkg_name][pkg_type][pkg_arch]) ||
hPkgs"v"][pkg_name] && hPkgs"v"][pkg_name][pkg_type] && hPkgs"v"][pkg_name][pkg_type][pkg_arch] && hPkgs"v"][pkg_name][pkg_type][pkg_arch]"repository"] == pkg"repository"]
hPkgs"v"] = {} if hPkgs"v"].nil?
hPkgs"v"][pkg_name] = {} if hPkgs"v"][pkg_name].nil?
hPkgs"v"][pkg_name][pkg_type] = {} if hPkgs"v"][pkg_name][pkg_type].nil?
hPkgs"v"][pkg_name][pkg_type][pkg_arch] = pkg
end
if hPkgs"v"][pkg_name] && hPkgs"v"][pkg_name][pkg_type] && hPkgs"v"][pkg_name][pkg_type][pkg_arch]
zBigger = zBigger(pkg"version"], hPkgs"v"][pkg_name][pkg_type][pkg_arch]"version"])
if (!optFilter || optFilter == zBigger) && (optAllRepositories || hPkgs"v"][pkg_name][pkg_type][pkg_arch]"repository"] == pkg"repository"])
showRepository = hPkgs"v"][pkg_name][pkg_type][pkg_arch]"repository"] != pkg"repository"]
if optUpgrade && zBigger == '<'
repository = showRepository ? hPkgs"v"][pkg_name][pkg_type][pkg_arch]"repository"] : 0
hUpgrade[repository] = ] if hUpgrade[repository].nil?
hUpgrade[repository].push(pkg_name)
end
print "#{pkg_name}: #{pkg"version"]}#{showRepository ? " (#{pkg"repository"]})" : ""} #{zBigger} #{hPkgs"v"][pkg_name][pkg_type][pkg_arch]"version"]}#{showRepository ? " (#{hPkgs"v"][pkg_name][pkg_type][pkg_arch]"repository"]})" : ""}
"
end
end
end
end
end
if optUpgrade && !hUpgrade.nil?
hUpgrade.each do |repository, aPackages|
sPackages = aPackages.join(" ")
if repository.class == String
print "
Upgrading packages from repository '#{repository}': #{sPackages}
"
sCmd = "zypper in --from '#{repository}'"
else
print "
Upgrading packages within their current repository: #{sPackages}
"
sCmd = "zypper up"
end
if optUpgradeY
`#{sCmd} -y --auto-agree-with-licenses #{sPackages}`
if $?.to_i != 0
print "Upgrading packages failed! Retry manually with: #{sCmd} #{sPackages}
"
end
else
system("#{sCmd} #{sPackages}")
end
end
end