Last active
July 22, 2022 18:42
-
-
Save ruario/4ef8ca34fb4d6c8eccc0e9b10c86d672 to your computer and use it in GitHub Desktop.
This script will convert an official Vivaldi Linux package into Slackware package format (it should work on any Linux distro, under macOS or even using BusyBox tools)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh -eu | |
# This script will convert an official Vivaldi Linux package into Slackware | |
# package format. | |
# | |
# To use, just run this script, followed by the name of the Vivaldi package. | |
# | |
# Note: Since this script was created with Slackware 15 and above in mind, it | |
# uses the new 'douninst.sh' script to clear down any proprietary media libs | |
# fetched by 'update-ffmpeg' during post install. | |
# | |
# If you run 14.2, the UNINSTALL-Slackware-14.2.txt in the doc directory | |
# (also mentioned below) explains any post cleanup you might wish to perform. | |
# Take the first command line argument as the name of the Vivaldi package or | |
# if nothing is provided, look in the current working directory for the most | |
# recent file named like a Vivaldi package | |
if [ -n "${1:-}" ]; then | |
VIVPKG="$1" | |
else | |
VIVPKG="$(ls -dt vivaldi-s* 2>/dev/null | grep -m1 '\.\(deb\|rpm\)$' 2>/dev/null ||:)" | |
if [ -n "${VIVPKG:-}" ]; then | |
echo "Found \"$VIVPKG\" as a potential source package." | |
else | |
echo "No Vivaldi package was found in the current working directory" >&2 | |
exit 1 | |
fi | |
fi | |
# Check that the package is correctly named | |
if ! echo "${VIVPKG##*/}" | grep -qxE "vivaldi-(stable|snapshot)[_-](([0-9]+\.){3}[0-9]+)-[0-9]+[_\.](aarch64|amd64|arm64|armhf|armv.hl|x86_64)\.(rpm|deb)"; then | |
echo "\"${VIVPKG##*/}\" is oddly named." >&2 | |
echo "Specify the name of the package you wish to convert as the first argument to this script." >&2 | |
exit 1 | |
fi | |
# Check that the package is present and readable on the filesystem | |
if ! [ -r "$VIVPKG" ]; then | |
echo "\"${VIVPKG##*/}\" cannot be accessed." >&2 | |
exit 1 | |
fi | |
# Set some basic variables | |
case "$VIVPKG" in | |
*rpm) | |
PKGNAME="$(echo "${VIVPKG##*/}" | cut -d- -f1-2)" | |
VERSION="$(echo "${VIVPKG##*/}" | cut -d- -f3)" | |
ARCH="$(echo ${VIVPKG%.rpm} | cut -d. -f5)" | |
;; | |
*deb) | |
PKGNAME="$(echo "${VIVPKG##*/}" | cut -d_ -f1)" | |
VERSION="$(echo "${VIVPKG##*/}" | cut -d_ -f2 | cut -d- -f1)" | |
ARCH="$(echo ${VIVPKG%.deb} | cut -d_ -f3)" | |
;; | |
esac | |
case $ARCH in | |
aarch64|arm64) ARCH=arm64 ;; | |
amd64) ARCH=x86_64 ;; | |
arm*) ARCH=arm ;; | |
esac | |
BUILD=${BUILD:-1} | |
TAG=${TAG:-ruario} | |
PKGTYPE="${PKGTYPE:-tbz}" | |
OUTPUT="$PWD" | |
PACKAGE="$OUTPUT/$PKGNAME-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE" | |
REPACKDIR="$(mktemp -d -t vivaldi-repackage.XXXXXX)/pkg" | |
# This function can be used in place of Slackware's makepkg, with the added | |
# bonuses that it is able to make packages with root owned files when run as | |
# a regular user and it will work on macOS. It will also work under BusyBox | |
# (if you are root). | |
mkpkg() { | |
if find * -type l | grep -qm1 .; then | |
mkdir -p install | |
find * -type l -print0 |\ | |
xargs -0 -I@ sh -c 'for l in "@";do printf "(*cd*${l%/*}*;*"; echo "rm*-rf*${l##*/}*)"; printf "(*cd*${l%/*}*;*"; echo "ln*-sf*"$(readlink "$l")"*${l##*/}*)"; done' |\ | |
sed 's/ /\\ /g;s/\*/ /g' > install/symlinks | |
find * -type l -delete | |
if [ -f "install/doinst.sh" ]; then | |
printf '\n' | cat - install/doinst.sh >> install/symlinks | |
fi | |
mv install/symlinks install/doinst.sh | |
fi | |
case "$1" in | |
*tbz) | |
if command -v lbzip2 >/dev/null 2>&1; then | |
COMPRESSOR=lbzip2 | |
else | |
COMPRESSOR=bzip2 | |
fi | |
;; | |
*tgz) | |
if command -v pigz >/dev/null 2>&1; then | |
COMPRESSOR=pigz | |
else | |
COMPRESSOR=gzip | |
fi | |
;; | |
*txz) | |
if command -v xz >/dev/null 2>&1; then | |
COMPRESSOR='xz -T0' | |
# We might still be able to make this work on macOS | |
elif tar --version | grep -q 'libarchive.*liblzma'; then | |
LIBARCHIVEXZ=J | |
COMPRESSOR='cat -' | |
else | |
echo "No XZ compressor found" >&2 | |
exit 1 | |
fi | |
;; | |
*) | |
echo "Unknown compression type" >&2 | |
exit 1 | |
;; | |
esac | |
if tar --version | grep -q libarchive; then | |
(echo ./; find *) | tar --no-recursion -T- --uname root --gname root -c${LIBARCHIVEXZ:-}f- | $COMPRESSOR > "$1" | |
else | |
# I would like this script to work on any system but BusyBox tar does not | |
# allow changing permissions of the fly. However if the script is run as | |
# root it should work in a pure BusyBox environment as well. | |
if tar --version | grep -q busybox; then | |
if [ "$(whoami)" = 'root' ];then | |
chown -R root:root . | |
else | |
echo "To run this under BusyBox, you must be root" >&2 | |
cd "$OUTPUT" | |
rm -r "$REPACKDIR" | |
exit 1 | |
fi | |
else | |
TAR_OWNERSHIP="--owner root --group root" | |
fi | |
(echo ./; find *) | tar --no-recursion -T- ${TAR_OWNERSHIP:-} -cf- | $COMPRESSOR > "$1" | |
fi | |
echo "Slackware package \"${1##*/}\" created." | |
} | |
# Make the basic directory structure | |
mkdir -p "$REPACKDIR/install" "$REPACKDIR/var/lib/pkgtools/douninst.sh" "$REPACKDIR/usr/doc/$PKGNAME-$VERSION" | |
# Add a this script to doc directory | |
cat "$0" > "$REPACKDIR/usr/doc/$PKGNAME-$VERSION/${0##*/}" | |
# Extract the to the repacking directory. | |
correct_offset () { | |
# Some strings implementations output the offset as octal, test for this | |
# and convert to decimal if needed (note: '-td' is not always available) | |
[ "$(printf 'popular\novel' | strings -o | sed -n '/v/s/ *\([0-9][0-9]*\) .*/\1/p')" -eq 10 ] && XZ_OFFSET="$(printf '%d' "0$XZ_OFFSET")" | |
} | |
if [ "${VIVPKG##*.}" = 'rpm' ]; then | |
if command -v bsdtar >/dev/null 2>&1; then | |
bsdtar Cfx "$REPACKDIR" "$VIVPKG" ./opt ./usr | |
else | |
XZ_OFFSET="$(strings -o "$VIVPKG" | grep -Fm1 7zXZ | sed 's/ *\([0-9][0-9]*\) .*/\1/')" | |
correct_offset | |
tail -c+"$XZ_OFFSET" "$VIVPKG" | xz -d | (cd "$REPACKDIR" && cpio --quiet -id ./opt\* ./usr\*) | |
fi | |
else | |
if command -v bsdtar >/dev/null 2>&1; then | |
bsdtar xOf "$VIVPKG" data.tar.xz | bsdtar Cfx "$REPACKDIR" - ./opt ./usr | |
else | |
XZ_OFFSET="$(strings -o "$VIVPKG" | grep -Fm2 7zXZ | tail -n1 | sed 's/ *\([0-9][0-9]*\) .*/\1/')" | |
correct_offset | |
tail -c+"$XZ_OFFSET" "$VIVPKG" | xz -d 2>/dev/null | tar -C "$REPACKDIR" -xf - ./opt ./usr | |
fi | |
# These only contain Debian specific stuff | |
rm -rf "$REPACKDIR/usr/share/doc" "$REPACKDIR/usr/share/menu" "$REPACKDIR/opt/${PKGNAME%-stable}/cron" | |
fi | |
# Add a 'vivaldi' symlink for stable | |
cd "$REPACKDIR" | |
[ "${PKGNAME%-stable}" = 'vivaldi' ] && ln -s /opt/${PKGNAME%-stable}/${PKGNAME%-stable} usr/bin/${PKGNAME%-stable} | |
# Setup icons for use with the .desktop file. | |
for PNG in opt/${PKGNAME%-stable}/product_logo_*.png; do | |
PNG_SIZE="$(echo $PNG | grep -o '[0-9]\+')" | |
mkdir -p usr/share/icons/hicolor/${PNG_SIZE}x$PNG_SIZE/apps | |
ln -s /$PNG usr/share/icons/hicolor/${PNG_SIZE}x$PNG_SIZE/apps/${PKGNAME%-stable}.png | |
done | |
# Add various package meta-data | |
cat <<EOF>install/slack-desc | |
$PKGNAME: $PKGNAME (web browser) | |
$PKGNAME: | |
$PKGNAME: Experience the web in a whole new way with Vivaldi. | |
$PKGNAME: | |
$PKGNAME: Vivaldi is a browser that has the features you need, a style that fits | |
$PKGNAME: and values you can stand by. Your browser matters. Take control with | |
$PKGNAME: Vivaldi. | |
$PKGNAME: | |
$PKGNAME: Home Page: https://vivaldi.com | |
$PKGNAME: | |
$PKGNAME: | |
EOF | |
cat <<EOF>install/doinst.sh | |
if [ -x /usr/bin/update-desktop-database ]; then | |
/usr/bin/update-desktop-database -q usr/share/applications >/dev/null 2>&1 | |
fi | |
# Installs a third party libffmpeg.so that supports proprietary media | |
if [ -x /opt/${PKGNAME%-stable}/update-ffmpeg ]; then | |
nohup /opt/${PKGNAME%-stable}/update-ffmpeg >/dev/null 2>&1 & | |
fi | |
EOF | |
cat <<EOF>var/lib/pkgtools/douninst.sh/$PKGNAME-$VERSION-$ARCH-$BUILD$TAG | |
# Remove any lib fetched by update-ffmpeg, when doinst.sh was first run | |
if ls /var/opt/${PKGNAME%-stable}/media-codecs-*/libffmpeg.so >/dev/null 2>&1; then | |
rm /var/opt/${PKGNAME%-stable}/media-codecs-*/libffmpeg.so | |
fi | |
if [ -d /var/opt/${PKGNAME%-stable} ]; then | |
# This removes directory trees that are empty or only populated by other | |
# empty directories. | |
find /var/opt/${PKGNAME%-stable} -depth -type d -empty -exec rmdir {} \; | |
fi | |
EOF | |
chmod +x var/lib/pkgtools/douninst.sh/$PKGNAME-$VERSION-$ARCH-$BUILD$TAG | |
# Add a note about uninstall on Slackware 14.2 | |
cat <<EOF>"$REPACKDIR/usr/doc/$PKGNAME-$VERSION/UNINSTALL-Slackware-14.2.txt" | |
Since '${0##*/}' was created with Slackware 15 and above in mind, it uses the | |
new 'douninst.sh' script to clear down any proprietary media libs fetched by | |
'update-ffmpeg' during post install. | |
If you run ≤14.2, make a copy of the douninst.sh *before* uninstall: | |
cp /var/lib/pkgtools/douninst.sh/$PKGNAME-$VERSION-$ARCH-$BUILD$TAG . | |
Then simply run it as root after uninstall. | |
(If you forget it is not the end of the world, you will just potentially | |
leave behind a small file [libffmpeg.so] under /var/opt/vivaldi*) | |
EOF | |
# Make sure the file permissions are ok | |
chmod -R u+w,go+r-w,a-s . | |
# Create the Slackware package | |
mkpkg "$PACKAGE" | |
# Cleanup | |
cd "$OUTPUT" | |
rm -r "$REPACKDIR" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment