epm-query 7.76 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
__epm_get_hilevel_nameform()
{
	[ -n "$*" ] || return

	case $PMTYPE in
		apt-rpm)
			# use # as delimeter for apt
			local pkg
139 140
			pkg=$(rpm -q --queryformat "%{NAME}=%{SERIAL}:%{VERSION}-%{RELEASE}\n" -- $1)
			# for case if serial is missed
141
			echo $pkg | grep -q "(none)" && pkg=$(rpm -q --queryformat "%{NAME}#%{VERSION}-%{RELEASE}\n" -- $1)
142 143 144 145 146
			# HACK: can use only for multiple install packages like kernel
			echo $pkg | grep -q kernel || return 1
			echo $pkg
			return
			;;
147
		yum-rpm|dnf-rpm)
148 149
			# just use strict version with Epoch and Serial
			local pkg
150 151
			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)
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
			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
169 170
		# FIXME: where we use it? continue or pkg=$i?
		quiet=1 pkg=$(__epm_query_shortname "$i") || pkg="$i" #continue # drop not installed packages
171 172 173
		# 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
174
		__epm_get_hilevel_nameform "$i" || echo $pkg
175 176 177
	done
}

178 179 180 181
__epm_query_file()
{
	local CMD

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

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

198
	docmd $CMD -- $@
199 200
}

201 202 203 204 205
# 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
206
		a='' dpkg -s $i >/dev/null 2>/dev/null || return
207 208 209 210
	done
	return 0
}

211 212 213 214
__epm_query_name()
{
	local CMD

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

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

259
	docmd $CMD $@
260 261
}

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

	[ -z "$*" ] && return

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

297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
		# 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 $@
}

312 313 314 315

# keep here, all modules and epm-query use is_installed from epm-query
# see epm-installed

316 317 318
# check if pkg is installed
is_installed()
{
319
	(quiet=1 __epm_query_name "$@") >/dev/null 2>/dev/null
320
}
321

322

Danil Mikhailov's avatar
Danil Mikhailov committed
323 324
epm_query()
{
Vitaly Lipatov's avatar
Vitaly Lipatov committed
325
	[ -n "$pkg_filenames" ] || fatal "Query: package name is missed"
326 327

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

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