summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEsteban Carnevale <alfplayer@mailoo.org>2014-12-21 11:56:49 -0300
committerEsteban Carnevale <alfplayer@mailoo.org>2014-12-21 15:18:28 -0300
commit575768d7c68fbbc674505ee0d56aac3cddd0f247 (patch)
treefed10c3bbc6994833dd79429670edc62de9fdcaa /src
parent8b17eaf422ae5bea4c1f2264576a3280d50b66dd (diff)
libredbdiff: Many improvements
* cleaner output format * multiple non-default repositories Parabola: libre pcr libre-multilib nonprism Arch: multilib * a single Parabola repository can be specified as argument to restrict the comparison to that repository * support expac 4 extra/expac 4.2 has a bug, so pcr/expac-relative 4.2-parabola1 or later is needed * detection of missing files * code style * move code to functions * usage text and messages
Diffstat (limited to 'src')
-rwxr-xr-xsrc/abslibre-tools/libredbdiff285
1 files changed, 232 insertions, 53 deletions
diff --git a/src/abslibre-tools/libredbdiff b/src/abslibre-tools/libredbdiff
index ff3b4a1..2bc8a5a 100755
--- a/src/abslibre-tools/libredbdiff
+++ b/src/abslibre-tools/libredbdiff
@@ -34,10 +34,23 @@ 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
@@ -54,6 +67,14 @@ downloadfile() {
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
@@ -71,7 +92,7 @@ setmirror() {
if [[ $init ]] && [[ $mirror ]]; then
mirrorescaped="${mirror//./\\.}"
mirrorescaped="${mirrorescaped//\$/\\$}"
- msg "Setting %q as the only enabled %s mirror." "${mirror}" "${distro}"
+ msg2 "Setting %s as the only enabled %s mirror." "${mirror}" "${distro}"
sed -i 's|^#\(Server = '"${mirrorescaped}"'\)$|\1|' "${mirrorlist}"
fi
}
@@ -79,35 +100,150 @@ setmirror() {
filenotfound() {
local file=$1
if [[ ! -r $1 ]]; then
- die "Could not read %q. Nothing done." "$file"
- plain "It may be necessary to run %q without arguments as root to initialize %s." "$cmd" "$name"
+ 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
}
-comparepkgs() {
+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
+}
+
+expac_version_test() {
+ if ! pkgname="$(pacman -Qoq expac 2> /dev/null)" ; then
+ die "The command expac could not be found installed. The package \
+pcr/expac-relative 4-2.parabola1 (or later) must be installed."
+ elif [[ $pkgname == expac-git ]] ; then
+ true
+ elif [[ $pkgname == expac-relative ]] ; then
+ expac_ver="$(expac %v expac-relative)"
+ if [[ $(vercmp "${expac_ver}" 4-2.parabola1) == -1 ]] ; then
+ die "The version of expac-relative installed on the system is \
+lower than needed."
+ fi
+ else
+ die "expac command must be provided by pcr/expac-relative version \
+4-2.parabola1 (or later). This package must be installed."
+ fi
+}
+
+compare_pkgs() {
+ local cmp
if [[ ${verarch[$pkgname]} ]] ; then
cmp=$(vercmp "${ver[$pkgname]}" "${verarch[$pkgname]}")
if [[ $cmp -lt 0 ]]; then
- msg "%s needs update from the Arch package of the same name. Versions: %s - %s" "${pkgname}" "${ver[$pkgname]}" "${verarch[$pkgname]}"
+ 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
- msg "%s may need update from provide candidate %s. Versions: %s - %s" "${pkgname}" "${provide}" "${ver[$pkgname]}" "${verarch[$provide]}"
+ printf "${printf_format}" \
+ 'p' \
+ "${pkgname}" \
+ "${provide}" \
+ "${ver[$pkgname]}" \
+ "${verarch[$provide]}"
fi
fi
done
else
- msg "Could not find candidate to compare %s" "${pkgname}"
+ 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 [libre] packages that need to be updated from Arch repositories.'
+ 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."
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
@@ -116,68 +252,83 @@ usage() {
print 'Options:'
flag '-n' "Don't update anything, just compare already downloaded files."
flag '-h' 'Show this message'
+ echo
+ print "Output format:
+ type_character parabola_pkgname (arch_pkgname) parabola_pkgver - (arch_pkgver)"
+ echo
+ print "Type characters:
+ = Arch package with the same pkgname and greater pkgver was found
+ 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
+ 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) UPDATE=0;;
- -h) usage; return 0;;
+ -n|--noupdate)
+ UPDATE=0
+ ;;
+ -h|--help)
+ usage
+ return 0
+ ;;
*)
- error "Bad arguments. Nothing done."
- usage >&2
- return 1
+ repo_test "$arg"
+ repo_arg="$arg"
+ break
;;
esac
done
if (( $UPDATE )) ; then
if [[ $EUID != 0 ]]; then
- die "To initialize $name or update %s pacman databases, the script must be run as root. Nothing done." "$name"
+ die "To initialize %s or update %s pacman \
+databases, %s must be run as root (without arguments). Nothing done." \
+ "$name" \
+ "$name" \
+ "$cmd"
fi
- if ! [[ -d "$baseconfpath" && -d "$basedbpath" && -d "$dbpath" && -d "$dbpatharch" && -e "${conffile}" && -e "${conffilearch}" && -e "${mirrorlist}" && -e "${mirrorlist}" ]]; then
- msg "%s files are missing. Initializing." "${name}"
+ 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"
- createdir "$dbpath"
- createdir "$dbpatharch"
- downloadfile "${conffile}" "https://projects.parabola.nu/abslibre.git/plain/libre/pacman/pacman.conf.x86_64" \
- "Downloading Parabola %q" pacman.conf
+ initialize
- downloadfile "${conffilearch}" "https://projects.archlinux.org/svntogit/packages.git/plain/pacman/trunk/pacman.conf.x86_64" \
- "Downloading Arch %q" pacman.conf
- if [[ $? == 255 ]] ; then
- msg "Setting Arch mirrorlist file in %q" "${conffilearch}"
- sed -i "s|/etc/pacman\.d/mirrorlist$|$baseconfpath/mirrorlist.archlinux|" "${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"
+ 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}" -b "${dbpath}" -Sy || die "Failed to synchronize pacman database for Parabola. Exiting."
+ 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."
+ 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"
+ msg "%s pacman databases are updated. %s is ready. Run %q -n to \
+print results." "$name" "$name" "$cmd"
return 0
else
filenotfound "${dbpath}"
@@ -186,21 +337,49 @@ main() {
filenotfound "${conffilearch}"
filenotfound "${mirrorlist}"
filenotfound "${mirrorlistarch}"
- fi
- unset provides ver verarch
- declare -gA provides ver verarch
+ 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
+
+ expac_version_test
+
+ 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}
- while read -a line; do
- verarch["${line[0]}"]="${line[1]}"
- done < <(pacman --dbpath "${dbpatharch}" --config "${conffilearch}" -Ss | grep -v '^ ' | awk -F/ '{print $2}')
+ 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}
- while read -a line; do
- ver[${line[0]}]="${line[1]}"
- provides[${line[0]}]="${line[@]:2}"
- pkgname=${line[0]}
- comparepkgs
- done < <(expac -b "${dbpath}" -c "${conffile}" -Ss '%r/%n %v %S' | awk -F/ '$1 == "libre" {print $2}')
+ if [[ ${repo_arg} ]] ; then
+ print_cmp "${repo_arg}"
+ else
+ for repo in ${repos} ; do
+ print "[$repo]"
+ print_cmp "$repo"
+ done
+ fi
+ fi
}
main "$@"