epm-repack 6.84 KB
Newer Older
1 2
#!/bin/sh
#
3 4
# Copyright (C) 2017-2018, 2020  Etersoft
# Copyright (C) 2017-2018, 2020  Vitaly Lipatov <lav@etersoft.ru>
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
#
# 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
# (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
# GNU Affero General Public License for more details.
#
# 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/>.
#

load_helper epm-sh-altlinux
load_helper epm-assure
22
load_helper epm-status
23

24 25
[ -n "$EPM_REPACK_SCRIPTS_DIR" ] || EPM_REPACK_SCRIPTS_DIR="$CONFIGDIR/repack.d"

26
__epm_have_repack_rule()
27 28
{
    # FIXME: use real way (for any archive)
Vitaly Lipatov's avatar
Vitaly Lipatov committed
29
    local pkgname="$(epm print name for package "$1" 2>/dev/null)"
30 31 32 33 34
    local repackcode="$EPM_REPACK_SCRIPTS_DIR/$pkgname.sh"
    [ -s "$repackcode" ]
}

__epm_check_repack_rule()
35
{
36 37 38
    # skip repacking on non ALT systems
    [ "$BASEDISTRNAME" = "alt" ] || return 1

39 40 41 42
    local i
    for i in $* ; do
        # skip for packages built with repack
        epm_status_repacked "$i" && return 1
43

44
        __epm_have_repack_rule "$i" || return 1
45 46
    done
    return 0
47 48 49 50
}

__epm_check_if_needed_repack()
{
51
    __epm_check_repack_rule "$@" || return
52
    local pkgname="$(epm print name for package "$1")"
53
    warning "There is repack rule for '$pkgname' package. It is better install this package via 'epm install --repack' or 'epm play'."
54 55
}

56 57 58
# arg: rpm or deb
# fills split_replaced_pkgs with packages of that type
__epm_split_by_pkg_type()
59
{
60 61
    local type="$1"
    shift
62

63
    split_replaced_pkgs=''
64

65 66 67 68 69
    for pkg in "$@" ; do
        [ "$(get_package_type "$pkg")" = "$type" ] || return 1
        [ -e "$pkg" ] || fatal "Can't read $pkg"
        split_replaced_pkgs="$split_replaced_pkgs $pkg"
    done
70

71
    [ -n "$split_replaced_pkgs" ]
72 73 74
}


75 76
__check_stoplist()
{
77 78 79 80 81
    local pkg="$1"
    local alf="$CONFIGDIR/repackstoplist.list"
    [ -s "$alf" ] || return 1
    [ -n "$pkg" ] || return 1
    grep -E -q "^$1$" $alf
82 83
}

84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
__convert_packrule_to_regexp()
{
    local tmpalf
    tmpalf="$(mktemp)" || fatal
    # copied from eget's filter_glob
    # check man glob
    # remove commentы and translate glob to regexp
    grep -v "^[[:space:]]*#" "$1" | grep -v "^[[:space:]]*$" | sed -e "s|\*|.*|g" -e "s|?|.|g" >$tmpalf
    echo "$tmpalf"
}

# fill __PACKRULE if $1 in packrules.list
__check_packrule()
{
    local pkg="$1"
    local alf="$CONFIGDIR/packrules.list"
    [ -s "$pkg" ] || return 1
    [ -s "$alf" ] || return 1

    local tmpalf=$(__convert_packrule_to_regexp "$alf")
    remove_on_exit $tmpalf
    __PACKRULE="$(awk -v s="$pkg" 'BEGIN{FS=" "} s ~ $2  {print $1}' "$tmpalf")"
    rm $tmpalf
    [ -n "${__PACKRULE}" ]
    return
}
110

111 112
# arg: <package file>
# sets:
113
#   alpkg      - resulted package file name in the current dir
114 115 116 117 118 119 120 121 122
#   SUBGENERIC - name of generic file's extension
__prepare_source_package()
{
    local pkg="$1"

    alpkg=$(basename $pkg)

    # TODO: use func for get name from deb pkg
    # TODO: epm print name from deb package
Vitaly Lipatov's avatar
Vitaly Lipatov committed
123 124
    local pkgname="$(echo $alpkg | sed -e "s|_.*||")"

125
    # TODO: use stoplist only for deb?
Vitaly Lipatov's avatar
Vitaly Lipatov committed
126
    [ -z "$force" ] && __check_stoplist $pkgname && fatal "Please use official package instead of $alpkg repacking (It is not recommended to use --force to skip this checking."
127 128 129 130

    SUBGENERIC=''

    if rhas "$alpkg" "\.(rpm|deb)$" ; then
131
        # skip packing for supported directly: rpm and deb
132 133 134
        return
    fi

135 136 137
    # convert tarballs to tar (for alien)
    load_helper epm-pack

138
    # they will fill $returntarname
139 140 141 142

    if __check_packrule "$alpkg" ; then
        __epm_pack_run_handler ${__PACKRULE} "$pkg"
    elif rihas "$alpkg" "\.AppImage$" ; then
143 144
        # big hack with $pkg_urls_downloaded (it can be a list, not a single url)
        __epm_pack_run_handler generic-appimage "$pkg" "" "$pkg_urls_downloaded"
145
        SUBGENERIC='appimage'
146 147 148 149 150
    elif rhas "$alpkg" "\.snap$" ; then
        __epm_pack_run_handler generic-snap "$pkg"
        SUBGENERIC='snap'
    else
        __epm_pack_run_handler generic-tar "$pkg"
151
        SUBGENERIC='tar'
152 153
    fi

154 155 156
    # it is possible there are a few files, we don't support it
    [ -s "$returntarname" ] || fatal "Can't read result from pack: '$returntarname' is not a readable file."

157
    alpkg=$(basename $returntarname)
158
    # FIXME: looks like a hack with current dir
159 160 161
    if [ "$(pwd)" != "$(dirname "$returntarname")" ] ; then
        cp $verbose $returntarname $alpkg
        [ -r "$returntarname.eepm.yaml" ] && cp $verbose $returntarname.eepm.yaml $alpkg.eepm.yaml
162 163 164 165
    fi
}


166

167
# used in epm install
168
__epm_repack_single()
169
{
170
    local pkg="$1"
171 172 173
    case $PKGFORMAT in
        rpm)
            load_helper epm-repack-rpm
174
            __epm_repack_to_rpm "$pkg" || return
175 176
            ;;
        deb)
177 178
            if __epm_have_repack_rule "$pkg" ; then
                # we have repack rules only for rpm, so use rpm step in any case
179 180
                load_helper epm-repack-rpm
                load_helper epm-repack-deb
181 182 183
                __epm_repack_to_rpm "$pkg" || return
                [ -n "$repacked_pkg" ] || return
                __epm_repack_to_deb $repacked_pkg || return
184 185
            else
                load_helper epm-repack-deb
186
                __epm_repack_to_deb "$pkg" || return
187 188 189 190 191 192 193 194
            fi
            ;;
        *)
            fatal "$PKGFORMAT is not supported for repack yet"
            ;;
    esac

    return 0
195 196
}

197 198 199 200 201 202 203 204 205 206 207 208
# fill repacked_pkgs
__epm_repack()
{
    local pkg
    repacked_pkgs=''
    for pkg in $* ; do
        __epm_repack_single "$pkg" || fatal "Error with $pkg repacking."
        [ -n "$repacked_pkgs" ] && repacked_pkgs="$repacked_pkgs $repacked_pkg" || repacked_pkgs="$repacked_pkg"
    done
}


209 210
__epm_repack_if_needed()
{
211 212
    # return 1 if there is a package in host package format
    __epm_split_by_pkg_type $PKGFORMAT "$@" && return 1
213

214 215
    __epm_repack "$@"
    return 0
216
}
217

218 219 220 221 222
epm_repack()
{
    # if possible, it will put pkg_urls into pkg_files and reconstruct pkg_filenames
    if [ -n "$pkg_urls" ] ; then
        load_helper epm-download
223 224
        __download_pkg_urls
        pkg_urls=
225 226
    fi

227
    [ -n "$pkg_names" ] && warning "Can't find $pkg_names files"
228 229
    [ -z "$pkg_files" ] && info "Skip empty repack list" && return 22

230
    if __epm_repack $pkg_files && [ -n "$repacked_pkgs" ] ; then
231 232 233 234 235
        if [ -n "$install" ] ; then
            epm install $repacked_pkgs
            return
        fi

236
        cp $repacked_pkgs "$EPMCURDIR"
237
        if [ -z "$quiet" ] ; then
238 239
            echo
            echo "Adapted packages:"
240
            for i in $repacked_pkgs ; do
241
                echo "    $EPMCURDIR/$(basename "$i")"
242
            done
243
        fi
244 245 246
    fi

}