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

20 21 22
__icons_res_list="apps scalable symbolic 8x8 14x14 16x16 20x20 22x22 24x24 28x28 32x32 36x36 42x42 45x45 48x48 64 64x64 72x72 96x96 128x128 144x144 160x160 192x192 256x256 256x256@2x 480x480 512 512x512 1024x1024"
__icons_type_list="actions animations apps categories devices emblems emotes filesystems intl mimetypes places status stock"

23 24
__get_icons_hicolor_list()
{
25
    local i j
26
    for i in ${__icons_res_list} ; do
27
        echo "/usr/share/icons/hicolor/$i"
28
        for j in ${__icons_type_list}; do
29 30
            echo "/usr/share/icons/hicolor/$i/$j"
        done
31 32 33
    done
}

34 35 36 37 38 39 40 41 42 43 44
__get_icons_gnome_list()
{
    local i j
    for i in ${__icons_res_list} ; do
        echo "/usr/share/icons/gnome/$i"
        for j in ${__icons_type_list}; do
            echo "/usr/share/icons/gnome/$i/$j"
        done
    done
}

45 46 47 48 49 50 51 52 53 54
# args: pkgname buildroot spec
__fix_spec()
{
    local pkgname="$1"
    local buildroot="$2"
    local spec="$3"
    local i

    # drop forbidded paths
    # https://bugzilla.altlinux.org/show_bug.cgi?id=38842
55
    for i in / /etc /etc/init.d /etc/systemd /bin /opt /usr /usr/bin /usr/lib /usr/lib64 /usr/share /usr/share/doc /var /var/log /var/run \
56
            /etc/cron.daily /usr/share/icons/usr/share/pixmaps /usr/share/man /usr/share/man/man1 /usr/share/appdata /usr/share/applications /usr/share/menu \
57 58
            /usr/share/mime /usr/share/mime/packages \
            /usr/share/icons/gnome $(__get_icons_gnome_list) \
59
            /usr/share/icons/hicolor $(__get_icons_hicolor_list) ; do
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
        sed -i \
            -e "s|/\./|/|" \
            -e "s|^%dir[[:space:]]\"$i/*\"$||" \
            -e "s|^%dir[[:space:]]$i/*$||" \
            -e "s|^\"$i/*\"$||" \
            -e "s|^$i/*$||" \
            $spec
    done

    # commented out: conflicts with already installed package
    # drop %dir for existed system dirs
    #for i in $(grep '^%dir "' $spec | sed -e 's|^%dir  *"\(.*\)".*|\1|' ) ; do #"
    #    echo "$i" | grep -q '^/opt/' && continue
    #    [ -d "$i" ] && [ -n "$verbose" ] && echo "drop dir $i from packing, it exists in the system"
    #done

    # replace dir "/path/dir" -> %dir /path/dir
    grep '^"/' $spec | sed -e 's|^"\(/.*\)"$|\1|' | while read i ; do
        # add dir as %dir in the filelist
        if [ -d "$buildroot$i" ] ; then
            subst "s|^\(\"$i\"\)$|%dir \1|" $spec
        #else
        #    subst 's|^\("'$i'"\)$|\1|' $spec
        fi
    done

}

88 89 90 91 92
has_repack_script()
{
    local repackcode="$EPM_REPACK_SCRIPTS_DIR/$1.sh"
    [ -s "$repackcode" ]
}
93 94 95 96 97 98

# args: pkgname buildroot spec
__apply_fix_code()
{
    local repackcode="$EPM_REPACK_SCRIPTS_DIR/$1.sh"
    [ -s "$repackcode" ] || return
99 100
    [ -f "$repackcode.rpmnew" ] && warning "There is .rpmnew file(s) in $EPM_REPACK_SCRIPTS_DIR dir. The pack script can be outdated."

101
    shift
102
    [ "$PROGDIR" = "/usr/bin" ] && SCPATH="$PATH" || SCPATH="$PROGDIR:$PATH"
103
    local bashopt=''
104
    [ -n "$debug" ] && bashopt='-x'
105
    ( unset EPMCURDIR ; export PATH=$SCPATH ; docmd $CMDSHELL $bashopt $repackcode "$1" "$2" "$3" "$4" "$5" ) || fatal "There is an error from $repackcode script"
106 107 108 109 110
}

__create_rpmmacros()
{
    cat <<EOF >$HOME/.rpmmacros
111 112
%_topdir    $HOME/RPM
%_tmppath    $TMPDIR
113

114 115 116
%packager    EPM <support@eepm.ru>
%_vendor    EEPM
%_gpg_name    support@etersoft.ru
117
# TODO: use special user for repack (instead of root of local user)
118
%_allow_root_build    1
119
EOF
120
    remove_on_exit "$HOME/.rpmmacros"
121 122
}

123
# will set RPMBUILD
124
__assure_exists_rpmbuild()
125
{
126 127 128 129 130 131 132 133
    # checking both if they already installed
    RPMBUILD=/usr/bin/eepm-rpmbuild
    if [ -x $RPMBUILD ] ; then
        info "will use eepm-rpmbuild for rpm packing"
        export EPM_RPMBUILD=$RPMBUILD
        return
    fi

134 135 136
    RPMBUILD=/usr/bin/rpmbuild
    [ -x "$RPMBUILD" ] && return

137 138

    # try install eepm-rpm-build
139
    RPMBUILD=/usr/bin/eepm-rpmbuild
140
    try_assure_exists $RPMBUILD eepm-rpm-build
141 142

    if [ -x $RPMBUILD ] ; then
143
        info "will use eepm-rpmbuild for rpm packing"
144 145 146 147
        export EPM_RPMBUILD=$RPMBUILD
        return
    fi

148 149

    # return to the default
150
    RPMBUILD=/usr/bin/rpmbuild
151 152 153 154 155 156 157 158 159 160

    # TODO: check for all systems
    case $PKGFORMAT in
        rpm)
            assure_exists $RPMBUILD rpm-build
            ;;
        deb)
            assure_exists $RPMBUILD rpm
            ;;
    esac
161
}
162

163
# will fill repacked_pkg var
164 165
__epm_repack_to_rpm()
{
166
    local pkg="$1"
167 168

    # Note: install epm-repack for static (package based) dependencies
169
    assure_exists alien
170
    assure_exists fakeroot
171

172
    # will set RPMBUILD
173
    __assure_exists_rpmbuild
174

175 176
    umask 022

177
    # TODO: improve
178
    if echo "$pkg" | grep -q "\.deb" ; then
179
        assure_exists dpkg
180 181 182 183 184 185 186
        # TODO: Для установки требует: /usr/share/debconf/confmodule но пакет не может быть установлен
        # assure_exists debconf
    fi

    local alpkg
    local abspkg
    local tmpbuilddir
187 188 189

    repacked_pkg=''

190 191 192 193 194 195
        # TODO: keep home?
        HOME="$(mktemp -d --tmpdir=$BIGTMPDIR)" || fatal
        remove_on_exit $HOME
        export HOME
        __create_rpmmacros

196 197 198 199 200 201 202 203
        tmpbuilddir=$HOME/$(basename $pkg).tmpdir
        mkdir $tmpbuilddir
        abspkg="$(realpath $pkg)"
        info ""
        info "Repacking $abspkg to local rpm format (inside $tmpbuilddir) ..."

        alpkg=$(basename $pkg)
        # don't use abs package path: copy package to temp dir and use there
204
        cp -l $verbose $pkg $tmpbuilddir/../$alpkg 2>/dev/null || cp $verbose $pkg $tmpbuilddir/../$alpkg || fatal
205 206

        cd $tmpbuilddir/../ || fatal
207
        # fill alpkg and SUBGENERIC
208
        __prepare_source_package "$(realpath $alpkg)"
209 210
        cd $tmpbuilddir/ || fatal

211 212 213 214
        local fakeroot
        fakeroot=''
        ! is_root && is_command fakeroot && fakeroot='fakeroot'

215
        if [ -n "$verbose" ] ; then
216
            docmd $fakeroot alien --generate --to-rpm $verbose $scripts "../$alpkg" || fatal
217
        else
218 219
            showcmd $fakeroot alien --generate --to-rpm $scripts "../$alpkg"
            a='' $fakeroot alien --generate --to-rpm $scripts "../$alpkg" >/dev/null || fatal
220 221
        fi

222 223
        # remove all empty dirs (hack against broken dpkg with LF in the end of line) (hack for linux_pantum.deb)
        rmdir * 2>/dev/null
224

225 226 227
        local subdir="$(echo *)"
        [ -d "$subdir" ] || fatal "can't find subdir in $(pwd)"

228 229
        local buildroot="$tmpbuilddir/$subdir"

230 231 232
        # for tarballs fix permissions (ideally fix in pack.d/generic-tar.sh, but there is tar repacking only)
        [ "$SUBGENERIC" = "tar" ] && chmod $verbose -R a+rX $buildroot/*

233
        # detect spec and move to prev dir
234
        local spec="$(echo $buildroot/*.spec)"
235 236 237
        [ -s "$spec" ] || fatal "Can't find spec $spec"
        mv $spec $tmpbuilddir || fatal
        spec="$tmpbuilddir/$(basename "$spec")"
238

239 240
        local pkgname="$(grep "^Name: " $spec | sed -e "s|Name: ||g" | head -n1)"

Vitaly Lipatov's avatar
Vitaly Lipatov committed
241
        # run generic scripts and repack script for the pkg
242
        cd $buildroot || fatal
243

244
        __fix_spec $pkgname $buildroot $spec
Vitaly Lipatov's avatar
Vitaly Lipatov committed
245
        __apply_fix_code "generic"             $buildroot $spec $pkgname $abspkg $SUBGENERIC
246
        __apply_fix_code "generic-$SUBGENERIC" $buildroot $spec $pkgname $abspkg
Vitaly Lipatov's avatar
Vitaly Lipatov committed
247
        __apply_fix_code $pkgname              $buildroot $spec $pkgname $abspkg
248 249 250
        if ! has_repack_script $pkgname ; then
            __apply_fix_code "generic-default" $buildroot $spec $pkgname $abspkg
        fi
251
        __fix_spec $pkgname $buildroot $spec
252
        cd - >/dev/null
253

254 255 256 257 258 259 260 261 262
        # reassign package name (could be renamed in fix scripts)
        pkgname="$(grep "^Name: " $spec | sed -e "s|Name: ||g" | head -n1)"

        if [ -n "$EEPM_INTERNAL_PKGNAME" ] ; then
            if ! estrlist contains "$pkgname" "$EEPM_INTERNAL_PKGNAME" ; then
                fatal "Some bug: the name of the repacking package ($pkgname) differs with the package name ($EEPM_INTERNAL_PKGNAME) from play.d script."
            fi
        fi

263 264
        TARGETARCH=$(epm print info -a | sed -e 's|^x86$|i586|')

265
        showcmd $RPMBUILD --buildroot $buildroot --target $TARGETARCH -bb $spec
266
        if [ -n "$verbose" ] ; then
267
            a='' $RPMBUILD --buildroot $buildroot --target $TARGETARCH -bb $spec || fatal
268
        else
269
            a='' $RPMBUILD --buildroot $buildroot --target $TARGETARCH -bb $spec >/dev/null || fatal
270
        fi
271

272 273 274 275
        # remove copy of source binary package (don't mix with generated)
        rm -f $tmpbuilddir/../$alpkg
        local repacked_rpm="$(realpath $tmpbuilddir/../*.rpm)"
        if [ -s "$repacked_rpm" ] ; then
276
            remove_on_exit "$repacked_rpm"
277
            repacked_pkg="$repacked_rpm"
278
        else
279
            warning "Can't find converted rpm for source binary package '$pkg' (got $repacked_rpm)"
280
        fi
281
        cd $EPMCURDIR >/dev/null
282 283 284 285

    true
}