epm-query 9.81 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
# pkg suffix
__print_with_arch_suffix()
{
26 27 28 29 30 31 32 33 34
    local pkg="$1"
    local suffix="$2"
    [ -n "$pkg" ] || return 1
    # do not change if some suffix already exists
    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
    echo "$pkg$suffix"
35
}
Vitaly Lipatov's avatar
Vitaly Lipatov committed
36

37 38 39
# add suffix .x86_64 if we have 64 arch
exp_with_arch_suffix()
{
40 41
    local suffix

42
    [ "$DISTRARCH" = "x86_64" ] || { cat ; return ; }
43 44 45 46 47
    [ "$DISTRNAME" = "ROSA" ] &&  { cat ; return ; }

    # TODO: it is ok for ALT rpm to remove with this suffix
    # TODO: separate install and remove?
    case $PMTYPE in
48
        yum-rpm|dnf-rpm|dnf5-rpm)
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
            suffix=".x86_64"
            ;;
        *)
            cat
            return
            ;;
    esac

    # TODO: use estrlist or some function to do it
    local pkg
    for pkg in $(cat) ; do
        local p
        # check only packages without arch
        p="$(__print_with_arch_suffix "$pkg" .i686)" || { echo "$pkg" ; continue ; }
        # 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"
    done
67 68 69
}


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

# TODO: combine with -qa (the difference only in return status now)
80
_shortquery_via_packages_list()
81
{
82 83 84 85 86 87 88 89 90 91 92
    local res=1
    local grepexp
    local firstpkg=$1
    shift

    grepexp=$(_get_grep_exp $firstpkg)

    # TODO: we miss status due grep
    # Note: double call due stderr redirect
    # Note: we use short=1 here due grep by ^name$
    # separate first line for print out command
93
    (short=1 epm_packages $firstpkg | grep -- "$grepexp") && res=0 || res=1
94 95 96 97

    local pkg
    for pkg in "$@" ; do
        grepexp=$(_get_grep_exp $pkg)
98
        (short=1 epm_packages $pkg 2>/dev/null) | grep -- "$grepexp" || res=1
99 100 101 102
    done

    # TODO: print in query (for user): 'warning: package $pkg is not installed'
    return $res
103 104
}

105 106 107 108
# Note: modified from _shortquery_via_packages_list
# TODO: non optimal double epm packages call
_query_via_packages_list()
{
109 110 111 112 113 114 115 116 117 118 119 120
    local res=1
    local grepexp
    local firstpkg=$1
    shift

    grepexp=$(_get_grep_exp $firstpkg)

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

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

    return $res
130 131
}

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

    case $PMTYPE in
        apt-rpm)
            # use # as delimeter for apt
            local pkg
            pkg=$(rpm -q --queryformat "%{NAME}=%{SERIAL}:%{VERSION}-%{RELEASE}\n" -- $1)
            # for case if serial is missed
            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
            ;;
149
        yum-rpm|dnf-rpm|dnf5-rpm)
150 151 152 153 154 155 156 157 158 159 160 161
            # just use strict version with Epoch and Serial
            local pkg
            #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)
            pkg=$(rpm -q --queryformat "%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n" -- $1)
            echo $pkg
            return
            ;;
        *)
            return 1
            ;;
    esac
162 163 164 165 166 167
}

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

181 182
__epm_query_file()
{
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
    local CMD

    [ -z "$*" ] && return

    case $PMTYPE in
        *-rpm)
            CMD="rpm -qp"
            [ -n "$short" ] && CMD="rpm -qp --queryformat %{name}\n"
            ;;
        *-dpkg)
            CMD="dpkg-deb --show --showformat=\${Package}-\${Version}\n"
            [ -n "$short" ] && CMD="dpkg-query --show --showformat=\${Package}\n"
            ;;
        *)
            fatal "Do not know command for query file package"
            ;;
    esac

    docmd $CMD -- $@
202 203
}

204 205 206
# hack: dpkg -W will print names for removed packages too (until newest Ubuntu)
__epm_query_dpkg_check()
{
207 208 209 210 211
    local i
    for i in $@ ; do
        a='' dpkg -s $i >/dev/null 2>/dev/null || return
    done
    return 0
212 213
}

214 215
__epm_query_name()
{
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
    local CMD

    [ -z "$*" ] && return

    case $PMTYPE in
        *-rpm)
            CMD="rpm -q"
            ;;
        *-dpkg)
            #docmd dpkg -l $@ | grep "^ii"
            #CMD="dpkg-query -W --showformat=\${Package}-\${Version}\n"
            docmd dpkg-query -W "--showformat=\${Package}-\${Version}\n" -- $@ || return
            __epm_query_dpkg_check $@ || return
            return
            ;;
        npackd)
            docmd npackdcl path --package=$1
            return
            ;;
        conary)
            CMD="conary query"
            ;;
        eopkg)
            showcmd eopkg blame $1
            local str
            str="$(a= eopkg blame $1 | grep "^Name")"
            [ -n "$str" ] || return 1
            echo "$str" | sed -e "s|Name[[:space:]]*: \(.*\), version: \(.*\), release: \(.*\)|\1-\2-\3|"
            return
            ;;
        #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
        #    ;;
        pacman)
            docmd pacman -Q $@
            return
            ;;
        # TODO: need to print name if exists
        #pkgng)
        #    CMD="pkg info -e"
        #    ;;
        # Note: slackpkg info pkgname
        *)
            # default slow workaround
            _query_via_packages_list $@
            return
            ;;
    esac

    docmd $CMD $@
271 272
}

273 274
__epm_query_shortname()
{
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
    local CMD

    [ -z "$*" ] && return

    case $PMTYPE in
        *-rpm)
            showcmd rpm -q --queryformat '%{name}\n' -- $@
            a='' rpm -q --queryformat '%{name}\n' -- $@
            return
            ;;
        *-dpkg)
            #CMD="dpkg-query -W --showformat=\${Package}\n"
            docmd dpkg-query -W "--showformat=\${Package}\n" -- $@ || return
            __epm_query_dpkg_check $@ || return
            return
            ;;
        npackd)
            docmd npackdcl path --package=$1
            return
            ;;
        conary)
            CMD="conary query"
            ;;
        eopkg)
            showcmd eopkg blame $1
            local str
            str="$(a= eopkg blame $1 | grep "^Name")"
            [ -n "$str" ] || return 1
            echo "$str" | sed -e "s|Name[[:space:]]*: \(.*\), version: \(.*\), release: \(.*\)|\1|"
            return
            ;;
        homebrew)
            docmd brew info "$1" >/dev/null 2>/dev/null && echo "$1" && return
            return 1
            ;;
        # TODO: check status
        #pacman)
        #    docmd pacman -Q $@ | sed -e "s| .*||g"
        #    return
        #    ;;

        # 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 $@
329 330
}

331 332 333 334

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

335 336 337
# check if pkg is installed
is_installed()
{
338
    (quiet=1 __epm_query_name "$@") >/dev/null 2>/dev/null
339
}
340

341 342 343 344 345
filter_pkgnames_to_short()
{
    local names="$(cat)"
    __epm_query_shortname $names
}
346

Danil Mikhailov's avatar
Danil Mikhailov committed
347 348
epm_query()
{
349
    [ -n "$pkg_filenames" ] || fatal "Query: package name is missed"
350

351
    __epm_query_file $pkg_files || return
Danil Mikhailov's avatar
Danil Mikhailov committed
352

353 354 355 356 357 358 359
    if [ -n "$short" ] ; then
        # shellcheck disable=SC2046
        __epm_query_shortname $(print_name $pkg_names) || return
    else
        # shellcheck disable=SC2046
        __epm_query_name $(print_name $pkg_names) || return
    fi
Danil Mikhailov's avatar
Danil Mikhailov committed
360
}