epm-query 7.85 KB
Newer Older
Danil Mikhailov's avatar
Danil Mikhailov committed
1 2
#!/bin/sh
#
3 4
# Copyright (C) 2012, 2013, 2015-2017  Etersoft
# Copyright (C) 2012, 2013, 2015-2017  Vitaly Lipatov <lav@etersoft.ru>
Danil Mikhailov's avatar
Danil Mikhailov committed
5
#
6 7 8
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
Danil Mikhailov's avatar
Danil Mikhailov committed
9 10 11 12 13
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
# GNU Affero General Public License for more details.
Danil Mikhailov's avatar
Danil Mikhailov committed
15
#
16 17
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
Danil Mikhailov's avatar
Danil Mikhailov committed
18 19
#

20
load_helper epm-packages
21
load_helper epm-print
22

23 24 25 26 27
# pkg suffix
__print_with_arch_suffix()
{
	local pkg="$1"
	local suffix="$2"
28
	[ -n "$pkg" ] || return 1
29
	# do not change if some suffix already exists
30 31 32 33
	echo "$pkg" | grep -q "(x86-32)$" && echo "$pkg" | sed -e "s|(x86-32)$|.i686|" && return 1
	echo "$pkg" | grep "\.x86_64$" && return 1
	echo "$pkg" | grep "\.noarch$" && return 1
	echo "$pkg" | grep "\.i[56]86$" && return 1
34 35
	echo "$pkg$suffix"
}
Vitaly Lipatov's avatar
Vitaly Lipatov committed
36

37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
# add suffix .x86_64 if we have 64 arch
exp_with_arch_suffix()
{
	local suffix

	[ "$($DISTRVENDOR -a)" = "x86_64" ] || { cat ; return ; }
	# TODO: it is ok for ALT rpm to remove with this suffix
	# TODO: separate install and remove?
	case $PMTYPE in
		yum-rpm|dnf-rpm)
			suffix=".x86_64"
			;;
		*)
			cat
			return
			;;
	esac

	# TODO: use estrlist or some function to do it
56 57
	local pkg
	for pkg in $(cat) ; do
58
		local p
59
		# check only packages without arch
60
		p="$(__print_with_arch_suffix "$pkg" .i686)" || { echo "$pkg" ; continue ; }
61 62 63
		# add arch suffix only if arch package already installed (otherwise we don't know package arch)
		is_installed "$p" || { echo "$pkg" ; continue ; }
		echo "$pkg.x86_64"
64 65 66 67
	done
}


68 69 70 71 72 73 74 75 76 77
_get_grep_exp()
{
	local def="^$1$"
	[ "$PMTYPE" != "emerge" ] && echo "$def" && return
	# Gentoo hack: support for short package form
	echo "$1" | grep -q "/" && echo "$def" && return
	echo "/$1$"
}

# TODO: combine with -qa (the difference only in return status now)
78
_shortquery_via_packages_list()
79
{
80
	local res=1
81
	local grepexp
82 83
	local firstpkg=$1
	shift
84

85 86
	grepexp=$(_get_grep_exp $firstpkg)

87 88
	# TODO: we miss status due grep
	# Note: double call due stderr redirect
89
	# Note: we use short=1 here due grep by ^name$
90
	# separate first line for print out command
91
	(short=1 pkg_filenames=$firstpkg epm_packages | grep -- "$grepexp") && res=0 || res=1
92

93
	local pkg
94
	for pkg in "$@" ; do
95
		grepexp=$(_get_grep_exp $pkg)
96
		(short=1 pkg_filenames=$pkg epm_packages 2>/dev/null) | grep -- "$grepexp" || res=1
97
	done
98

99
	# TODO: print in query (for user): 'warning: package $pkg is not installed'
100 101 102
	return $res
}

103 104 105 106
# Note: modified from _shortquery_via_packages_list
# TODO: non optimal double epm packages call
_query_via_packages_list()
{
107
	local res=1
108 109 110 111 112 113
	local grepexp
	local firstpkg=$1
	shift

	grepexp=$(_get_grep_exp $firstpkg)

114 115 116
	# TODO: we miss status due grep
	# TODO: grep correctly
	# Note: double call due stderr redirect
117 118
	# Note: we use short=1 here due grep by ^name$
	# separate first line for print out command
119
	(short=1 pkg_filenames=$firstpkg epm_packages) | grep -q -- "$grepexp" && (quiet=1 pkg_filenames=$firstpkg epm_packages) && res=0 || res=1
120 121 122 123

	local pkg
	for pkg in "$@" ; do
		grepexp=$(_get_grep_exp $pkg)
124
		(short=1 pkg_filenames=$pkg epm_packages 2>/dev/null) | grep -q -- "$grepexp" && (quiet=1 pkg_filenames=$pkg epm_packages) || res=1
125 126 127 128 129
	done

	return $res
}

Vitaly Lipatov's avatar
Vitaly Lipatov committed
130
# internal use only, for installed package
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
__epm_get_hilevel_nameform()
{
	[ -n "$*" ] || return

	case $PMTYPE in
		apt-rpm)
			# use # as delimeter for apt
			local pkg
			pkg=$(rpm -q --queryformat "%{NAME}#%{SERIAL}:%{VERSION}-%{RELEASE}\n" $1)
			echo $pkg | grep -q "(none)" && pkg=$(rpm -q --queryformat "%{NAME}#%{VERSION}-%{RELEASE}\n" $1)
			# HACK: can use only for multiple install packages like kernel
			echo $pkg | grep -q kernel || return 1
			echo $pkg
			return
			;;
146
		yum-rpm|dnf-rpm)
147 148
			# just use strict version with Epoch and Serial
			local pkg
149 150
			pkg=$(rpm -q --queryformat "%{EPOCH}:%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n" $1)
			echo $pkg | grep -q "(none)" && pkg=$(rpm -q --queryformat "%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n" $1)
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
			echo $pkg
			return
			;;
		*)
			return 1
			;;
	esac
}

# for local installed packages only
# used from epm remove
__epm_get_hilevel_name()
{
	local i
	for i in $@ ; do
		local pkg
		# get short form in pkg
Vitaly Lipatov's avatar
Vitaly Lipatov committed
168 169
		# FIXME: where we use it? continue or pkg=$i?
		quiet=1 pkg=$(__epm_query_shortname "$i") || pkg="$i" #continue # drop not installed packages
170 171 172
		# if already short form, skipped
		[ "$pkg" = "$i" ] && echo "$i" && continue
		# try get long form or use short form
Vitaly Lipatov's avatar
Vitaly Lipatov committed
173
		__epm_get_hilevel_nameform "$i" || echo $pkg
174 175 176
	done
}

177 178 179 180
__epm_query_file()
{
	local CMD

181
	[ -z "$*" ] && return
182 183

	case $PMTYPE in
184
		*-rpm)
185
			CMD="rpm -qp"
186
			[ -n "$short" ] && CMD="rpm -qp --queryformat %{name}\n"
187
			;;
Vitaly Lipatov's avatar
Vitaly Lipatov committed
188
		*-dpkg)
189 190
			CMD="dpkg-deb --show --showformat=\${Package}-\${Version}\n"
			[ -n "$short" ] && CMD="dpkg-query --show --showformat=\${Package}\n"
191 192 193 194 195 196
			;;
		*)
			fatal "Do not know command for query file package"
			;;
	esac

197
	docmd $CMD $@
198 199
}

200 201 202 203 204
# hack: dpkg -W will print names for removed packages too (until newest Ubuntu)
__epm_query_dpkg_check()
{
	local i
	for i in $@ ; do
Vitaly Lipatov's avatar
Vitaly Lipatov committed
205
		a='' dpkg -s $i >/dev/null 2>/dev/null || return
206 207 208 209
	done
	return 0
}

210 211 212 213
__epm_query_name()
{
	local CMD

214
	[ -z "$*" ] && return
215 216

	case $PMTYPE in
217
		*-rpm)
218 219
			CMD="rpm -q"
			;;
Vitaly Lipatov's avatar
Vitaly Lipatov committed
220
		*-dpkg)
221
			#docmd dpkg -l $@ | grep "^ii"
222 223 224 225
			#CMD="dpkg-query -W --showformat=\${Package}-\${Version}\n"
			docmd dpkg-query -W "--showformat=\${Package}-\${Version}\n" $@ || return
			__epm_query_dpkg_check $@ || return
			return
226 227
			;;
		npackd)
Vitaly Lipatov's avatar
Vitaly Lipatov committed
228
			docmd "npackdcl path --package=$1"
229 230 231 232
			return
			;;
		conary)
			CMD="conary query"
233
			;;
234 235 236 237 238 239 240 241
		#homebrew)
		#	showcmd "brew info $1"
		#	local HBRESULT
		#	HBRESULT="$(brew info "$1" 2>/dev/null)" || return
		#	echo "$HBRESULT" | grep -q "Not installed" && return 1
		#	echo "$1"
		#	return 0
		#	;;
242 243 244 245
		pacman)
			docmd pacman -Q $@
			return
			;;
246 247 248 249
		# TODO: need to print name if exists
		#pkgng)
		#	CMD="pkg info -e"
		#	;;
250
		# Note: slackpkg info pkgname
251
		*)
252
			# default slow workaround
253
			_query_via_packages_list $@
254 255 256 257
			return
			;;
	esac

258
	docmd $CMD $@
259 260
}

261 262 263 264 265 266 267 268 269 270 271
__epm_query_shortname()
{
	local CMD

	[ -z "$*" ] && return

	case $PMTYPE in
		*-rpm)
			CMD="rpm -q --queryformat %{name}\n"
			;;
		*-dpkg)
272 273 274 275
			#CMD="dpkg-query -W --showformat=\${Package}\n"
			docmd dpkg-query -W "--showformat=\${Package}\n" $@ || return
			__epm_query_dpkg_check $@ || return
			return
276 277
			;;
		npackd)
Vitaly Lipatov's avatar
Vitaly Lipatov committed
278
			docmd "npackdcl path --package=$1"
279 280 281 282 283 284
			return
			;;
		conary)
			CMD="conary query"
			;;
		homebrew)
Vitaly Lipatov's avatar
Vitaly Lipatov committed
285 286
			docmd brew info "$1" >/dev/null 2>/dev/null && echo "$1" && return
			return 1
287
			;;
288 289 290 291 292 293
		# TODO: check status
		#pacman)
		#	docmd pacman -Q $@ | sed -e "s| .*||g"
		#	return
		#	;;

294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
		# TODO: need to print name if exists
		#pkgng)
		#	CMD="pkg info -e"
		#	;;
		# Note: slackpkg info pkgname
		*)
			# default slow workaround
			_shortquery_via_packages_list $@
			return
			;;
	esac

	docmd $CMD $@
}

309 310 311
# check if pkg is installed
is_installed()
{
312
	__epm_query_shortname "$@" >/dev/null 2>/dev/null
313 314
	# broken way to recursive call here (overhead!)
	#epm installed $@ >/dev/null 2>/dev/null
315
}
316

317 318 319 320 321
# fill pkg_installed and pkg_noninstalled
separate_installed()
{
	pkg_installed=
	pkg_noninstalled=
Vitaly Lipatov's avatar
Vitaly Lipatov committed
322
	for i in "$@" ; do
323 324 325 326
		is_installed $i && pkg_installed="$pkg_installed $i" || pkg_noninstalled="$pkg_noninstalled $i"
	done
}

Danil Mikhailov's avatar
Danil Mikhailov committed
327 328
epm_query()
{
Vitaly Lipatov's avatar
Vitaly Lipatov committed
329
	[ -n "$pkg_filenames" ] || fatal "Query: missing package(s) name"
330 331

	__epm_query_file $pkg_files || return
Danil Mikhailov's avatar
Danil Mikhailov committed
332

333
	if [ -n "$short" ] ; then
Vitaly Lipatov's avatar
Vitaly Lipatov committed
334
		# shellcheck disable=SC2046
335 336
		__epm_query_shortname $(print_name $pkg_names) || return
	else
Vitaly Lipatov's avatar
Vitaly Lipatov committed
337
		# shellcheck disable=SC2046
338 339
		__epm_query_name $(print_name $pkg_names) || return
	fi
Danil Mikhailov's avatar
Danil Mikhailov committed
340
}