summaryrefslogtreecommitdiff
path: root/src/abslibre-tools/libredbdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/abslibre-tools/libredbdiff')
-rwxr-xr-xsrc/abslibre-tools/libredbdiff360
1 files changed, 360 insertions, 0 deletions
diff --git a/src/abslibre-tools/libredbdiff b/src/abslibre-tools/libredbdiff
new file mode 100755
index 0000000..09c7ad1
--- /dev/null
+++ b/src/abslibre-tools/libredbdiff
@@ -0,0 +1,360 @@
+#!/usr/bin/env bash
+name="Libredbdiff"
+
+# Copyright (C) 2014 Esteban Carnevale <alfplayer@mailoo.org>
+# Copyright (C) 2014 Luke Shumaker <lukeshu@sbcglobal.net>
+#
+# License: GNU GPLv3+
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+baseconfpath="/etc/libredbdiff"
+basedbpath="/var/lib/libredbdiff"
+
+conffile="$baseconfpath/pacman.conf.parabola"
+conffilearch="$baseconfpath/pacman.conf.archlinux"
+
+dbpath="$basedbpath/pacman.parabola"
+dbpatharch="$basedbpath/pacman.archlinux"
+
+mirrorlist="$baseconfpath/mirrorlist.parabola"
+mirrorlistarch="$baseconfpath/mirrorlist.archlinux"
+
+mirror='http://repo.parabola.nu/$repo/os/$arch'
+mirrorarch='http://mirrors.kernel.org/archlinux/$repo/os/$arch'
+
+repos="libre pcr libre-multilib nonprism"
+
+field_pkgname_parabola=30
+field_pkgname_arch=30
+
+
+. libremessages
+
+cmd="${0##*/}"
+
+arch_packages_tmp="/tmp/${cmd}.arch-packages"
+parabola_packages_tmp="/tmp/${cmd}.parabola-packages"
+
+field_pkgname_total="$((${field_pkgname_parabola} + ${field_pkgname_arch}))"
+printf_format="%s %-${field_pkgname_parabola}s%-${field_pkgname_arch}s %s | %s\n"
+printf_format_noarch="%s %-${field_pkgname_total}s %s\n"
+
+downloadfile() {
+ local outfile=$1
+ local url=$2
+ local mesg=("${@:3}")
+ if [[ ! -e $outfile ]] ; then
+ msg "${mesg[@]}"
+ if wget -q "$url" -O "$outfile"; then
+ return 255
+ else
+ die "Failed to download %q. Exiting." "$outfile"
+ fi
+ elif [[ $init ]]; then
+ warning "%q already exists. Skipping." "$outfile"
+ fi
+}
+
+enablerepo() {
+ repo="$1"
+ conffile_arg="$2"
+ msg2 "Enabling repo %q in %q" "$repo" "${conffile_arg}"
+ sed -i "s/\#\[$repo\]/[$repo]/" "${conffile_arg}"
+ sed -i "\/\[$repo\]/,+1 s/#Include/Include/" "${conffile_arg}"
+}
+
+createdir() {
+ local dir=$1
+ if [[ ! -e $dir ]] ; then
+ msg "Creating directory %q" "$dir"
+ mkdir -- "$1" || die "Failed to create directory %q. Exiting." "$dir"
+ elif [[ $init ]]; then
+ warning "%q already exists. Skipping." "$dir"
+ fi
+}
+
+setmirror() {
+ local distro="$1"
+ local mirror="$2"
+ local mirrorlist="$3"
+ if [[ $init ]] && [[ $mirror ]]; then
+ mirrorescaped="${mirror//./\\.}"
+ mirrorescaped="${mirrorescaped//\$/\\$}"
+ msg2 "Setting %s as the only enabled %s mirror." "${mirror}" "${distro}"
+ sed -i 's|^#\(Server = '"${mirrorescaped}"'\)$|\1|' "${mirrorlist}"
+ fi
+}
+
+filenotfound() {
+ local file=$1
+ if [[ ! -r $1 ]]; then
+ error "Could not read %q." "$file"
+ die "Nothing done. It may be necessary to run %q without \
+arguments as root to initialize %s." "$cmd" "$name"
+ fi
+}
+
+initialize() {
+ createdir "$baseconfpath"
+ createdir "$basedbpath"
+
+ downloadfile \
+ "${conffile}" \
+ "https://projects.parabola.nu/abslibre.git/plain/libre/pacman/pacman.conf.x86_64" \
+ "Downloading Parabola %q" \
+ pacman.conf
+ if [[ $? == 255 ]] ; then
+ msg2 "Setting DBPath in %q" "${conffile}"
+ sed -i "s|^#DBPath .*|DBPath = ${dbpath}|" "${conffile}"
+ enablerepo nonprism "${conffile}"
+ enablerepo pcr "${conffile}"
+ enablerepo libre-multilib "${conffile}"
+ enablerepo multilib "${conffile}"
+ fi
+
+ downloadfile \
+ "${conffilearch}" \
+ "https://projects.archlinux.org/svntogit/packages.git/plain/pacman/trunk/pacman.conf.x86_64" \
+ "Downloading Arch %q" \
+ pacman.conf
+ if [[ $? == 255 ]] ; then
+ msg2 "Setting DBPath in %q" "${conffilearch}"
+ sed -i "s|^#DBPath .*|DBPath = ${dbpatharch}|" "${conffilearch}"
+ msg2 "Setting Arch mirrorlist file in %q" "${conffilearch}"
+ sed -i "s|/etc/pacman\.d/mirrorlist$|$baseconfpath/mirrorlist.archlinux|" \
+ "${conffilearch}"
+ enablerepo multilib "${conffilearch}"
+ fi
+
+ downloadfile \
+ "${mirrorlist}" \
+ "https://repo.parabola.nu/mirrorlist.txt" \
+ "Downloading Parabola %q" \
+ mirrorlist
+ if [[ $? == 255 ]] ; then
+ sed -i 's|^Server|#Server|' "${mirrorlist}"
+ setmirror "Parabola" "$mirror" "$mirrorlist"
+ fi
+
+ downloadfile \
+ "${mirrorlistarch}" \
+ "https://projects.archlinux.org/svntogit/packages.git/plain/pacman-mirrorlist/trunk/mirrorlist" \
+ "Downloading Arch %q" \
+ mirrorlist
+ if [[ $? == 255 ]] ; then
+ setmirror "Arch" "$mirrorarch" "$mirrorlistarch"
+ fi
+}
+
+repo_test() {
+ for repo in ${repos} ; do
+ if [[ $repo == $1 ]] ; then
+ found=1
+ return 0
+ fi
+ done
+ if [[ $found != 1 ]] ; then
+ die "The specified Parabola repo \"%s\" cannot be compared. It's not in the list of repos in the configuration variable \"repos\"." "$1"
+ fi
+}
+
+compare_pkgs() {
+ local cmp
+ if [[ ${verarch[$pkgname]} ]] ; then
+ cmp=$(vercmp "${ver[$pkgname]}" "${verarch[$pkgname]}")
+ if [[ $cmp -lt 0 ]]; then
+ printf "${printf_format}" \
+ '=' \
+ "${pkgname}" \
+ "" \
+ "${ver[$pkgname]}" \
+ "${verarch[$pkgname]}"
+ fi
+ elif [[ ${provides[$pkgname]} ]]; then
+ for provide in "${provides[$pkgname]}"; do
+ if [[ ${verarch["$provide"]} ]]; then
+ cmp=$(vercmp "${ver[$pkgname]}" "${verarch[$provide]}")
+ if [[ $cmp -lt 0 ]]; then
+ printf "${printf_format}" \
+ 'p' \
+ "${pkgname}" \
+ "${provide}" \
+ "${ver[$pkgname]}" \
+ "${verarch[$provide]}"
+ fi
+ fi
+ done
+ else
+ printf "${printf_format_noarch}" \
+ 'o' \
+ "${pkgname}" \
+ "${ver[$pkgname]}"
+ fi
+}
+
+print_cmp() {
+ local repo="$1"
+ awk -F/ -v repo="$repo" \
+ '$1 == repo {print $2}' \
+ ${parabola_packages_tmp} | \
+ while read -a line ; do
+ ver["${line[0]}"]="${line[1]}"
+ provides[${line[0]}]="${line[@]:2}"
+ pkgname=${line[0]}
+ compare_pkgs
+ done
+}
+
+usage() {
+ print "Usage: %q [-n|-h]" "$cmd"
+ print 'Show packages that need to be updated from Arch repositories.'
+ echo
+ prose "Compares packages in Parabola repositories. Packages from
+ all configured Parabola repositories are compared. A Parabola
+ repository name can be specified as argument to compare only
+ packages in that repository."
+ echo
+ prose "The default mode of operation is to download/update all necessary
+ files for comparison, but not compare them. Specify the \`-n\`
+ flag to not download anything, but to compare already downloaded
+ files."
+ echo
+ print 'Options:'
+ flag '-n' "Don't update anything, just compare already downloaded files."
+ flag '-h' 'Show this message'
+ echo
+ print "Output format:"
+ print "type_character parabola_pkgname (arch_pkgname) parabola_pkgver - (arch_pkgver)"
+ echo
+ print "Type characters:"
+ flag '=' "Arch package with the same pkgname and greater pkgver was found"
+ flag 'p' "Arch package with pkgname equal to a provide and greater
+ pkgver was found In this case arch_pkgname is a provide of
+ parabola_pkgname"
+ flag 'o' "No Arch package with the same pkgname or with pkgname equal to
+ a provide was found"
+}
+
+main() {
+ local UPDATE=1
+ local arg
+ local repo_arg
+
+ for arg in "$@"; do
+ case "$arg" in
+ -n|--noupdate)
+ UPDATE=0
+ ;;
+ -h|--help)
+ usage
+ return 0
+ ;;
+ *)
+ repo_test "$arg"
+ repo_arg="$arg"
+ break
+ ;;
+ esac
+ done
+
+ if (( $UPDATE )) ; then
+ if [[ $EUID != 0 ]]; then
+ die "To initialize %s or update %s pacman databases, %s must be run as root (without arguments). Nothing done." \
+ "$name" \
+ "$name" \
+ "$cmd"
+ fi
+
+ if ! [[ -e "${conffile}" && \
+ -e "${conffilearch}" && \
+ -e "${mirrorlist}" && \
+ -e "${mirrorlist}" ]]; then
+ warning "At least one %s configuration file is missing." \
+ "${name}"
+ msg "Downloading and preparing missing configuration files."
+ init=1
+ fi
+
+ createdir "$baseconfpath"
+ createdir "$basedbpath"
+
+ initialize
+
+ if ! [[ -d "$dbpath" && \
+ -d "$dbpatharch" ]]; then
+ warning "At least one %s pacman DB directory is missing. Synchronizing %s DB files." \
+ "${name}" "${name}"
+ fi
+
+ createdir "$dbpath"
+ msg "Synchronizing %s pacman databases for Parabola" "$name"
+ pacman --config "${conffile}" -Sy ||
+ die "Failed to synchronize pacman database for Parabola. Exiting."
+
+ createdir "$dbpatharch"
+ msg "Synchronizing %s pacman databases for Arch" "$name"
+ pacman --config "${conffilearch}" -b "${dbpatharch}" -Sy ||
+ die "Failed to synchronize pacman database for Arch. Exiting."
+
+ msg "%s pacman databases are updated. %s is ready. Run %q -n to print results." \
+ "$name" "$name" "$cmd"
+ return 0
+ else
+ filenotfound "${dbpath}"
+ filenotfound "${dbpatharch}"
+ filenotfound "${conffile}"
+ filenotfound "${conffilearch}"
+ filenotfound "${mirrorlist}"
+ filenotfound "${mirrorlistarch}"
+
+ unset provides ver verarch
+ declare -gA provides ver verarch
+
+ if ! [[ -d "$dbpath" && \
+ -d "$dbpatharch" ]]; then
+ die "At least one %s pacman DB directory is missing. To update %s pacman databases, %s must be run as root. Nothing done." \
+ "$name" \
+ "$name" \
+ "$cmd"
+ fi
+
+ pacman --config "${conffilearch}" -Ss | \
+ grep -v '^ ' | \
+ awk -F/ '{print $2}' \
+ > ${arch_packages_tmp} || \
+ die "pacman command to get Arch package data has failed. Exiting."
+ chmod 777 ${arch_packages_tmp}
+
+ while read -a line; do
+ verarch["${line[0]}"]="${line[1]}"
+ done < ${arch_packages_tmp}
+
+ expac --config "${conffile}" -S '%r/%n %v %S' \
+ > ${parabola_packages_tmp} || \
+ die "expac command to get Parabola package data has failed. Exiting."
+ chmod 777 ${parabola_packages_tmp}
+
+ if [[ ${repo_arg} ]] ; then
+ print_cmp "${repo_arg}"
+ else
+ for repo in ${repos} ; do
+ echo "[$repo]"
+ print_cmp "$repo"
+ done
+ fi
+ fi
+}
+
+main "$@"