script for seeing available upgrades by program versions only

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 :slight_smile:

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

A bit newer version:


#!/usr/bin/env ruby


# a script to compare package versions, excluding build versions
# by Silver Salonen <silver.salonen@gmail.com>
# license: GPL


# TODO:
# show output of zypper when checking packages


# version 0.4 (12.Dec.2012)
# possibility to exclude packages: option --exclude or -e


# version 0.3 (30.Nov.2012)
# - possibility to upgrade packages: option --upgrade or -u


# version 0.2 (29.Nov.2012)
# - use options
# - filter is specified with option --filter or -f
# - default to comparing versions only from the same repository: option --all-repositories or -r
# - show repository names for versions from separate repositories
# - add help/usage: option --help or -h


# version 0.1 (28.Nov.2012)


require 'getoptlong'


def usage
	print "Usage: pkg_version-zypper.rb (--filter|-f) ('<'|'>'|'=')] (--all-repositories|-r)] (--upgrade|-u) -y]] (--exclude|-e) <regex>] (--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 "	--exclude		skip packages matching the given regular expression
"
	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],
	 "--exclude", "-e", GetoptLong::OPTIONAL_ARGUMENT],
	 "-y", GetoptLong::OPTIONAL_ARGUMENT],
)


optHelp = false
optAllRepositories = false
optFilter = nil
optUpgrade = false
optUpgradeY = false
optExclude = nil
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 "-y"
			optUpgradeY = true
		when "--exclude", "-e"
			optExclude = arg
	end
end


if optHelp
	usage
	exit
end


#system("zypper ref")
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)) &&
			!(optExclude && /#{optExclude}/ =~ pkg_name)
		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

On 2012-12-12 09:36, atroxix wrote:
>
> A bit newer version:

Maybe you would want to use the scripts subforum?


Cheers / Saludos,

Carlos E. R.
(from 12.1 x86_64 “Asparagus” at Telcontar)

I would :slight_smile:
Where is it (tried, but didn’t find)?

On 2012-12-12 10:46, atroxix wrote:
>
> robin_listas;2510377 Wrote:
>> On 2012-12-12 09:36, atroxix wrote:
>>>
>>> A bit newer version:
>>
>> Maybe you would want to use the scripts subforum?
>
> I would :slight_smile:
> Where is it (tried, but didn’t find)?

In these forums. Just search for the word “script” or “programming” in
the main forum page.


> https://forums.opensuse.org/english/other-forums/development/programming-scripting/


Cheers / Saludos,

Carlos E. R.
(from 12.1 x86_64 “Asparagus” at Telcontar)

OK, so maybe some admin could move this thread in there? It seems that I can’t do it.

On 2012-12-12 11:06, atroxix wrote:

> OK, so maybe some admin could move this thread in there? It seems that
> I can’t do it.

You have to send a personal message to one. Or use the small report
button at the bottom, it appears that it can also be used for the purpose.


Cheers / Saludos,

Carlos E. R.
(from 12.1 x86_64 “Asparagus” at Telcontar)

Hi
Thread being closed prior to moving to the programming/scripting subforum.

nntp user please don’t reply to this thread.

Hi
Thread moved and re-opened for business.

Some updates to the script:


#!/usr/bin/env ruby


# a script to compare package versions, excluding build versions
# by Silver Salonen <silver.salonen@gmail.com>
# license: GPL


# TODO:
# show output of zypper when checking packages


# version 0.4.2 (23.Jan.2013)
# show package versions also before performing upgrade
# packages with missing repository ("(System Packages)") are always considered to be within whichever other repository


# version 0.4.1 (25.Dec.2012)
# possibility to specify multiple expressions to option --exclude or -e


# version 0.4 (12.Dec.2012)
# possibility to exclude packages: option --exclude or -e


# version 0.3 (30.Nov.2012)
# - possibility to upgrade packages: option --upgrade or -u


# version 0.2 (29.Nov.2012)
# - use options
# - filter is specified with option --filter or -f
# - default to comparing versions only from the same repository: option --all-repositories or -r
# - show repository names for versions from separate repositories
# - add help/usage: option --help or -h


# version 0.1 (28.Nov.2012)


require 'getoptlong'


def usage
	print "Usage: pkg_version-zypper.rb (--filter|-f) ('<'|'>'|'=')] (--all-repositories|-r)] (--upgrade|-u) -y]] (--exclude|-e) <regex-1>,<regex-2>,<regex-N>,] (--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 "	--exclude		skip packages matching the given regular expression. Multiple expressions can be separated with commas.
"
	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 -e amarok,rekonq
"
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


def aGrep(aFrom, sWhat)
	aFrom.each do |a|
		return true if /#{a}/ =~ sWhat
	end
	#else
	return false
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],
	 "--exclude", "-e", GetoptLong::OPTIONAL_ARGUMENT],
	 "-y", GetoptLong::OPTIONAL_ARGUMENT],
)


optHelp = false
optAllRepositories = false
optFilter = nil
optUpgrade = false
optUpgradeY = false
optExclude = ]
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 "-y"
			optUpgradeY = true
		when "--exclude", "-e"
			optExclude = arg.split(',')
	end
end


if optHelp
	usage
	exit
end


#system("zypper ref")
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)) &&
			!(optExclude && aGrep(optExclude, pkg_name))
		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) && (pkg"repository"] == "(System Packages)" || 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][pkg_name] = [hPkgs["v"][pkg_name][pkg_type][pkg_arch]"version"], pkg"version"]]
					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, hPackages|
		sPackages = ""
		sPackagesVersions = ""
		hPackages.each do |pkg_name, aVersions|
			sPackages += "#{pkg_name} "
			sPackagesVersions += "#{pkg_name} (#{aVersions.pop} => #{aVersions.pop}), "
		end
		sPackages = sPackages.sub(/..$/, '')
		sPackagesVersions = sPackagesVersions.sub(/..$/, '')
		if repository.class == String
			print "
Upgrading packages from repository '#{repository}': #{sPackagesVersions}
"
			sCmd = "zypper in --from '#{repository}'"
		else
			print "
Upgrading packages within their current repository: #{sPackagesVersions}
"
			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

Oh, the previous one went terribly wrong. Here’s the correct one:


#!/usr/bin/env ruby


# a script to compare package versions, excluding build versions
# by Silver Salonen <silver.salonen@gmail.com>
# license: GPL


# TODO:
# show output of zypper when checking packages


# version 0.4.2 (23.Jan.2013)
# show package versions also before performing upgrade
# packages with missing repository ("(System Packages)") are always considered to be within whichever other repository
# bugfix: zBigger() gave a wrong result if compareTo had more version number places
# bugfix: zBigger() was not used while composing the hash of packages


# version 0.4.1 (25.Dec.2012)
# possibility to specify multiple expressions to option --exclude or -e


# version 0.4 (12.Dec.2012)
# possibility to exclude packages: option --exclude or -e


# version 0.3 (30.Nov.2012)
# - possibility to upgrade packages: option --upgrade or -u


# version 0.2 (29.Nov.2012)
# - use options
# - filter is specified with option --filter or -f
# - default to comparing versions only from the same repository: option --all-repositories or -r
# - show repository names for versions from separate repositories
# - add help/usage: option --help or -h


# version 0.1 (28.Nov.2012)


require 'getoptlong'


def usage
	print "Usage: pkg_version-zypper.rb (--filter|-f) ('<'|'>'|'=')] (--all-repositories|-r)] (--upgrade|-u) -y]] (--exclude|-e) <regex-1>,<regex-2>,<regex-N>,] (--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 "	--exclude		skip packages matching the given regular expression. Multiple expressions can be separated with commas.
"
	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 -e amarok,rekonq
"
end


def zVersion(sVersion)
	return sVersion.include?("-") ? sVersion.split('-').first() : sVersion
end


# returns:
# '>' -- if sVersion > compareTo
# '<' -- if sVersion < compareTo
# '=' -- if sVersion == compareTo
def zBigger(sVersion, compareTo)
	aVersion = sVersion.split('.').reverse()
	compareTo.split('.').each do |num|
		if aVersion.length == 0
			return '<'
		end
		num_comp = aVersion.pop.to_i
		num = num.to_i
		if num_comp > num
			return '>'
		elsif num_comp < num
			return '<'
		end
	end
	# equal
	return '='
end


def aGrep(aFrom, sWhat)
	aFrom.each do |a|
		return true if /#{a}/ =~ sWhat
	end
	#else
	return false
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],
	 "--exclude", "-e", GetoptLong::OPTIONAL_ARGUMENT],
	 "-y", GetoptLong::OPTIONAL_ARGUMENT],
)


optHelp = false
optAllRepositories = false
optFilter = nil
optUpgrade = false
optUpgradeY = false
optExclude = ]
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 "-y"
			optUpgradeY = true
		when "--exclude", "-e"
			optExclude = arg.split(',')
	end
end


if optHelp
	usage
	exit
end


#system("zypper ref")
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] && zBigger(pkg_version, hPkgs[pkg_status][pkg_name][pkg_type][pkg_arch]"version"]) == '<') &&
			(optAllRepositories || pkg_repository == "(System Packages)" || !(hPkgs[pkg_status][pkg_name][pkg_type][pkg_arch] && hPkgs[pkg_status][pkg_name][pkg_type][pkg_arch]"repository"] != pkg_repository)) &&
			!(optExclude && aGrep(optExclude, pkg_name))
		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) && (pkg"repository"] == "(System Packages)" || 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][pkg_name] = [hPkgs["v"][pkg_name][pkg_type][pkg_arch]"version"], pkg"version"]]
					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, hPackages|
		sPackages = ""
		sPackagesVersions = ""
		hPackages.each do |pkg_name, aVersions|
			sPackages += "#{pkg_name} "
			sPackagesVersions += "#{pkg_name} (#{aVersions.pop} => #{aVersions.pop}), "
		end
		sPackages = sPackages.sub(/.$/, '')
		sPackagesVersions = sPackagesVersions.sub(/..$/, '')
		if repository.class == String
			print "
Upgrading packages from repository '#{repository}': #{sPackagesVersions}
"
			sCmd = "zypper in --from '#{repository}'"
		else
			print "
Upgrading packages within their current repository: #{sPackagesVersions}
"
			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

Found out that the script left many packages unnoticed. Here’s the fixed one.

#!/usr/bin/env ruby

# a script to compare package versions, excluding build versions
# by Silver Salonen <silver.salonen@gmail.com>
# license: GPL


# TODO:
# + show output of zypper when checking packages


# version 0.5.1 (31.Jan.2013)
# + possibility to show abandoned packages that have the only repository "(System Packages)": --abandoned or -a


# version 0.5 (25.Jan.2013)
# + remember all the repositories for packagges, otherwise packages being in several repositories may have never been found
# - bugfix: use also _ as version number separator


# version 0.4.2 (23.Jan.2013)
# + show package versions also before performing upgrade
# + packages with missing repository ("(System Packages)") are always considered to be within whichever other repository
# - bugfix: zBigger() gave a wrong result if compareTo had more version number places
# - bugfix: zBigger() was not used while composing the hash of packages


# version 0.4.1 (25.Dec.2012)
# + possibility to specify multiple expressions to option --exclude or -e


# version 0.4 (12.Dec.2012)
# + possibility to exclude packages: option --exclude or -e


# version 0.3 (30.Nov.2012)
# + possibility to upgrade packages: option --upgrade or -u


# version 0.2 (29.Nov.2012)
# + use options
# + filter is specified with option --filter or -f
# + default to comparing versions only from the same repository: option --all-repositories or -r
# + show repository names for versions from separate repositories
# + add help/usage: option --help or -h


# version 0.1 (28.Nov.2012)


require 'getoptlong'


def usage
	print "Usage: pkg_version-zypper.rb (--filter|-f) ('<'|'>'|'=')] (--all-repositories|-r)] (--upgrade|-u) -y]] (--exclude|-e) <regex-1>,<regex-2>,<regex-N>,] --abandoned|-a] (--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 "	--exclude		skip packages matching the given regular expression, multiple expressions can be separated with commas
"
	print "	--help			show this help
"
	print "	--abandoned		show abandoned packages which are considered the ones that have the single repository '(System Packages)'
"
	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 -e amarok,rekonq
"
end


def zVersion(sVersion)
	sVersion = sVersion.sub('_', '.')
	return sVersion.include?('-') ? sVersion.split('-').first() : sVersion
end


# returns:
# '>' -- if sVersion > compareTo
# '<' -- if sVersion < compareTo
# '=' -- if sVersion == compareTo
def zBigger(sVersion, compareTo)
	aVersion = sVersion.split('.').reverse()
	compareTo.split('.').each do |num|
		if aVersion.length == 0
			return '<'
		end
		num_comp = aVersion.pop.to_i
		num = num.to_i
		if num_comp > num
			return '>'
		elsif num_comp < num
			return '<'
		end
	end
	# equal
	return '='
end


def aGrep(aFrom, sWhat)
	aFrom.each do |a|
		return true if /#{a}/ =~ sWhat
	end
	#else
	return false
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],
	 "--exclude", "-e", GetoptLong::OPTIONAL_ARGUMENT],
	 "--abandoned", "-a", GetoptLong::OPTIONAL_ARGUMENT],
	 "-y", GetoptLong::OPTIONAL_ARGUMENT],
)


optHelp = false
optAllRepositories = false
optFilter = nil
optUpgrade = false
optUpgradeY = false
optAbandoned = false
optExclude = ]
hUpgrade = {}
hAbandoned = {}


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 "-y"
			optUpgradeY = true
		when "--exclude", "-e"
			optExclude = arg.split(',')
		when "--abandoned", "-a"
			optAbandoned = true
	end
end


if optHelp
	usage
	exit
end


#system("zypper ref")
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?
	hPkgs[pkg_status][pkg_name][pkg_type][pkg_arch] = {} if hPkgs[pkg_status][pkg_name][pkg_type][pkg_arch].nil?


	if !(optExclude && aGrep(optExclude, pkg_name))
		if !hPkgs[pkg_status][pkg_name][pkg_type][pkg_arch][pkg_repository] ||
				hPkgs[pkg_status][pkg_name][pkg_type][pkg_arch][pkg_repository] && zBigger(pkg_version, hPkgs[pkg_status][pkg_name][pkg_type][pkg_arch][pkg_repository]) == '>'
			hPkgs[pkg_status][pkg_name][pkg_type][pkg_arch][pkg_repository] = pkg_version
		end
	end
end


hPkgs"i"].each do |pkg_name, hPkg|
	hPkg.each do |pkg_type, hArchs|
		hArchs.each do |pkg_arch, hRepositories|
			hRepositories.each do |pkg_repository, pkg_version|
				if optAbandoned && pkg_repository == "(System Packages)" && !(hPkgs"v"] && hPkgs"v"][pkg_name] && hPkgs"v"][pkg_name][pkg_type] && hPkgs"v"][pkg_name][pkg_type][pkg_arch])
					hAbandoned[pkg_name] = pkg_version
				end
				if !(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][pkg_repository])
					# no other package available besides the one installed, make it available
					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] = {} if hPkgs"v"][pkg_name][pkg_type][pkg_arch].nil?
					hPkgs"v"][pkg_name][pkg_type][pkg_arch][pkg_repository] = pkg_version
				end
				pkg_repository_biggest = ""
				pkg_version_biggest = ""
				if optAllRepositories || pkg_repository == "(System Packages)"
					hPkgs"v"][pkg_name][pkg_type][pkg_arch].each do |pkg_repository2, pkg_version2|
						if zBigger(pkg_version_biggest, pkg_version2) == '<'
							pkg_repository_biggest = pkg_repository2
							pkg_version_biggest = pkg_version2
						end
					end
					zBigger = zBigger(pkg_version, pkg_version_biggest)
					showRepository = pkg_repository_biggest != pkg_repository
				else
					pkg_version_biggest = hPkgs"v"][pkg_name][pkg_type][pkg_arch][pkg_repository]
					zBigger = zBigger(pkg_version, pkg_version_biggest)
					showRepository = false
				end
				if (!optFilter || optFilter == zBigger)
					if optUpgrade && zBigger == '<'
						repository = showRepository ? pkg_repository_biggest : 0
						hUpgrade[repository] = {} if hUpgrade[repository].nil?
						hUpgrade[repository][pkg_name] = [pkg_version_biggest, pkg_version]
					end
					print "#{pkg_name}: #{pkg_version}#{showRepository ? " (#{pkg_repository})" : ""} #{zBigger} #{pkg_version_biggest}#{showRepository ? " (#{pkg_repository_biggest})" : ""}
"
				end
			end
		end
	end
end


if optAbandoned
	print "Abandoned packages:
"
	hAbandoned.each do |pkg_name, pkg_version|
		print "#{pkg_name} (#{pkg_version})
"
	end
end


if optUpgrade
	hUpgrade.each do |repository, hPackages|
		sPackages = ""
		sPackagesVersions = ""
		hPackages.each do |pkg_name, aVersions|
			sPackages += "#{pkg_name} "
			sPackagesVersions += "#{pkg_name} (#{aVersions.pop} => #{aVersions.pop}), "
		end
		sPackages = sPackages.sub(/.$/, '')
		sPackagesVersions = sPackagesVersions.sub(/..$/, '')
		if repository.class == String
			print "
Upgrading packages from repository '#{repository}': #{sPackagesVersions}
"
			sCmd = "zypper in --from '#{repository}'"
		else
			print "
Upgrading packages within their current repository: #{sPackagesVersions}
"
			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

On 01/31/2013 09:26 AM, atroxix wrote:
> # version 0.5.1 (31.Jan.2013)

decided to try it, and got:


denverd@linux-os114:~> locate getoptlong
/usr/lib/ruby/1.8/getoptlong.rb
denverd@linux-os114:~/bin> pkg_version-zypper.rb
/home/denverd/bin/pkg_version-zypper.rb: line 54: require: command not found
/home/denverd/bin/pkg_version-zypper.rb: line 57: def: command not found
/home/denverd/bin/pkg_version-zypper.rb: line 59: print: command not found
/home/denverd/bin/pkg_version-zypper.rb: line 60: print: command not found
/home/denverd/bin/pkg_version-zypper.rb: line 61: print: command not found
/home/denverd/bin/pkg_version-zypper.rb: line 62: print: command not found
/home/denverd/bin/pkg_version-zypper.rb: line 63: print: command not found
/home/denverd/bin/pkg_version-zypper.rb: line 64: print: command not found
/home/denverd/bin/pkg_version-zypper.rb: line 65: print: command not found
/home/denverd/bin/pkg_version-zypper.rb: line 66: print: command not found
/home/denverd/bin/pkg_version-zypper.rb: line 67: print: command not found
/home/denverd/bin/pkg_version-zypper.rb: line 68: print: command not found
/home/denverd/bin/pkg_version-zypper.rb: line 69: end: command not found
/home/denverd/bin/pkg_version-zypper.rb: line 72: syntax error near
unexpected token `('
/home/denverd/bin/pkg_version-zypper.rb: line 72: `  def zVersion(sVersion)

and have no idea how to proceed… ?? except to write: ‘which’ can not
find an executable named ‘require’, ‘def’, ‘print’, or ‘end’ so i wonder
if your script should setup an environment where pkg_version-zypper.rb
can find those (of course, i can just barely spell ‘ruby’, and that is
all i know about that.)

openSUSE 11.4 Evergreen with KDE4 on a little atom (more detail in sig)


dd
http://tinyurl.com/DD-Hardware
http://tinyurl.com/DD-Software

What if you run it with “ruby pkg_version-zypper.rb”?

On 01/31/2013 03:06 PM, atroxix wrote:
> ruby pkg_version-zypper.rb


denverd@linux-os114:~> ruby pkg_version-zypper.rb
ruby: No such file or directory -- pkg_version-zypper.rb (LoadError)
denverd@linux-os114:~> which ruby
/usr/bin/ruby
denverd@linux-os114:~>

so, must it be run as root?

(i’m not competent to look though your script and determine if it is
safe, so) don’t take offense, but i hesitate to run any script as root
on my production machine.


dd

No, you don’t have to be root (in that case upgrading won’t work and repositories won’t autorefreshed, but you should be able to read current information just fine). You just have to specify the full path to the script :slight_smile:
In your case it seems to be eg:

ruby ~/bin/pkg_version-zypper.rb -h

On 01/31/2013 04:16 PM, atroxix wrote:
> ruby ~/bin/pkg_version-zypper.rb -h

hmmmm…since my /bin is in my path, shouldn’t it be found?

so, the following is getting closer (but still i don’t understand why
ruby couldn’t find my bin):


denverd@linux-os114:~> ruby ~/bin/pkg_version-zypper.rb -h
/home/denverd/bin/pkg_version-zypper.rb:118: syntax error, unexpected ')'
denverd@linux-os114:~>


dd

dd wrote:
> On 01/31/2013 04:16 PM, atroxix wrote:
>> ruby ~/bin/pkg_version-zypper.rb -h
>
> hmmmm…since my /bin is in my path, shouldn’t it be found?

No, arguments to programs are not changed like that.

As to why it didn’t run when invoked directly, is it marked as executable?

> so, the following is getting closer (but still i don’t understand why
> ruby couldn’t find my bin):
>
>


> denverd@linux-os114:~> ruby ~/bin/pkg_version-zypper.rb -h
> /home/denverd/bin/pkg_version-zypper.rb:118: syntax error, unexpected ')'
> denverd@linux-os114:~>
> 

It would probably help if you posted line 118 (and a couple of lines
around it) for whatever code you actually have in the file you’re trying
to execute.

Right :slight_smile:

In my original script lines 117 and 118 are:


                when "--filter", "-f"
                        optFilter = arg

So no ‘)’ there…

On 01/31/2013 05:51 PM, Dave Howorth wrote:
>
> As to why it didn’t run when invoked directly, is it marked as executable?

yes…


denverd@linux-os114:~/bin> ls -hal *rb
-rwx------ 1 denverd users 9.0K Jan 31 18:42 pkg_version-zypper.rb*
denverd@linux-os114:~/bin>

It would probably help if you posted line 118 (and a couple of lines
around it) for whatever code you actually have in the file you’re trying
to execute.

it is as in #11 above (except i added two commented out lines/notes, so
the offending character “)” is on line 116 of the originalscript…


 "--exclude", "-e", GetoptLong::OPTIONAL_ARGUMENT],
 "--abandoned", "-a", GetoptLong::OPTIONAL_ARGUMENT],
 "-y", GetoptLong::OPTIONAL_ARGUMENT],
)


optHelp = false
optAllRepositories = false
optFilter = nil
optUpgrade = false

so, i removed that apparently troublesome “)” and now get this:


denverd@linux-os114:~> ruby ~/bin/pkg_version-zypper.rb -h
/home/denverd/bin/pkg_version-zypper.rb:120: syntax error, unexpected
tIDENTIFIER, expecting ')'
optAllRepositories = false
^
denverd@linux-os114:~>

so, while ) was unexpedted, when i took it out now it is expected…that
is very cool!?


dd