diff options
Diffstat (limited to 'src')
39 files changed, 3762 insertions, 0 deletions
diff --git a/src/abslibre-tools/abslibre-commit b/src/abslibre-tools/abslibre-commit new file mode 100755 index 0000000..e906fbd --- /dev/null +++ b/src/abslibre-tools/abslibre-commit @@ -0,0 +1,36 @@ +#!/bin/bash +# ABSLibreCommit +# Commits a PKGBUILD to ABSLibre.git + +# Copyright 2010 Nicolás Reynolds + +# ---------- GNU General Public License 3 ---------- + +# This file is part of Parabola. + +# Parabola 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. + +# Parabola 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 Parabola. If not, see <http://www.gnu.org/licenses/>. + +for _pkg in ${@}; do + [[ ! -e ${_pkg}/PKGBUILD ]] && continue + + unset pkgbase pkgname + source ${_pkg}/PKGBUILD + +# use . instead of * will use .gitignore + git stage ${_pkg}/. + + git commit -m "${pkgbase:-$pkgname}-${pkgver}-${pkgrel}" +done + +exit 0 diff --git a/src/abslibre-tools/createworkdir b/src/abslibre-tools/createworkdir new file mode 100755 index 0000000..b443c08 --- /dev/null +++ b/src/abslibre-tools/createworkdir @@ -0,0 +1,63 @@ +#!/bin/bash +# CreateWorkDir +# Creates a dir structure for working with Parabola packages + +# Copyright 2010 Nicolás Reynolds + +# ---------- GNU General Public License 3 ---------- + +# This file is part of Parabola. + +# Parabola 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. + +# Parabola 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 Parabola. If not, see <http://www.gnu.org/licenses/>. + +source /etc/libretools.conf +custom_config=$XDG_CONFIG_HOME/libretools/libretools.conf +[[ -e $custom_config ]] && source $custom_config + +[[ ! -d ${WORKDIR} ]] && { # Create the WORKDIR + + msg "Creating WORKDIR on ${WORKDIR}" + mkdir -p ${WORKDIR} ||{ + error "Could not create ${WORKDIR}"; exit 1 + } + +} + +for _repo in ${REPOS[@]}; do # Create the staging dirs + + [[ ! -d ${WORKDIR}/staging/${_repo} ]] && { + mkdir -p ${WORKDIR}/staging/${_repo} || { + error "Can't create ${WORKDIR}/staging/${_repo}" + exit 1 + } + } + +done + +[[ ! -d ${WORKDIR}/abslibre/.git ]] && { + msg "Cloning into ABSLibre" + CMD="git clone ${ABSLIBREGIT} ${WORKDIR}/abslibre" + ${CMD} || { + error "Could not clone ABSLibre" + plain "Try running this command:" + echo + plain "${CMD}" + exit 1 + } +} + +msg "Finished, your packaging dir tree looks like this now:" +ls --color=always ${WORKDIR}/*/* + +exit 0 diff --git a/src/abslibre-tools/libreaddiff b/src/abslibre-tools/libreaddiff new file mode 100755 index 0000000..98646a2 --- /dev/null +++ b/src/abslibre-tools/libreaddiff @@ -0,0 +1,97 @@ +#!/bin/bash +# -*- coding: utf-8 -*- +# Copyright (C) 2011, 2012 Michał Masłowski <mtjm@mtjm.eu> +# +# 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 Affero 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/>. + + +set -e + +. /etc/libretools.conf +custom_config=$XDG_CONFIG_HOME/libretools/libretools.conf +[ -e $custom_config ] && . $custom_config + +for arg in "$@" ; do + case "$arg" in + -h|--h|--he|--hel|--help|-\?) + echo 'Usage: libreaddiff repo [arch] + +This script outputs a diff of package names and versions in repo +between pacman'\''s sync db and abslibre checkout.' >&2 + exit 0 + ;; + esac +done + +# The repo to find missing packages in. +repo=$1 +# The arch to check in Arch repos, other will have all arches checked. +arch=${2:-mips64el} +# A Python tuple of repos which don't have arch=any packages. +archrepos='("core", "extra", "community")' + +diff -U0 \ + <( ( + cd /var/lib/pacman/sync + for f in $repo.db ; do + tar xOf $f | python -c 'import sys +arch = None +name = None +version = None +it = iter(sys.stdin) +try: + while True: + line = next(it) + if line == "%ARCH%\n": + arch = next(it) + if arch == "'"$arch"'\n" or "'$repo'" not in '"$archrepos"': + print("%s-%s" % (name.strip(), version.strip())) + if line == "%NAME%\n": + name = next(it) + if line == "%VERSION%\n": + version = next(it) +except StopIteration: + pass +' + done + ) | sort ) \ + <( ( + cd "${WORKDIR}/abslibre" + # Needed to not include pkgnames specific to other arches. + CARCH=$arch + for f in $repo/* ; do + unset pkgname + unset epoch + unset pkgver + unset pkgrel + unset arch + . $f/PKGBUILD || continue + is_here=false + for arc in ${arch[@]} ; do + if [ "$arc" = "any" -o "$arc" = "$CARCH" ] ; then + is_here=true + break + fi + done + if [ "$is_here" = "true" ] ; then + for name in ${pkgname[@]} ; do + if [ -z "$epoch" ] ; then + echo $name-$pkgver-$pkgrel + else + echo $name-$epoch:$pkgver-$pkgrel + fi + done + fi + done + ) | sort ) | sed -rn 's/^[+-][^+-].+$/&/p' diff --git a/src/abslibre-tools/librecommit b/src/abslibre-tools/librecommit new file mode 100755 index 0000000..1698bed --- /dev/null +++ b/src/abslibre-tools/librecommit @@ -0,0 +1,65 @@ +#!/bin/bash +# Copyright 2010 Nicolás Reynolds + +# ---------- GNU General Public License 3 ---------- + +# This file is part of Parabola. + +# Parabola 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. + +# Parabola 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 Parabola. If not, see <http://www.gnu.org/licenses/>. + +source /etc/libretools.conf + +usage () { + echo "cd to the dir with the PKGBUILD you are commiting and" + echo + echo "$0 [optionally files to commit]" + echo + echo "This script commits the package using name, pkgver and pkgrel" + echo + exit 1 +} + +msg="Commiting libre package \"\$pkg-\$pkgver-\$pkgrel\"" + +for opt in $@ ; do + case ${opt} in + -h) usage ;; + -m) shift; msg=${1}; shift ;; + *) files+="${1} " ; shift ;; + esac +done + +if [ ! -e PKGBUILD -o -z "$files" ]; then usage; fi + +source PKGBUILD + +pkg=${pkgbase:-${pkgname}} + +msg=$(eval echo $msg) + +if [ "$COMMITCMD" = 'git' ]; then + + ${COMMITCMD} add ${files} && ${COMMITCMD} commit -m "$(echo $msg)" + +elif [ "$COMMITCMD" = 'hg' ]; then + + ${COMMITCMD} commit ${files} -m "$msg" -v || exit 1 + +else + + error "COMMITCMD is not correctly set on libretools.conf" + +fi + +exit 0 diff --git a/src/abslibre-tools/librerelease b/src/abslibre-tools/librerelease new file mode 100755 index 0000000..efb698e --- /dev/null +++ b/src/abslibre-tools/librerelease @@ -0,0 +1,155 @@ +#!/bin/bash +# Librerelease +# Uploads packages into [staging] + +# Copyright 2010 Nicolás Reynolds + +# ---------- GNU General Public License 3 ---------- + +# This file is part of Parabola. + +# Parabola 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. + +# Parabola 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 Parabola. If not, see <http://www.gnu.org/licenses/>. + +source /etc/libretools.conf +custom_config=$XDG_CONFIG_HOME/libretools/libretools.conf + +function usage { + echo "$(gettext "Usage: $0")" + echo + echo "$(gettext "This script uploads packages on $WORKDIR/stagging")" + echo "$(gettext "to parabola server.")" + echo + echo "$(gettext "OPTIONS:")" + echo "$(gettext " -h this message.")" + echo "$(gettext " -l only list packages but not upload them.")" + echo "$(gettext " -c clean packages on $WORKDIR/staging.")" + echo "$(gettext " -n dry-run")" +} + +function list_packages { + repos=($(find "$WORKDIR/staging/" -mindepth 1 -type d \! -empty -printf '%f ' 2>/dev/null)) + for _repo in ${repos[@]}; do + msg2 "$_repo" + find ${WORKDIR}/staging/${_repo} -type f -printf "%f\n" + done + unset repos +} + +function sign_packages { + if [ -z "${SIGEXT}" ]; then + SIGEXT=.sig + warning "Empty SIGEXT var, using default .sig" + fi + + if [ -z "${GPG_AGENT_INFO}" ]; then + warning "It's better to use gpg-agent to sign packages in batches" + fi + + packages=($(find "${WORKDIR}/staging/" -type f -iname '*.pkg.tar.?z')) + for package in ${packages[@]}; do + if [ -f "${package}${SIGEXT}" ]; then + + warning "Package signature found, verifying..." + +# Verify that the signature is correct, else remove for re-signing + if ! gpg --quiet --verify "${package}${SIGEXT}" >/dev/null 2>&1; then + error "Failed! Resigning..." + rm -f "${package}${SIGEXT}" + fi + fi + + msg2 "Signing ${package}..." + gpg --default-key "${SIGID}" --output "${package}${SIGEXT}" \ + --detach-sig "${package}" || { + error "Signing failed" + exit 2 + } + + done +} + +# Remove everything that's not a package or a signature +function clean_non_packages { + find $WORKDIR/staging/ -type f \ + \! -iname "*.pkg.tar.?z" -a \! -iname "*.pkg.tar.?z.sig" \ + -delete +} + +# Clean everything if not on dry-run mode +function clean { + [ -z ${dryrun} ] && \ + rm -f $@ +} + +if [ -w / ]; then + error "Run $0 as normal user" + exit 1 +fi + +while getopts 'hlcn' arg; do + case $arg in + h) usage; exit 0 ;; + l) list_packages; exit 0 ;; + c) clean; exit $? ;; + n) dryrun="--dry-run" ;; + esac +done + +[[ -e $custom_config ]] && source $custom_config + +[[ ! -z ${HOOKPRERELEASE} ]] && bash -c "${HOOKPRERELEASE}" + +clean_non_packages +if [ ! -z "${SIGID}" ]; then + sign_packages +else + error "Package signing is *required*, please set SIGID on your libretools.conf" + exit 1 +fi + +# Make the permissions of the packages 644 otherwise the user will get access +# denied error when they try to download (rsync --no-perms doesn't seem to +# work). +find ${WORKDIR}/staging -type f -exec chmod 644 {} \; +find ${WORKDIR}/staging -type d -exec chmod 755 {} \; + +# Get the synced files +SYNCED_FILES=($(find ${WORKDIR}/staging -type f)) + +msg "%s to upload" $(du -h -d 0 ${WORKDIR}/staging | tr "\t" " " | cut -d" " -f1) +msg "Uploading packages..." +rsync --recursive \ + ${dryrun} \ + --no-group \ + --no-perms \ + --copy-links \ + --hard-links \ + --partial \ + --prune-empty-dirs \ + --human-readable \ + --progress \ + -e "ssh " \ + ${WORKDIR}/staging \ + ${PARABOLAHOST}:${LIBREDESTDIR}/ || { + error "Sync failed, try again" + exit 1 + } + +msg "Removing ${#SYNCED_FILES[@]} files from local [staging]" +clean ${SYNCED_FILES[@]} + +msg "Running db-update on repos" +ssh ${PARABOLAHOST} dbscripts/db-update + +exit 0 diff --git a/src/abslibre-tools/librestage b/src/abslibre-tools/librestage new file mode 100755 index 0000000..b474bb1 --- /dev/null +++ b/src/abslibre-tools/librestage @@ -0,0 +1,138 @@ +#!/bin/bash +# LibreStage +# Prepares packages for upload into [staging] + +# Copyright 2010 Nicolás Reynolds + +# ---------- GNU General Public License 3 ---------- + +# This file is part of Parabola. + +# Parabola 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. + +# Parabola 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 Parabola. If not, see <http://www.gnu.org/licenses/>. + + +source /etc/libretools.conf +custom_config=$XDG_CONFIG_HOME/libretools/libretools.conf +[[ -e $custom_config ]] && source $custom_config + +if [ -w / ]; then + error "This script should be run as regular user" + exit 1 +fi + + +# End Config + +usage() { + cat <<EOU +LibreStage Copyright (C) 2011 Nicolás Reynolds +This program comes with ABSOLUTELY NO WARRANTY. +This is free software, and you are welcome to redistribute it +under the terms of the GNU General Public License version 3 or later. + + +Usage: $(basename $0) <repo> [<repo2> ... ] + +LibreRelease will stage for upload the package(s) built by the PKGBUILD on +the current directory to the specified repo(s). +EOU +} + +repos=$@ + +while getopts 'h' arg; do + case $arg in + h) usage; exit 0 ;; + esac +done + +if [ ${#repos} -eq 0 ]; then + usage + exit 1; +fi + +[[ ! -e ./PKGBUILD ]] && { + error "PKGBUILD not found" + exit 1 +} + +# Source the needed files +source /etc/makepkg.conf +[[ -e ~/.makepkg.conf ]] && source ~/.makepkg.conf +source ./PKGBUILD +[[ -e ./rePKGBUILD ]] && source ./rePKGBUILD + +# Default package location +PKGDEST=${PKGDEST:-.} +SRCPKGDEST=${SRCPKGDEST:-.} + +PKGEXT=".pkg.tar.?z" + +staged=false +# Copies the packages to the specified repos inside staging +for _arch in ${ARCHES[@]}; do + for pkg in ${pkgname[@]}; do + + pkgpath=$(find ${PKGDEST}/ -type f \ + -name "${pkg}-${pkgver}-${pkgrel}-${_arch}${PKGEXT}" -or \ + -name "${pkg}-${epoch}:${pkgver}-${pkgrel}-${_arch}${PKGEXT}") + + [[ -z ${pkgpath} ]] && continue + + pkgfile=$(basename ${pkgpath}) + +# TODO refactor this + if [ -e "${pkgpath}" ]; then + msg "Found ${pkgfile}" + + canonical="" + for _repo in ${repos[@]}; do + + if [ ! -d "${WORKDIR}/staging/${_repo}" ]; then + warning "[${_repo}] didn't exist, creating..." + mkdir -p "${WORKDIR}/staging/${_repo}" + fi + + if [ -z "$canonical" ]; then + canonical="${WORKDIR}/staging/${_repo}/${pkgfile}" + + cp "${pkgpath}" "${WORKDIR}/staging/${_repo}/" || { + error "Can't put ${pkgfile} on [staging]" + exit 1 + } && { + msg2 "${pkg} staged on [${_repo}]" + staged=true + } + + else + ln "${canonical}" "${WORKDIR}/staging/${_repo}/${pkgfile}" || { + error "Can't put ${pkgfile} on [staging]" + exit 1 + } && { + msg2 "${pkg} staged on [${_repo}]" + staged=true + } + + fi + done + fi + done +done + +if ! $staged ; then + error "No package was staged" + exit 1 +fi + +exit 0 diff --git a/src/abslibre-tools/updateabslibre b/src/abslibre-tools/updateabslibre new file mode 100755 index 0000000..76f964a --- /dev/null +++ b/src/abslibre-tools/updateabslibre @@ -0,0 +1,39 @@ +#!/bin/bash +# UpdateABSLibre +# Updates the ABSLibre git repo + +# Copyright 2010 Nicolás Reynolds + +# ---------- GNU General Public License 3 ---------- + +# This file is part of Parabola. + +# Parabola 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. + +# Parabola 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 Parabola. If not, see <http://www.gnu.org/licenses/>. + +source /etc/libretools.conf +custom_config=$XDG_CONFIG_HOME/libretools/libretools.conf +[[ -e $custom_config ]] && source $custom_config + +# Send every output to /dev/null + +msg "Updating ABSLibre..." + +pushd ${WORKDIR}/abslibre ${stdnull} + git pull ${ABSLIBREGIT} || { + error "Failed pull" + exit 1 +} +stdnull "popd" + +exit 0 @@ -0,0 +1,123 @@ +#!/bin/bash +# Copyright 2010 Nicolás Reynolds, Joshua Ismael + +# ---------- GNU General Public License 3 ---------- + +# This file is part of Parabola. + +# Parabola 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. + +# Parabola 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 Parabola. If not, see <http://www.gnu.org/licenses/>. + +source /etc/libretools.conf +source /etc/abs.conf + +function usage { + echo "Usage: $0 pkgname-from-aur1 [pkgname-from-aur2 ...]" + echo + echo "This script will download packages from aur to the current dir" + echo "and check their license for nonfree issues." +} + +while getopts 'h' arg; do + case $arg in + h) usage; exit 0 ;; + *) usage; exit 1 ;; + esac +done + +missing_deps=() +for _pkg in ${@}; do + +# Remove the version + _pkg="${_pkg%%[<>=]*}" + + if [ -f "${_pkg}/PKGBUILD" ]; then + warning "${_pkg} already existed." + +# Check if we want to diff + if [ -z "${DIFFTOOL}" ]; then + continue + else +# Store our copy of the PKGBUILD dir + _diff="${PWD}/${_pkg}" + stdnull "pushd $(mktemp -d /tmp/${_pkg}.XXXX)" + msg2 "Downloading PKGBUILD into ${PWD} for diff" + fi + fi + + msg "Downloading $_pkg..." + wget -O - -q https://aur.archlinux.org/packages/$(echo $_pkg | sed "s/^../&\/&/")/$_pkg.tar.gz | \ + tar xzf - >/dev/null 2>&1 + + if [ $? -ne 0 ]; then + error "Couldn't get $_pkg" + continue + fi + + stdnull "pushd $_pkg" + + if [ ! -z "$_diff" ]; then + msg2 "Diffing files" +# Diff all files with our difftool + for file in *; do + ${DIFFTOOL} ${_diff}/${file} ${file} + done + +# Go back to our copy to continue working + stdnull "pushd ${_diff}" + fi + + source PKGBUILD + + if ! pkgbuild-check-nonfree; then + if [ $? -eq 15 ]; then + warning "This PKGBUILD links to known unfree packages" + fi + fi + + msg2 "Checking license..." + free=0 + for _license in ${license[@]}; do + if [ ! -d /usr/share/licenses/common/$_license ]; then + warning "License $_license is not a common license" + free=1 + fi + done + + if [ $free -eq 1 ]; then + plain "Please check that the license is included in the package and + *specially* that it respects your freedom." + fi + + for _dep in ${depends[@]} ${makedepends[@]}; do + _dep=${_dep/[<>=]*/} + if ! is_built $_dep; then + if ! find ${ABSROOT} -maxdepth 2 -type d -name "$_dep" | egrep "*" >/dev/null ; then + msg2 "$_dep will be get from AUR" + missing_deps+=($_dep) + fi + else + msg2 "$_dep is on repos" + fi + done + + stdnull popd + +done + +[[ ${#missing_deps[*]} -gt 0 ]] && { + msg2 "Retrieving missing deps: ${missing_deps[@]}" + $0 ${missing_deps[@]} +} + +exit 0 diff --git a/src/chroot-tools/buildenv b/src/chroot-tools/buildenv new file mode 100755 index 0000000..84a1fc2 --- /dev/null +++ b/src/chroot-tools/buildenv @@ -0,0 +1,28 @@ +#!/bin/bash + +trap "umount_all" 0 ERR TERM KILL + +user=${SUDO_USER:-${1}} + +umount_all() { + for mp in home/pkgdest home/srcdest home/${user}; do + msg "Umounting /$mp" + umount $CHROOTDIR/$CHROOT/$mp || error "Couldn't umount" + done +} + +source /etc/libretools.conf + +for mp in home/pkgdest home/srcdest home/${user} var/lib/toru; do + msg "Binding /$mp" + mount -o bind /$mp $CHROOTDIR/$CHROOT/$mp || exit 1 +done + +for etc in etc/makepkg.conf etc/abs.conf etc/mtab; do + msg "Copying config /$etc" + cp --remove-destination /$etc $CHROOTDIR/$CHROOT/$etc || exit 1 +done + +$(dirname $0)/librechroot $CHROOT + +exit $? diff --git a/src/chroot-tools/chcleanup b/src/chroot-tools/chcleanup new file mode 100755 index 0000000..17c1f02 --- /dev/null +++ b/src/chroot-tools/chcleanup @@ -0,0 +1,57 @@ +#!/bin/bash +# (c) Nicolás Reynolds <fauno@parabola.nu> +# Released under GPLv3 +# +# Performs chroot cleanup smartly, it only removes the unneeded packages or +# leaves you with a cleansystem +# +# See: HOOKPREBUILD + +set -e +DRYRUN=${DRYRUN:-false} + +source /etc/makepkg.conf +source /etc/libretools.conf +source ${HOME}/.makepkg.conf 2>/dev/null|| true + +msg "Cleaning chroot..." + +TMPDIR="$(mktemp -d /tmp/$(basename $0)-XXXXX)" +cleanup_log="${TMPDIR}"/libretools-cleanup.log + +cp -a /var/lib/pacman/sync "${TMPDIR}/" +touch ${cleanup_log} + +# If we're running makepkg +if [ -f PKGBUILD ]; then + source PKGBUILD || true + + check=(${depends[@]} ${makedepends[@]} ${checkdepends[@]}) + +fi + +# Get the full list of packages needed by dependencies, including the base system +sudo pacman -b "${TMPDIR}" \ + -Sp \ + --print-format "%n" \ + base base-devel sudo \ + ${CHROOTEXTRAPKG[@]} \ + ${check[@]} \ + >${cleanup_log} + +# Diff installed packages against a clean chroot then remove leftovers +packages=($(comm -23 <(pacman -Qq | sort) \ + <(sort -u ${cleanup_log}))) + +[ ${#packages[@]} -eq 0 ] && exit 0 + +msg2 "Removing %d packages" ${#packages[@]} + +# Only remove leftovers, -Rcs removes too much +${DRYRUN} || sudo pacman --noconfirm -Rn ${packages[@]} +${DRYRUN} && echo ${packages[@]} + +# Cleanup +${DRYRUN} || rm -fr ${TMPDIR} + +exit $? diff --git a/src/chroot-tools/librechroot b/src/chroot-tools/librechroot new file mode 100755 index 0000000..c8e02b0 --- /dev/null +++ b/src/chroot-tools/librechroot @@ -0,0 +1,108 @@ +#!/bin/bash +# LibreChRoot +# Enters a chroot + +# Copyright 2010 Nicolás Reynolds +# Copyright 2011 Joshua Haase + +# ---------- GNU General Public License 3 ---------- + +# This file is part of Parabola. + +# Parabola 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. + +# Parabola 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 Parabola. If not, see <http://www.gnu.org/licenses/>. + +function usage { + + echo "" + echo "Usage: $0 [options] [chrootname]" + echo "Use it as root." + echo "" + echo "Default chroot name: $CHROOT" + echo "Default chrootdir: $CHROOTDIR" + echo "" + echo "OPTIONS:" + echo "" + echo " -c : clean the chroot using pacman" + echo " only 'base', 'base-devel' and 'sudo' on chroot" + echo " -d <chrootdir> : use <chrootdir> instead of default" + echo " -r : clean /repo on the chroot" + echo " -h : this message" + echo " -u : update the chroot" + echo "" + +} + +function clean_chroot { # Clean packages with pacman + cp -a "$(dirname $0)/chcleanup" "${CHROOTDIR}/${CHROOTNAME}/clean" + + mkarchroot -r "cd /build; /clean" "${CHROOTDIR}/${CHROOTNAME}" +} + +function clean_repo { + msg "Cleaning repo for chroot: ${CHROOTDIR}/${CHROOTNAME}" + if [ -d "${CHROOTDIR}/${CHROOTNAME}/repo" ]; then + find "${CHROOTDIR}/${CHROOTNAME}/repo/" -mindepth 1 -delete + else + mkdir -p "${CHROOTDIR}/${CHROOTNAME}/repo" + fi + bsdtar -czf "${CHROOTDIR}/${CHROOTNAME}/repo/repo.db.tar.gz" -T /dev/null + ln -s "repo.db.tar.gz" "${CHROOTDIR}/${CHROOTNAME}/repo/repo.db" +} +source /etc/libretools.conf + +if [ -e "$XDG_CONFIG_HOME/libretools/libretools.conf" ]; then + source "$XDG_CONFIG_HOME/libretools/libretools.conf" +fi + +CLEANCHROOT='false' +UPDATE='false' +CLEANREPO='false' +CHROOTNAME="${CHROOT:-${SUDO_USER:-root}}" + +while getopts 'hrcud:' arg; do + case $arg in + h) usage; exit 0 ;; + c) CLEANCHROOT='true' ;; + u) UPDATE='true' ;; + r) CLEANREPO='true' ;; + d) CHROOTDIR="$(readlink -e $OPTARG)" ;; + esac +done + +[[ "$UID" != "0" ]] && { + error "This script must be run as root." + exit 1 +} + +shift $(($OPTIND - 1)) + +if [ $# -eq 1 ]; then + CHROOTNAME="$1" +fi + +if "$CLEANREPO"; then + clean_repo +fi + +if "$CLEANCHROOT"; then + clean_chroot +elif "$UPDATE"; then + msg "Updating chroot: ${CHROOTDIR}/${CHROOTNAME}" + mkarchroot -u "${CHROOTDIR}/${CHROOTNAME}" +else + msg "Entering chroot: ${CHROOTDIR}/${CHROOTNAME}" + mkarchroot -r "bash" "${CHROOTDIR}/${CHROOTNAME}" +fi + +exit 0 diff --git a/src/chroot-tools/libremakepkg b/src/chroot-tools/libremakepkg new file mode 100755 index 0000000..f7924f6 --- /dev/null +++ b/src/chroot-tools/libremakepkg @@ -0,0 +1,126 @@ +#!/bin/bash +# Copyright 2010 - 2011 Nicolás Reynolds +# Copyright 2011 Joshua Ismael Haase Hernández + +# ---------- GNU General Public License 3 ---------- + +# This file is part of Parabola. + +# Parabola 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. + +# Parabola 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 Parabola. If not, see <http://www.gnu.org/licenses/>. + + +# set -x # uncomment for debug + +function copy_log { # copy logs if they exist + + find "${CHROOTDIR}/${CHROOT}/build/" -maxdepth 1 -name "*\.log" -exec cp {} ./ \; + +} + + +function trap_exit { # End inmediately but print a useful message + + copy_log + error "$@" + exit 1 + +} + +# Trap signals from makepkg +set -E +trap 'trap_exit "(libremakepkg): TERM signal caught. Exiting..."' TERM HUP QUIT +trap 'trap_exit "(libremakepkg): Aborted by user! Exiting..."' INT +trap 'trap_exit "(libremakepkg): An unknown error has occurred. Exiting..."' ERR + +source /etc/libretools.conf + +CLEANFIRST="false" +UPDATEFIRST="false" +CHECKNONFREE="true" +LIBRECHROOT_ARGS="" +MAKEPKG_ARGS="" + +function usage { + + echo '' + echo 'cd to a dir containing a PKGBUILD and run:' + echo '$0 [options] [-- makechrootpkg args [-- makepkg args]]' + echo 'This script will build your package on a chroot.' + echo '' + echo 'OPTIONS:' + echo '' + echo ' -h : show this message.' + echo ' -c : clean the chroot before building.' + echo ' -u : update the chroot before building.' + echo ' -d <chrootdir> : use this dir instead of "$CHROOTDIR"' + echo ' -n <chrootname> : use this dir instead of "$CHROOT".' + echo ' -N : do not check freedom issues' # As fullpkg-check will do that before + echo '' + exit 1 + +} + +while getopts 'hcud:n:N' arg ; do + case "${arg}" in + h) usage ;; + c) CLEANFIRST="true" ;; + u) UPDATEFIRST="true" ;; + d) CHROOTDIR="$OPTARG" + LIBRECHROOT_ARGS='-d "$OPTARG"' ;; + n) CHROOT="$OPTARG" ;; + N) CHECKNONFREE="false" ;; + esac +done + +# Pass all arguments after -- right to makechrootpkg +MAKEPKG_ARGS="$makepkg_args ${*:$OPTIND}" + +if (( EUID )); then + error "This script must be run as root" + exit 1 +fi + +if [ ! -e PKGBUILD ]; then # Check if we are actually on a build directory. Do this early. + error "This isn't a build directory"; usage +fi + +msg "Checking PKGBUILD for non-free issues" +if "$CHECKNONFREE"; then + if ! pkgbuild-check-nonfree; then + + if [[ $? -eq 15 ]]; then # other errors mean fail, not nonfree + error "PKGBUILD contains non-free issues" + exit 15 + else + warning "PKGBUILD couldn't be check aganist non-free issues" + fi + fi +fi + +if "$CLEANFIRST"; then + librechroot -c "$LIBRECHROOT_ARGS" "$CHROOT" +fi + +if "$UPDATEFIRST"; then + librechroot -u "$LIBRECHROOT_ARGS" "$CHROOT" +fi + +unset CLEANFIRST UPDATEFIRST LIBRECHROOT_ARGS + +makechrootpkg -d -r "$CHROOTDIR" -l "$CHROOT" -- $MAKEPKG_ARGS +ev="$?" # exit value + +copy_log + +exit $ev diff --git a/src/chroot-tools/libremkchroot b/src/chroot-tools/libremkchroot new file mode 100755 index 0000000..b576209 --- /dev/null +++ b/src/chroot-tools/libremkchroot @@ -0,0 +1,64 @@ +#!/bin/bash +# LibreMkChroot +# Creates a chroot + +# Copyright 2011, 2012 Luke Shumaker + +# ---------- GNU General Public License 3 ---------- + +# This file is part of Parabola. + +# Parabola 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. + +# Parabola 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 Parabola. If not, see <http://www.gnu.org/licenses/>. + +source /etc/libretools.conf + +if [ -e "$XDG_CONFIG_HOME/libretools/libretools.conf" ]; then + source "$XDG_CONFIG_HOME/libretools/libretools.conf" +fi + +cmd=${0##*/} +function usage { + echo "Usage: $cmd [OPTIONS]" + echo 'This script will create a chroot to build packages in.' + echo "Use \`librechroot' to interact with the chroot after it is created." + echo '' + echo 'Options:' + echo ' -h Show this message' + echo '' + echo ' -f Force overwrite of files in the working-dir' + echo '' + echo ' -d <chrootdir> Use this dir instead of "$CHROOTDIR".' + echo " -c <pacmandir> Location of pacman cache. Default: \`/var/cache/pacman/pkg'." + echo ' -C <file> Location of pacman config file.' + echo ' -M <file> Location of makepkg config file.' +} + +mkchroot_args=(); +while getopts 'hfd:c:C:M:' arg; do + case "$arg" in + h) usage; exit 0 ;; + f) mkchroot_args+=("-$arg");; + c|C|M) mkchroot_args+=("-$arg" "$OPTARG");; + d) CHROOTDIR=$OPTARG ;; + ?) usage; exit 1 ;; + esac +done + +if (( EUID )); then + error "This script must be run as root" + exit 1 +fi + +mkdir -p "${CHROOTDIR}" +xargs -d'\n' mkarchroot "${mkchroot_args[@]}" "${CHROOTDIR}/root" < /etc/libretools.d/cleansystem diff --git a/src/diff-unfree b/src/diff-unfree new file mode 100755 index 0000000..a0a8d63 --- /dev/null +++ b/src/diff-unfree @@ -0,0 +1,85 @@ +#!/bin/bash +# This script will help you diff a *-libre PKGBUILD against the unfree one +# to check for updates. +# Copyright 2010 Nicolás Reynolds + +# ---------- GNU General Public License 3 ---------- + +# This file is part of Parabola. + +# Parabola 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. + +# Parabola 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 Parabola. If not, see <http://www.gnu.org/licenses/>. + +source /etc/libretools.conf +custom_config=$XDG_CONFIG_HOME/libretools/libretools.conf + +[[ "$1" == "--help" ]] && { + msg "Diff-Unfree helps you diff build scripts from ABSLibre against + (Unfree) ABS. Package name and repo will we guessed if you don't + specify them." + msg2 "Usage: $0 [community|packages] [unfree-package] [repo]" + exit 0 +} + +[[ ! -r PKGBUILD ]] && { + error "This is not a build dir." + exit 1 +} + +package_guess=$(basename $PWD) + +repo=${1:-$(basename $(dirname $PWD))} +package=${2:-${package_guess/-libre}} +trunk=${3:-trunk} + +tmp_dir=$(mktemp -d /tmp/${package}.XXXXXX) + +svnrepo="packages" +case $repo in + community*) + svnrepo="community" + ;; + multilib*) + svnrepo="community" + ;; + *) + ;; +esac + +unfree_dir="${tmp_dir}/${svnrepo}/${package}/${trunk}" + +[[ ! -d "${tmp_dir}" ]] && { + error "Can't create temp dir" + exit 1 +} + +stdnull 'pushd "${tmp_dir}"' + +msg "Getting diff from $repo/$package..." + +stdnull 'svn checkout --depth=empty svn://svn.archlinux.org/$svnrepo' + +cd ${svnrepo} +svn update ${package} + +# Back to start dir +stdnull popd + +msg "Diffing files" + +for _file in ${unfree_dir}/*; do + msg2 "$(basename "${_file}")" + ${DIFFTOOL} "$PWD/$(basename "${_file}")" "${_file}" +done + +exit $? diff --git a/src/fullpkg/fullpkg b/src/fullpkg/fullpkg new file mode 100755 index 0000000..9a03b82 --- /dev/null +++ b/src/fullpkg/fullpkg @@ -0,0 +1,34 @@ +#!/bin/bash +# set -x # uncomment for debug +# Builds packages from ABS recursively. It tries to find dependencies that +# aren't built or need update and then makepkg them in order. + +usage() { + + echo "cd to a dir containing a PKGBUILD and run:" + echo "$0 [build_dir]" + echo "" + echo "This script will check dependencies, build them if possible " + echo "and stage the packages on it's repo." + echo "" + echo "OPTIONS:" + echo " -h : this message." + echo "" + echo "Wrapper for \`fullpkg-find' and \`fullpkg-build'" + echo "" + exit 1 + +} + +while getopts 'haA:l:nm:' arg; do + case "$arg" in + h) usage ;; + esac +done + +shift $(( OPTIND - 1 )) + +build_dir="${1:-$(mktemp -d /tmp/fullpkg.XXXXXX)}" +fullpkg-find "$build_dir" && fullpkg-build -N "$build_dir" + +exit 0 diff --git a/src/fullpkg/fullpkg-build b/src/fullpkg/fullpkg-build new file mode 100755 index 0000000..b497db5 --- /dev/null +++ b/src/fullpkg/fullpkg-build @@ -0,0 +1,211 @@ +#!/bin/bash +# set -x # uncomment for debug +# Builds packages from ABS recursively. It tries to find dependencies that +# aren't built or need update and then makepkg them in order. + +# TODO move __build to chroot + +source /etc/makepkg.conf +source /etc/libretools.conf + +if [ -e $XDG_CONFIG_HOME/libretools/libretools.conf ]; then + source $XDG_CONFIG_HOME/libretools/libretools.conf +fi + + +## List packages on log that are on status +## usage: list_pkgs <status> <message> +# +## status: nonfree, built, failed, unstaged +list_pkgs() { + msg="$2" + local pkgs=($(grep "$1:" $build_dir/log)) && { + msg "$2" + echo ${pkgs[@]} | tr " " "\n" | cut -d: -f2 + } +} + +# return : full version spec, including epoch (if necessary), pkgver, pkgrel +# usage : get_fullver( ${epoch:-0}, $pkgver, $pkgrel ) +get_fullver() { + if [[ $1 -eq 0 ]]; then +# zero epoch case, don't include it in version + echo $2-$3 + else + echo $1:$2-$3 + fi + +} + +## Check all build_dir, fails if one PKGBUILD is nonfree +check_nonfree() { + find "$build_dir" -name PKGBUILD \ + -exec pkgbuild-check-nonfree {} + + if [ "$?" -eq 15 ]; then + error "Some PKGBUILD have nonfree problems" + exit 15 + fi + +} + +# Removes a package from the buildorder +# $1 package name +# $2 buildorder file +remove_buildorder() { + grep -Evw "${1}" ${2} > ${2}2 + mv -f ${2}2 ${2} + + return $? +} + +succesfull_build() { + + if [ "$RUN" != "$FULLBUILDCMD" ]; then + return 0 # Custom command or download sources + fi + + if source .INFO && [ -n "$repo" ]; then + + if [ ! -z "$HOOKLOCALRELEASE" ]; then + find -name "*.pkg.tar.?z" -print0 | xargs -0 "$HOOKLOCALRELEASE" "$repo" + fi + + librestage $repo || echo "unstaged:$(basename $PWD)" >>$build_dir/log + + msg "Updating pacman db and packages" + sudo pacman -Sy || true + + fi + + echo "built:$(basename $PWD)" >>$build_dir/log +} + +build_description() { + list_pkgs "nonfree" "Those packages contain nonfree deps:" + list_pkgs "built" "Those packages were built and staged:" + list_pkgs "failed" "Those packages failed to build:" + list_pkgs "unstaged" "Those packages couldn't be staged (missing reponame):" +} + +__build() { + pushd ${build_dir} >/dev/null + + build_packages=($(sort -gr $buildorder | cut -d: -f2)) # greater levels must be built first + + while [ ${#build_packages[@]} -ge 1 ]; do + + pushd "$build_dir/${build_packages[0]}" >/dev/null + + if [ -n "${HOOKPKGBUILDMOD}" ]; then + ${HOOKPKGBUILDMOD} || true + fi + + eval "$RUN"; r=$? + + case $r in + + 0) succesfull_build ;; + + *) error "There were errors while trying to build the package." + echo "failed:$(basename $PWD)" >>$build_dir/log + ;; + esac + + remove_buildorder "${build_packages[0]}" $buildorder || true + +# which is next package? + build_packages=($(sort -gr $buildorder | cut -d: -f2)) + popd > /dev/null + done + + popd >/dev/null +} + +# End inmediately but print a useful message +trap_exit() { + error "$@" + warning "Leftover files left on $build_dir" + mv .BUILDORDER BUILDORDER + exit 1 +} + +# Trap signals from makepkg +set -E +trap 'trap_exit "(fullpkg-build) TERM signal caught. Exiting..."' TERM HUP QUIT +trap 'trap_exit "(fullpkg-build) Aborted by user! Exiting..."' INT +trap 'trap_exit "(fullpkg-build) An unknown error has occurred. Exiting..."' ERR + +CLEANUP="false" +CHECKNONFREE="true" +RUN="$FULLBUILDCMD" +MESSAGE="Building packages" + +usage() { + + echo "" + echo "$(basename $0) [options] <build_dir>" + echo "" + echo "Builds packages from build_dir, create a build_dir using:" + echo "'fullpkg-find <build_dir>'" + echo "" + echo "If no <build_dir> is specified, it uses the current directory." + echo "" + echo "OPTIONS:" + echo " -h : this message." + echo " -c : clean <build_dir> on succesfull build" + echo " -N : don't check for freedom issues." #Also made by fullpkg-find + echo " -r \"command\" : use this instead of \"$FULLBUILDCMD\"." + echo " -g : get sources for building packages on build_dir." + echo "" + exit 1 + +} + +while getopts 'hNr:g' arg; do + case $arg in + h) usage ;; + c) CLEAN ;; + N) CHECKNONFREE="false" ;; + r) RUN="$OPTARG" + MESSAGE="Executing custom action";; + g) RUN='makepkg -g > /dev/null' + MESSAGE="Downloading packages";; + esac +done + +shift $(( OPTIND - 1 )) +build_dir="${1:-`pwd`}" +buildorder="${build_dir}/BUILDORDER" + +if [ ! -e "$buildorder" ]; then + error "This is not a build_dir. Make one using fullpkg." + usage +else +# backup BUILDORDER + cp "$buildorder" "$build_dir/.BUILDORDER" +fi + +if "$CHECKNONFREE"; then + check_nonfree +fi + +if [ -z "$FULLBUILDCMD" ]; then + error "Set your FULLBUILDCMD on libretools.conf" +fi + +msg "$MESSAGE" +__build + +if [ "$RUN" != "$FULLBUILDCMD" ]; then + # Used for downloading or custom command + mv "$build_dir/.BUILDORDER" "$buildorder" + exit 0 +elif "$CLEANUP"; then + find "$build_dir" -mindepth 1 -delete +fi + +build_description + +plain "Test packages on and if they work fine librerelease." + +exit 0 diff --git a/src/fullpkg/fullpkg-find b/src/fullpkg/fullpkg-find new file mode 100755 index 0000000..e188ec8 --- /dev/null +++ b/src/fullpkg/fullpkg-find @@ -0,0 +1,212 @@ +#!/bin/bash +# set -x # uncomment for debug +# Builds packages from ABS recursively. It tries to find dependencies that +# aren't built or need update and then makepkg them in order. + +# TODO: fullpkg-find should find packages wich depend on the +# package to be build, so we can avoid "missing $name.so errors" + +# Get repo name. Asumes ${ABSROOT}/repo/package/PKGBUILD +guess_repo() { + basename $(dirname $(pwd)) +} + +# return : full version spec, including epoch (if necessary), pkgver, pkgrel +# usage : get_fullver( ${epoch:-0}, $pkgver, $pkgrel ) +get_fullver() { + if [[ $1 -eq 0 ]]; then +# zero epoch case, don't include it in version + echo $2-$3 + else + echo $1:$2-$3 + fi + +} + +copy_files() { + + local copydir="$build_dir/${pkgbase:-${pkgname[0]}}" + mkdir -p "$copydir" + + # Copy PKGBUILD and sources + cp PKGBUILD "$copydir" + ( + source PKGBUILD + for file in "${source[@]}"; do + file="${file%%::*}" + file="${file##*://*/}" + if [[ -f $file ]]; then + cp "$file" "$copydir/" + elif [[ -f $SRCDEST/$file ]]; then + cp "$SRCDEST/$file" "$copydir/" + fi + done + + # Find all changelog and install files, even inside functions + for i in 'changelog' 'install'; do + while read -r file; do + # evaluate any bash variables used + eval file=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$file")\" + [[ -f $file ]] && cp "$file" "$copydir" + done < <(sed -n "s/^[[:space:]]*$i=//p" PKGBUILD) + done + ) +} + +# Checks ABSROOT and look for target pkg deps. Adds them if not built or outdated. +find_deps() { +# Check this level + source /etc/makepkg.conf + source PKGBUILD + + local repo="${repo:-$(guess_repo)}" + local pkgbase="${pkgbase:-${pkgname[0]}}" + local fullver="$(get_fullver ${epoch:-0} ${pkgver} ${pkgrel})" + + if ! pkgbuild-check-nonfree > /dev/null 2> /dev/null; then + if [ "$?" -eq 15 ]; then + error "pkgbase" has nonfree issues + return 15 + fi + fi + + # Checking any package built, since otherwise e.g. kdebase would + # be always considered outdated: there is no package built named kdebase. + # TODO: maybe check for the package requested in case of recursive calls, + # instead of the first one listed? + if is_built "${pkgname[0]}" "${fullver}"; then + exit 0 # pkg is built and updated + fi + +# greater levels are built first + echo "${LEVEL}:${pkgbase}" >>"$build_dir/BUILDORDER" +# PKGBUILD is already there + if [ -d "${build_dir}/${pkgbase}" ]; then + exit 0 +# Copy dir to build_dir + else + copy_files + +# to identify repo later + echo "repo=$repo" > "${build_dir}/${pkgbase}/.INFO" + fi + +# current package plus a space for every level + msg2 "%${LEVEL}s${pkgbase}-${fullver}" + +## Check next levels + declare -i next_level=$LEVEL+1 + +# All deps in separate line, only once, without version. + deps=($(echo "${depends[@]} ${makedepends[@]}" | \ + sed "s/[=<>]\+[^ ]\+//g" | \ + tr ' ' "\n" | \ + sort -u)) + + for _dep in ${deps[@]}; do + + local found=false + # May fail, e.g. since abslibre-mips64el doesn't include + # arch=any packages. + local pkgdir=$(toru -p ${_dep}) || true + + if [ -n "$pkgdir" -a -d "${pkgdir}" ]; then + found=true + + pushd "${pkgdir}" > /dev/null +# runs itself on dep's PKGBUILD dir + $0 -l ${next_level} ${build_dir} || return $? + popd > /dev/null + fi + + if ! (( found )); then + echo "dep_not_found:$_dep" >>$build_dir/log + fi + + done + +## End variable block + + unset next_level dir +} + +source /etc/libretools.conf + +if [ -e $XDG_CONFIG_HOME/libretools/libretools.conf ]; then + source $XDG_CONFIG_HOME/libretools/libretools.conf +fi + +LEVEL=0 +MAXLEVEL=20 +CLEANFIRST='false' +UPDATEDB='true' + +usage() { + + echo "" + echo "cd to a dir containing a PKGBUILD and run:" + echo "$(basename $0) [options] <build_dir>" + echo "" + echo "This script will create a build_dir for recursive building" + echo "it tries to find dependencies that aren't built or need update." + echo "" + echo "If no <build_dir> is specified, the script works on a tempdir" + echo "" + echo "OPTIONS:" + echo " -h : this message." + echo " -A <absroot> : use this ABSROOT." + echo " -c : clean <build_dir> before working." + echo " -m <max_level> : check deps until this level" + echo " -n : don't update pacman db." + echo "" + exit 1 + +} + +while getopts 'hA:l:cmn' arg; do + case "$arg" in + h) usage ;; + A) ABSROOT="$OPTARG" ;; + l) LEVEL="$OPTARG" ;; # hidden option to know dep level. + c) CLEANFIRST='true' ;; + m) MAXLEVEL="$OPTARG" ;; + n) UPDATEDB='false' ;; + esac +done + +if [ ! -r PKGBUILD ]; then + error "This directory doesnt contain a PKGBUILD" + usage +fi + +shift $(( OPTIND - 1 )) +build_dir="${1}" + +if [ "$LEVEL" -eq 0 ]; then + + build_dir="${1:-$(mktemp -d /tmp/fullpkg.XXXXXX)}" + + if [ ! -d "$build_dir" ]; then + mkdir -p "$build_dir" + elif "$CLEANFIRST"; then + # Erase files already in dir + msg "Cleaning up files in dir" + find "$build_dir" -mindepth 1 -delete + fi + + if "$UPDATEDB"; then + msg "Updating pacman db" + sudo pacman -Sy --noconfirm || true + fi + +# make files for log and buildorder + touch "${build_dir}"/{log,BUILDORDER} + buildorder="${build_dir}/BUILDORDER" + + msg "Checking dependencies" +fi + +# Find the dependencies on the ABS itself +find_deps + +exit 0 diff --git a/src/is_built b/src/is_built new file mode 100755 index 0000000..1fa79d2 --- /dev/null +++ b/src/is_built @@ -0,0 +1,36 @@ +#!/bin/bash +usage() { + echo "$0 " + echo + echo "Detect if a given package version is already in repos" + echo "Assuming you want greater or equal" + echo + echo "Example usage: is_built 'pcre' '20'" +} + +while getopts 'h' arg; do + case $arg in + h) usage; exit 0 ;; + *) usage; exit 1 ;; + esac +done + +ver=${2} +pkg=${1} +pver=$(LC_ALL=C pacman -Sddp --print-format "%v" "${pkg}" 2>/dev/null) + +# if pacman fails or returns nothing +r=$? +[ "${pver}" = " there is nothing to do" ] && r=1 + +result=$(vercmp "${pver}" "${ver}") + +# if vercmp > 1 means our version is bigger +if [ ${result} -ge 0 -a ${r} -eq 0 ]; then + exit 0 +else + exit 1 +fi + +# just in case +exit 1 diff --git a/src/is_unfree b/src/is_unfree new file mode 100755 index 0000000..f32c193 --- /dev/null +++ b/src/is_unfree @@ -0,0 +1,11 @@ +#!/bin/bash +# Checks if a package is on blacklist + +# fail immediately on error +set -E + +blacklist="$XDG_CONFIG_HOME/libretools/blacklist.txt" + +egrep -q "^${1}:" "${blacklist}" + +exit $? diff --git a/src/librediff b/src/librediff new file mode 100755 index 0000000..1f39eb9 --- /dev/null +++ b/src/librediff @@ -0,0 +1,65 @@ +#!/bin/bash +# Generates a patch for a nonfree PKGBUILD +# +# Copyright 2010 Nicolás Reynolds + +# ---------- GNU General Public License 3 ---------- + +# This file is part of Parabola. + +# Parabola 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. + +# Parabola 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 Parabola. If not, see <http://www.gnu.org/licenses/>. + +usage() { + echo "Usage: $0 <pkgname> [<pkgname2> ...]" + echo "Requirements:" + echo "* Have a <pkgname>/ directory with nonfree build scripts inside" + echo "* Have a <pkgname>-libre/ directory with libre build scripts inside" +} + +# Load custom config or system-wide config +custom_config=$XDG_CONFIG_HOME/libretools/libretools.conf +if [ -e $custom_config ]; then + source $custom_config +else + source /etc/libretools.conf +fi + +# Print usage if no package has been given +[[ -z "$@" ]] && { + usage + exit 1 +} + + +for package in $@; do +# Continue on errors + [[ ! -d ./${package} || ! -d ./${package}-libre ]] && { + error "no matching ${package} and ${package}-libre found" + continue + } + + [[ ! -f ./${package}/PKGBUILD || ! -f ./${package}-libre/PKGBUILD ]] && { + error "no matching PKGBUILDs found for ${package}-libre" + continue + } + + source ./${package}-libre/PKGBUILD + [[ -z ${pkgbase} ]] && pkgbase=${pkgname} + +# Generate a diff file, no -r since we don't want to patch src/ nor pkg/ + diff -auN ${package} ${package}-libre > $PATCHDIR/${pkgbase}-${pkgver}-${pkgrel}.patch + +done + +exit 0 diff --git a/src/libremessages b/src/libremessages new file mode 100755 index 0000000..68badb8 --- /dev/null +++ b/src/libremessages @@ -0,0 +1,107 @@ +# Copyright (c) 2006-2010 Pacman Development Team <pacman-dev@archlinux.org> +# Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> +# Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> +# Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org> +# Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu> +# Copyright (c) 2006 by Alex Smith <alex@alex-smith.me.uk> +# Copyright (c) 2006 by Andras Voroskoi <voroskoi@frugalware.org> +# Copyright (c) 2011 by Joshua Haase <hahj87@gmail.com> +# +# 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/>. + +# gettext initialization +export TEXTDOMAIN='libretools' +export TEXTDOMAINDIR='/usr/share/locale' + +# check if messages are to be printed using color +unset ALL_OFF BOLD BLUE GREEN RED YELLOW +if [[ -t 2 ]]; then + # prefer terminal safe colored and bold text when tput is supported + if tput setaf 0 &>/dev/null; then + ALL_OFF="$(tput sgr0)" + BOLD="$(tput bold)" + PURPLE="${ALL_OFF}$(tput setaf 5)" + BLUE="${BOLD}$(tput setaf 4)" + GREEN="${BOLD}$(tput setaf 2)" + RED="${BOLD}$(tput setaf 1)" + YELLOW="${BOLD}$(tput setaf 3)" + else + ALL_OFF="\e[1;0m" + BOLD="\e[1;1m" + BLUE="${BOLD}\e[1;34m" + GREEN="${BOLD}\e[1;32m" + RED="${BOLD}\e[1;31m" + YELLOW="${BOLD}\e[1;33m" + PURPLE="${BOLD}\033[1;30;40m" + fi +fi +readonly ALL_OFF BOLD BLUE GREEN RED YELLOW PURPLE + +stdnull() { + eval "$@ >/dev/null 2>&1" +} + +plain() { + local mesg=$1; shift + printf "${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 +} + +msg() { + local mesg=$1; shift + printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 +} + +msg2() { + local mesg=$1; shift + printf "${BLUE} ->${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 +} + +warning() { + local mesg=$1; shift + printf "${YELLOW}==> $(gettext "WARNING:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 +} + +error() { + local mesg=$1; shift + printf "${RED}==> $(gettext "ERROR:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2 +} + +stat_busy() { + local mesg=$1; shift + printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}...${ALL_OFF}" >&2 +} + +stat_done() { + printf "${BOLD}done${ALL_OFF}\n" >&2 +} + +# Set the terminal title +# TODO test on several terms - it works on screen/tmux +term_title() { + printf "\033k%s\033\\" "$@" +} + +# usage : in_array( $needle, $haystack ) +in_array() { + [[ $2 ]] || return 1 # Not found + + local needle=$1; shift + local item + + for item in "$@"; do + [[ ${item#@} = $needle ]] && return 0 # Found + done + + return 1 # Not Found +} diff --git a/src/librerepkg b/src/librerepkg new file mode 100755 index 0000000..d506003 --- /dev/null +++ b/src/librerepkg @@ -0,0 +1,72 @@ +#!/bin/bash +# Copyright 2011 Joshua Ismael Haase Hernandez + +# ---------- GNU General Public License 3 ---------- + +# This file is part of Parabola. + +# Parabola 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. + +# Parabola 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 Parabola. If not, see <http://www.gnu.org/licenses/>. + +source /etc/libretools.conf +custom_config=$XDG_CONFIG_HOME/libretools/libretools.conf +if [ -x $custom_config ]; then + source $custom_config; + unset $custom_config +fi + +[[ ! -r rePKGBUILD ]] && { + error "This build does not contains a rePKGBUILD." + exit 1 +} + +source /etc/makepkg.conf +source /etc/abs.conf +source rePKGBUILD + +usage() { + echo "cd to a dir with a rePKGBUILD and other file info and run" + echo "$0 [makepkg flags]" + echo + echo "This script will repackage an arch package without compiling" +} + +while getopts 'h' arg; do + case $arg in + h) usage; exit 0 ;; + esac +done + +makepkgflags=$@ + +tempdir=$(mktemp -d /tmp/$(basename $PWD).XXXXX) + +msg "Copying files" +cp ./* ${tempdir}/ + +for _arch in ${arch[@]}; do + + msg "Repackaging: $pkgname $pkgver-$pkgrel ($(date -u))" + + stdnull pushd ${tempdir} + + msg2 "Updating md5sums" + makepkg -gp rePKGBUILD >> rePKGBUILD + + echo "export CARCH=${_arch}" >> rePKGBUILD + + msg "Repackaging using makepkg" + makepkg -Lcdp rePKGBUILD ${makepkgflags} + + stdnull popd ${tempdir} +done diff --git a/src/mips64el-tools/add-mips64el b/src/mips64el-tools/add-mips64el new file mode 100755 index 0000000..e06d857 --- /dev/null +++ b/src/mips64el-tools/add-mips64el @@ -0,0 +1,6 @@ +#!/bin/bash +# Change all arch array that aren't any or mips64el already + +find -name 'PKGBUILD' -exec sed -i "s/^\(arch=([^)anym]\+\))/\1 'mips64el')/" '{}' \; + +exit $? diff --git a/src/mips64el-tools/librebasebuilder b/src/mips64el-tools/librebasebuilder new file mode 100755 index 0000000..f7d3a25 --- /dev/null +++ b/src/mips64el-tools/librebasebuilder @@ -0,0 +1,84 @@ +#!/bin/bash +# -*- coding: utf-8 -*- +# Copyright (C) 2012 Michał Masłowski <mtjm@mtjm.eu> +# +# 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 Affero 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/>. + + +set -e + +# TODO: + +# - make it more configurable + +# - compare the result with previous base images + +for arg in "$@" ; do + case "$arg" in + -h|--h|--he|--hel|--help|-\?) + echo 'Usage: librebasebuilder + +Make a base tarball named parabola-mips64el-DATE.tar.bz2. + +This script must be run as root.' >&2 + exit 0 + ;; + esac +done + +[[ "$UID" != "0" ]] && { + echo "This script must be run as root." >&2 + exit 1 +} + +tempdir=/home/chroot/base +outdir=$(pwd) + +mkarchroot -n $tempdir mkinitcpio base sudo parted nano zile vi ed openssh + +cd $tempdir + +# Don't list mtjm's DNS servers. +cat > etc/resolv.conf <<EOF +# +# /etc/resolv.conf +# + +#search <yourdomain.tld> +#nameserver <ip> + +# End of file +EOF + +# From pacman-mirrorlist-libre-20120307-1. Remember to escape dollars. +cat > etc/pacman.d/mirrorlist <<EOF +# Parabola GNU/Linux - Last Updated: Wed Mar 7 17:33:36 GMT 2012 + +# Atlanta, GA, USA +# Responsible: belos +Server = http://parabola.techno-geeks.org/\$repo/os/\$arch + +# Nuremberg, Germany +# Responsible: johkra +Server = http://parabolaweb.eu/\$repo/os/\$arch + +# UK +# Responsible: Parabola Project +Server = http://repo.parabolagnulinux.org/\$repo/os/\$arch + +EOF + +rm .arch-chroot + +tar cjf $outdir/parabola-mips64el-$(LC_ALL=C date -u +%Y%m%d).tar.bz2 . diff --git a/src/mips64el-tools/mips-add b/src/mips64el-tools/mips-add new file mode 100644 index 0000000..da9b431 --- /dev/null +++ b/src/mips64el-tools/mips-add @@ -0,0 +1,7 @@ +#!/bin/bash +source /etc/libretools.conf +if ! grep mips64el PKGBUILD >/dev/null; then # Add mips64el in ${arch} array if it isn't 'any' + warning "Adding mips64el arch" + sed -i "s/^\(arch=([^)anym]\+\))/\1 'mips64el')/" "PKGBUILD" + librecommit PKGBUILD +fi diff --git a/src/mips64el-tools/mips64el.conf b/src/mips64el-tools/mips64el.conf new file mode 100644 index 0000000..836b407 --- /dev/null +++ b/src/mips64el-tools/mips64el.conf @@ -0,0 +1,12 @@ +## Arquitecture specific commands + +## Run a command for PKGBUILD modifications before building +## Like adding 'mips64el' to arch if it's not there +# HOOKPKGBUILDMOD="mips-add" + +## Run a command for local releasing of packages +# Useful for mass packaging (ie. mips port) +# Must accept the following parameters even if the command won't use them: +# $1 repo name +# $2+ packages +# HOOKLOCALRELEASE="mipsrelease" diff --git a/src/mips64el-tools/mipsrelease b/src/mips64el-tools/mipsrelease new file mode 100755 index 0000000..4d7a7de --- /dev/null +++ b/src/mips64el-tools/mipsrelease @@ -0,0 +1,65 @@ +#!/bin/bash +# Lic: GPLv3+ +# Author: Nicolas Reynolds <fauno@kiwwwi.com.ar> +# Local release of mips64el packages + clean ABS sync +# Called by HOOKLOCALRELEASE + +# $1 repo +# $2+ packages + +source /etc/makepkg.conf +source /etc/libretools.conf + +libretoolsdir="$(dirname $0)/../" + +usage() { + echo "$0 repo package1 [ package2 ... packageN ]" + echo + echo " release packages locally on ${PKGDEST}/stage3." + echo " and make a clean ABS sync " +} + +## +# usage : get_full_version( $epoch, $pkgver, $pkgrel ) +# return : full version spec, including epoch (if necessary), pkgver, pkgrel +## +get_full_version() { + if [[ $1 -eq 0 ]]; then + # zero epoch case, don't include it in version + echo $2-$3 + else + echo $1:$2-$3 + fi +} + +repo=$1; shift + +if [ -z "${repo}" ]; then + error "Empty repo" + exit 1 +fi + +# Get all needed sources +source PKGBUILD +fullver=$(get_full_version ${epoch:-0} ${pkgver} ${pkgrel}) +pkgs=() +makepkg --source -f --skippgpcheck + +msg "Adding packages to [stage3]..." +for name in ${pkgname[@]}; do + msg2 "${name} ${fullver}" + pkgs+=("${PKGDEST}/${name}-${fullver}-*.pkg.tar.*") +done + +repo-add ${PKGDEST}/stage3.db.tar.gz ${pkgs[@]} + +librestage ${repo} + + +mkdir -p ${WORKDIR}/abs/${CARCH}/${repo} >/dev/null + +pushd ${WORKDIR}/abs/${CARCH}/${repo} >/dev/null + tar xvf $SRCPKGDEST/${pkgbase:-${pkgname[0]}}-${fullver}${SRCEXT} +popd >/dev/null + +exit $? diff --git a/src/pkgbuild-check-nonfree b/src/pkgbuild-check-nonfree new file mode 100755 index 0000000..df0ff36 --- /dev/null +++ b/src/pkgbuild-check-nonfree @@ -0,0 +1,205 @@ +#!/bin/bash +# pkgbuild-check-nonfree +# Copyright 2010 Joshua Ismael Haase Hernández, Joseph Graham + +# ---------- GNU General Public License 3 ---------- + +# This file is part of Parabola. + +# Parabola 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. + +# Parabola 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 Parabola. If not, see <http://www.gnu.org/licenses/>. + +# function log_end { +# kill "$teepid" +# rm "$logpipe" +# } + +# function log { +# LOG="pkgbuild-check-nonfree-$(date -u +%Y%m%d).log" +# # ensure overridden package variables survive tee with split packages +# logpipe="$(mktemp -u "$startdir/logpipe.XXXXXXXX")" +# mkfifo "$logpipe" +# tee "$LOG" < "$logpipe" & +# teepid=$! +# trap log_end ERR EXIT +# } + + +function unset_pkgbuild { + + unset 'pkgbase' 'pkgname' 'pkgver' 'pkgrel' 'epoch' 'pkgdesc' \ + 'arch' 'url' 'license' 'groups' 'optdepends' 'provides' \ + 'conflicts' 'replaces' 'backup' 'options' 'install' \ + 'changelog' 'source' 'noextract' 'md5sums' 'build' \ + 'check' 'package' 'depends' 'makedepends' 'checkdepends' + +} + +function assert_pkgbuild { + + if [ -e "$1" ]; then + + source "$1" + if [ -n "${pkgname[0]}" ]; then + return 0 # valid PKGBUILD + fi + + fi + + error "$1 is not a valid PKGBUILD" + return 1 +} + +function check_replacement { + + [ $2 ] || return 0 # Free (not found) + local needle=$1; shift + local item + local rep + for line in $@; do + + item="$(echo "$line" | cut -d':' -f1)" + rep="$(echo "$line" | cut -s -d':' -f2)" + + if [ "$item" == "$needle" ]; then + if [ -z "$rep" ]; then + return 15 # Nonfree (found) + else + echo "$rep" + return 0 # Free (has replacement) + fi + fi + + done + return 0 # Free (not found) +} + +function get_blacklist { # Download the blacklist. + + pushd "$XDG_CONFIG_HOME/libretools" >/dev/null + + msg "Downloading the blacklist of proprietary software packages." + + if ! wget -N -q -O blacklist.txt "${BLACKLIST}" 2>/dev/null; then + + if [ -e "$XDG_CONFIG_HOME/libretools/blacklist.txt" ]; then + warning "Using local copy of blacklist" + else + error "Download failed, exiting" + fi + + fi + + popd > /dev/null +} + +function check_deps { # Check wheter a package depends on non-free + + unset_pkgbuild + + if ! assert_pkgbuild "$1"; then + return 1 # not PKGBUILD + fi + + msg2 "${pkgbase:-${pkgname[0]}} $pkgver $pkgrel ${epoch:-""}" # > "$logpipe" + + for pkg in ${pkgname[@]} ${depends[@]} ${makedepends[@]} ${checkdepends[@]}; do + + lines=($(grep "$pkg" "$XDG_CONFIG_HOME/libretools/blacklist.txt" | tr " " "_")) + + rep="$(check_replacement $pkg ${lines[@]})" + freedom=$? + + if [ "$freedom" -eq 15 ]; then + warning "found $pkg" # > "$logpipe" + ev=15 + continue + + elif [ -n "$rep" ]; then + + if [ "$rep" = "$pkg" ]; then + plain "$pkg is repackaged with the same name." # > "$logpipe" + continue + else + plain "$pkg -> $rep" # > "$logpipe" + continue + fi + + fi + + done + +} + +function usage { + # TODO: implement PKGBUILD arguments + echo "" + echo "$(basename $0) [options] [PKGBUILD1 PKGBUILD2 ...]" + echo "" + echo "OPTIONS" + echo "" + echo " -h : this message" + echo "" + echo "If no PKGBUILD is specified, one is searched on current directory" + + exit 1 +} + +while getopts 'h' arg; do + case "$arg" in + h) usage ;; + esac +done + +if [ -w / ]; then + error "Run as normal user" +fi + +source /etc/libretools.conf +if [ -e "$XDG_CONFIG_HOME/libretools/libretools.conf" ]; then + source "$XDG_CONFIG_HOME/libretools/libretools.conf" +fi + +if [ -z "${BLACKLIST}" ]; then + error "BLACKLIST variable is not set your libretools.conf file" + exit 1 +fi + +if [ ! -d "$XDG_CONFIG_HOME/libretools" ]; then + mkdir -p "$XDG_CONFIG_HOME/libretools" +fi + +startdir=`pwd` + +get_blacklist +# log + +shift $(( OPTIND - 1)) + +msg "Looking for unfree dependencies" + +if [ $# -ge 1 ]; then + + for p in $@; do + if [ -n "$p" ]; then + check_deps "$p" + fi + done + +else + + check_deps "`pwd`/PKGBUILD" + +fi + +exit $ev diff --git a/src/prtools/prfullpkg b/src/prtools/prfullpkg new file mode 100755 index 0000000..bbb8d73 --- /dev/null +++ b/src/prtools/prfullpkg @@ -0,0 +1,398 @@ +#!/bin/bash + +source /etc/makepkg.conf +source /etc/abs.conf +source /etc/libretools.conf +source /etc/libretools.d/prtools.conf + +if [ -z $XDG_CONFIG_HOME ]; then # Avoid /libretools dir doesn't exist errors + + error "There's no XDG_CONFIG_HOME var set"; exit 1 + +elif [ -e $XDG_CONFIG_HOME/libretools/libretools.conf ]; then + + source $XDG_CONFIG_HOME/libretools/libretools.conf + +fi + + +function usage { + + echo "cd to a dir containing a PKGBUILD and run:" + echo "$0 [options]" + printf "This script will check dependencies, build them if possible " + printf "and stage the packages on it's repo." + echo + echo "OPTIONS:" + echo " -h : this message." + echo " -a absdir : set absdir as ABSROOT." + echo " -b build_dir : use a fullpkg build_dir and only build." + echo " -c : check deps only, do not build." + echo " -d build_dir : use this dir to build. Defaults to mktemp." + echo " -n : don't update pacman db." + echo " -m max_level : check deps until this level" + echo " -r \"command\" : use this instead of \"$FULLBUILDCMD\"" + echo + exit 1 + +} + +function remove_buildorder { # Removes a package from the buildorder +# $1 package name +# $2 buildorder file + + grep -Evw "${1}" ${2} > ${2}2 + mv -f ${2}2 ${2} + +} + +function guess_repo { # Get repo name. Asumes ${ABSROOT}/package/repo/PKGBUILD + + basename $(pwd) + +} + +function get_fullver { # return : full version spec, including epoch (if necessary), pkgver, pkgrel + +# usage : get_fullver( ${epoch:-0}, $pkgver, $pkgrel ) + + if [[ $1 -eq 0 ]]; then + # zero epoch case, don't include it in version + echo $2-$3 + else + echo $1:$2-$3 + fi + +} + +function cleanup { # Cleans the build_dir. + + [ ! -d "${build_dir}" -o "${build_only}" = 'y' ] && return 0 # Do nothing or already cleaned. + + + if [ $level -eq 0 ]; then # Only do cleanup on level 0. + msg "Cleaning up ${build_dir}" + rm -rf "$build_dir/*" + fi +} + +function find_deps { # Checks ABSROOT and look for target pkg deps. Adds them if not built or outdated. + + source PKGBUILD ## Check this level. + + local repo=${repo:-$(guess_repo)} + local pkgbase=${pkgbase:-${pkgname[0]}} + local epoch=${epoch:-0} + local fullver=$(get_fullver ${epoch} ${pkgver} ${pkgrel}) + + if is_built "${pkgbase}" "${fullver}"; then + exit 0 # pkg is built and updated + fi + + echo "${level}:${pkgbase}" >> "${build_dir}/BUILDORDER" # greater levels are built first + + if [ -d "${build_dir}/${pkgbase}" ]; then # PKGBUILD is already there + + exit 0 + + else # Copy dir to build_dir + + mkdir ${build_dir}/${pkgbase} + cp -r $(pwd)/* ${build_dir}/${pkgbase} + + echo "repo=$repo" > "${build_dir}/${pkgbase}/.INFO" # to identify repo later + fi + + msg2 "%${level}s${pkgbase}-${fullver}" # current package plus a space for every level + + declare -i next_level=$level+1 ## Check next deps level. + + deps=$(echo "${depends[@]} ${makedepends[@]}" | \ + sed "s/[=<>]\+[^ ]\+//g" | \ + tr ' ' "\n" | \ + sort -u) # All deps in separate line, only once, without version. + + for _dep in ${deps[@]}; do + + local found=false + + if [ -d "${ABSROOT}/${_dep}" ]; then # ABSROOT/package/repo + + for _repo in ${REPOS[@]}; do # Use PKGBUILD from repo in REPOS array order + + if [ -e "${ABSROOT}/${_dep}/${_repo}/PKGBUILD" ]; then + + pushd "${ABSROOT}/${_dep}/${_repo}" > /dev/null + $0 -c -d ${build_dir} -l ${next_level} # run this cmd on dep's PKGBUILD dir + [ $? -eq 20 ] && return 20 # probable circular deps + popd > /dev/null + local found=true + break 1 # found, go to next dep + fi + + done + + else # pkgsplit, needs guess + + for _repo in ${REPOS[@]}; do + + if _dir=($(find "$ABSROOT/" -type f \ + -wholename "*/${_repo}/PKGBUILD" -print0 2>/dev/null | \ + "xargs" -0 -e grep -HEw "pkgname=|pkgbase=|provides=" | \ + grep -w "$_dep" 2>&1)) ; + + then + + _dir=$(dirname $(echo $_dir | cut -d: -f1)) + plain "guess for $_dep -> $_dir" + + pushd "$_dir" > /dev/null + $0 -c -d ${build_dir} -l ${next_level} # run this cmd on dep's PKGBUILD dir + [ $? -eq 20 ] && return 20 # probable circular dep + popd > /dev/null + local found=true + break 1 # found, go to next dep + fi + + done + + fi + + if ( ${found} ); then + continue 1 # go to next dep + else + echo "dep_not_found:$_dep" >> $build_dir/log + fi + + done + + unset next_level dir + # unset PKGBUILD variables + unset pkgbase pkgname pkgver pkgrel epoch pkgdesc arch url license groups depends \ + makedepens checkdepends optdepends provides conflicts replaces backup \ + options install changelog source noextract md5sums build check package +} + +function __build () { + pushd ${build_dir} > /dev/null + + build_packages=($(sort -gr $buildorder | cut -d: -f2)) # greater levels must be built first + + while [ ${#build_packages[@]} -ge 1 ]; do + pushd $build_dir/${build_packages[0]} > /dev/null + source PKGBUILD + + msg2 "${pkgbase:-${pkgname[0]}} $pkgver-$pkgrel" + + msg2 "Checking for non free deps" + pkgbuild-check-nonfree || { + if [ $? -eq 15 ]; then # this error means nonfree others means fail. + + echo "nonfree:$(basename $PWD)" >> $build_dir/log + + remove_buildorder "$(basename $PWD)" $buildorder # take out package from $buildorder + + continue # build next package + fi + } + + msg2 "Building $(basename $PWD)" + + $FULLBUILDCMD; r=$? # this buildcmd is on libretools.conf + + case $r in + + 0) ## Succesfull build + + plain "The build was succesful." + if source .INFO && [ -n $repo ]; then + + if [ ! -z $HOOKLOCALRELEASE ]; then # Calls a local release script if it's used + find -name "*.pkg.tar.?z" -print0 | xargs -0 $HOOKLOCALRELEASE $repo + fi + + librestage $repo || echo "unstaged:$(basename $PWD)" >> $build_dir/log + + msg "Updating pacman db and packages" + sudo pacman -Sy || true + + fi + + echo "built:$(basename $PWD)" >> $build_dir/log + ;; + + *) ## Build failed + error "There were errors while trying to build the package." + echo "failed:$(basename $PWD)" >> $build_dir/log + ;; + esac + + remove_buildorder "${build_packages[0]}" $buildorder || true + + build_packages=($(sort -gr $buildorder | cut -d: -f2)) # which is next package? + popd > /dev/null + done + + pkgs=($(grep "nonfree:" $build_dir/log)) && { + error "Those packages contain nonfree deps:" + echo ${pkgs[@]} | tr " " "\n" | cut -d: -f2 + } + + pkgs=($(grep "built:" $build_dir/log)) && { + msg "Those packages were built and staged:" + echo ${pkgs[@]} | tr " " "\n" | cut -d: -f2 + } + + pkgs=($(grep "failed:" $build_dir/log)) && { + error "Those packages failed to build:" + echo ${pkgs[@]} | tr " " "\n" | cut -d: -f2 + } + + pkgs=($(grep "unstaged:" $build_dir/log)) && { + error "Those packages couldn't be staged because of missing reponame:" + echo ${pkgs[@]} | tr " " "\n" | cut -d: -f2 + } + + popd > /dev/null +} + +function trap_exit { # End inmediately but print a useful message + + error "$@" + warning "Leftover files left on $build_dir" + + exit 1 +} + +# Trap signals from makepkg +set -E +trap 'trap_exit "(prfullpkg:${level}) TERM signal caught. Exiting..."' TERM HUP QUIT +trap 'trap_exit "(prfullpkg:${level}) Aborted by user! Exiting..."' INT +trap 'trap_exit "(prfullpkg:${level}) An unknown error has occurred. Exiting..."' ERR + +ban_file=$XDG_CONFIG_HOME/libretools/ban +force_build="" +level=0 +noupdate='n' +build_only='n' +check_deps_only='n' +max_level=21 + +while getopts 'ha:b:cd:l:nm:r:' arg; do + case $arg in + h) usage ;; + a) ABSROOT="$OPTARG" ;; + b) build_only='y' + build_dir="$OPTARG" + if [ -z ${build_dir} ]; then + usage + fi + if [ ! -r ${build_dir}/BUILDORDER ] ; then + error "${build_dir}/BUILDORDER doesn't exist." + exit 1 + fi;; + c) check_deps_only='y' ;; + d) build_dir="$OPTARG" ;; + l) level=$OPTARG ;; # hidden option to know dep level. + n) noupdate='y';; + m) max_level=$OPTARG ;; + r) FULLBUILDCMD="$OPTARG" ;; + esac +done + +if [ ${build_only} == 'n' ]; then + + [ ! -r PKGBUILD ] && { # Check if we are actually on a build directory. Do this early. + error "This isn't a build directory" + usage + } + + if [ ! -z "$HOOKPKGBUILDMOD" ]; then + "$HOOKPKGBUILDMOD" + fi + +fi + +if [ $level -eq 0 ]; then + + if [ ! -d ${build_dir} ]; then # in case of custom -d option + mkdir -p ${build_dir} + else + cleanup # files already there can screw find_deps + fi + + build_dir=${build_dir:-$(mktemp -d /tmp/fullpkg.XXXXXX)} # use -d option or else mktemp + + touch ${build_dir}/{log,BUILDORDER} ${ban_file} # make files for log and buildorder + buildorder=${build_dir}/BUILDORDER + + if [ ${noupdate} = 'n' ]; then + + msg "Updating pacman db and packages" + sudo pacman -Syu --noconfirm || true + + fi + + if [ ${build_only} == 'y' ]; then + + msg "Build Packages" + + __build + + exit 0 + + fi + + msg "Checking dependencies" +fi + +[ $level -ge $max_level ] && exit 20 # Probable circular deps + +find_deps || { + + if [ $? -eq 20 ]; then # Probable circular deps + + if [ $level -eq 0 ]; then # Show error only on level 0 + error "Check for circular deps on $build_dir/BUILDORDER"; + fi + + fi + exit 20 # Pass message 20 +} + +[ $check_deps_only = 'y' -o $level -gt 0 ] && exit 0 # only build on level 0 + +if [ $level -eq 0 -a -d $build_dir ]; then # Sanity check + + if [ ! -w $ban_file -o ! -r $ban_file ]; then # Check ban_file permisions + + chmod a+rw $ban_file || error "Ban file is not readable/writable ($ban_file)" + + else + + rsync -e ssh -aq $PARABOLAHOST:mips64el/ban >/dev/null 2>&1 || { + + warning "Failed to get ban list" && [ -r ${ban_file} ] && { # use local copy if it exist + + search=$(cat ${ban_file} | tr "\n" "|") + + egrep -w "$search" ${buildorder} >> ${build_dir}/banned # Keep track of banned files + + egrep -vw "$search" ${buildorder} > ${buildorder}2 # Take banned packages out of buildorder + + mv -f ${buildorder}2 ${buildorder} + + unset search + } + } + fi +fi + +msg "Building packages:" + +__build # Build the packages + +echo +msg2 "Check if your system works fine and librerelease if it does" + +exit 0 diff --git a/src/prtools/prmipsrelease b/src/prtools/prmipsrelease new file mode 100755 index 0000000..1fbd696 --- /dev/null +++ b/src/prtools/prmipsrelease @@ -0,0 +1,98 @@ +#!/bin/bash +# Lic: GPLv3+ +# Author: Nicolas Reynolds <fauno@kiwwwi.com.ar> +# Local release of mips64el packages + clean ABS sync +# Called by HOOKLOCALRELEASE + +# $1 repo +# $2+ packages + + source /etc/makepkg.conf + source /etc/libretools.conf + source /etc/libretools.d/prtools.conf + + usage() { + echo "$0 repo package1 [ package2 ... packageN ]" + echo + echo " release packages locally on ${PKGDEST}/stage3." + echo " and make a clean ABS sync " + } + +## +# usage : get_full_version( $epoch, $pkgver, $pkgrel ) +# return : full version spec, including epoch (if necessary), pkgver, pkgrel +## + get_full_version() { + if [[ $1 -eq 0 ]]; then + # zero epoch case, don't include it in version + echo $2-$3 + else + echo $1:$2-$3 + fi + } + + repo=$1; shift + repo-add "${PKGDEST}/stage3.db.tar.gz" $@ + +# Get all needed sources + source PKGBUILD + fullver=$(get_full_version ${epoch:-0} ${pkgver} ${pkgrel}) + pkgbase=${pkgbase:-$pkgname} + + msg "Adding packages to [stage3]..." + repo-add $@ + for name in ${pkgname[@]}; do + msg2 "${name} ${fullver}" + repo-add ${PKGDEST}/stage3.db.tar.gz ${PKGDEST}/${name}-${fullver}-*.pkg.tar.* + done + +# Copy PKGBUILD and sources + + msg "Adding clean source to $WORKDIR/abs/${CARCH}/$repo/$pkgbase" + dest_dir="$WORKDIR/abs/${CARCH}/$repo/$pkgbase" + mkdir -p ${dest_dir} >/dev/null + rm -rf ${dest_dir}/* # if package existed already there + + eval $(grep '^CARCH=' "$copydir/etc/makepkg.conf") # CARCH might be used in PKGBUILD to select sources. + export CARCH + source=($(. "PKGBUILD"; echo ${source[@]})) + cp --remove-destination "PKGBUILD" "${dest_dir}" || echo "copy 1" + for f in ${source[@]}; do + basef=$(echo $f | sed 's|::.*||' | sed 's|^.*://.*/||g') + if [ -f "$basef" ]; then + cp --remove-destination "$basef" "${dest_dir}" + fi + done + + ( . PKGBUILD + for i in 'changelog' 'install'; do + filelist=$(sed -n "s/^[[:space:]]*$i=//p" PKGBUILD) + for file in $filelist; do + # evaluate any bash variables used + eval file=${file} + if [ -f "$file" ]; then + cp --remove-destination "$file" "${dest_dir}" + fi + done + done + ) +# END add clean abs + +# Commit the changes + + pushd "$dest_dir" >/dev/null + + source "${dest_dir}/PKGBUILD" + epoch=${epoch:-0} + fullver=$(get_full_version ${epoch} ${pkgver} ${pkgrel}) + pkgbase=${pkgbase:-${pkgname[0]}} + + git add "${dest_dir}/." # add using .gitignore + + git commit -m "${pkgbase}-${fullver} ${repo}" >/dev/null && msg2 "${pkgbase} ${fullver} ${repo}" + + popd >/dev/null + +# END commit + + exit $? diff --git a/src/prtools/prtools.conf b/src/prtools/prtools.conf new file mode 100644 index 0000000..5b41216 --- /dev/null +++ b/src/prtools/prtools.conf @@ -0,0 +1,4 @@ + +# Absroot for libretools-pr +ABSROOT=$WORKDIR/prabs +HOOKLOCALRELEASE="prmipsrelease"
\ No newline at end of file diff --git a/src/prtools/prtoru b/src/prtools/prtoru new file mode 100644 index 0000000..2898b66 --- /dev/null +++ b/src/prtools/prtoru @@ -0,0 +1,173 @@ +#!/bin/bash +# Queries the ABS +# License: GPL3 + +## TODO +# * Add license text +# * Create symlinks from pkgbase to pkgname[@] for easy package finding +# * Use lastsync to store processed packages + +## GOALS +# * Have a searchable database of PKGBUILD metadata +# * Have an interface for source-only builds +# * Possibility to hook up ABS dirs besides ABSROOT (low priority) +# * Tell updates and non available binary packages (working on this) + +source /etc/abs.conf +source /etc/libretools.conf +source /etc/libretools.d/prtools.conf + +# Stores the lastsync date +lastsync() { + [ -e ${lastsyncfile} -a ! -w ${lastsyncfile} ] && { + error "The sync date can't be saved. ${lastsyncfile} isn't writable." + return 1 + } + + date +%s > "$lastsyncfile" + touch "$lastsyncfile" +} + +## +# usage : get_full_version( $epoch, $pkgver, $pkgrel ) +# return : full version spec, including epoch (if necessary), pkgver, pkgrel +## +get_full_version() { + if [[ $1 -eq 0 ]]; then + # zero epoch case, don't include it in version + echo $2-$3 + else + echo $1:$2-$3 + fi +} + +# Outputs an ordered package-fullpkgver array +print_package_array() { + echo "$@" | tr " " "\n" | sort -V -u +} + + +# Gets repo.db contents +# $1 repo +get_db_contents() { + [ ! -r /var/lib/pacman/sync/$1.db ] && return 0 + + bsdtar -tf /var/lib/pacman/sync/$1.db | \ + cut -d'/' -f1 | \ + sort -V -u +} + + +extract_pkgname() { + echo "$@" | tr " " "\n" | sed "s/^\(.\+\)-[^-]\+-[^-]\+$/\1/" +} + +extract_fullpkgver() { + echo "$@" | tr " " "\n" | sed "s/^.\+-\([^-]\+-[^-]\+\)$/\1/" +} + + +# Updates the database by finding all PKGBUILDS +# Workflow: +# * Find all PKGBUILDs on the ABS repo specified +# * Get all packages already on package repos +# * Compare them +# Args: +update() { +# The PKGBUILDs found + local pkgbuilds=() +# The list of pkgname-fullpkgver + local packages_to_sync=() + local packages_in_sync=() + local needed_updates=() + local old_versions=() + +# Find all the PKGBUILDs newer than the last update +# Update newer, otherwise everything + if [ $force ] || [ ! -e ${lastsyncfile} ]; then + $quiet || msg "Forcing upgrade" + pkgbuilds=($(find ${@} -maxdepth 2 -type f -name 'PKGBUILD')) + else + pkgbuilds=($(find ${@} -maxdepth 2 -type f -name 'PKGBUILD' -newer ${lastsyncfile})) + fi + +# Inform how many PKGBUILDS were found and quit immediately if none + $quiet || msg "Found $((${#pkgbuilds[*]}-1)) packages to update" + [ ${#pkgbuilds[*]} -eq 1 ] && { + $quiet || msg2 "There's nothing to be done. Phew!" + exit 0 + } + + for _pkgbuild in ${pkgbuilds[@]}; do + +# The repo name is guessed +# You *must* use repo/pkgbase structure + _pkgpath=$(dirname "${_pkgbuild}") + _pkgbase=$(basename "${_pkgpath}") + _pkgrepo=$(basename $(dirname "${_pkgpath}")) + + source ${_pkgbuild} + + for _pkg in ${pkgname[@]}; do +# Fill the list of packages to find + packages_to_sync+=($_pkg-$(get_full_version ${epoch:-0} $pkgver $pkgrel)) + done + + unset pkgbase pkgname pkgver pkgrel source epoch + done + +# Get repo database contents + packages_in_sync=($(get_db_contents ${_pkgrepo})) + print_package_array "${packages_to_sync[@]}" > ${TMPDIR}/packages_to_sync + print_package_array "${packages_in_sync[@]}" > ${TMPDIR}/packages_in_sync + +# We've orderer the files! + needed_updates=($(comm --nocheck-order -32 ${TMPDIR}/packages_to_sync ${TMPDIR}/packages_in_sync)) + old_versions=($(comm --nocheck-order -31 ${TMPDIR}/packages_to_sync ${TMPDIR}/packages_in_sync)) + + $quiet || msg "This packages are available to update" + for _update in ${needed_updates[@]}; do + pkg=$(extract_pkgname $_update) + + $quiet && echo $pkg + $quiet || { + ver=$(extract_fullpkgver $_update) + oldver=$(extract_fullpkgver $(grep -w $pkg ${TMPDIR}/packages_in_sync)) + + msg2 "$pkg $oldver => $ver" + } + + done + +# lastsync + +} + +## MAIN +commands=() +repos=() +quiet=false +force=false +while getopts 'hqfu' arg; do + case $arg in + h) usage; exit 0 ;; + q) quiet=true ;; + f) force=true ;; + u) commands+=(update);; + esac + + shift $((OPTIND-1)) +done + +# This is the syncfile, stores the last date as content and mtime +lastsyncfile=${ABSROOT}/toru.lastsync + +TMPDIR=$(mktemp -d) + +[[ -z ${TMPDIR} ]] && exit 1 + +${commands[0]} ${@} + +rm -rf ${TMPDIR} + +exit $? diff --git a/src/toru/toru b/src/toru/toru new file mode 100755 index 0000000..28f0b8a --- /dev/null +++ b/src/toru/toru @@ -0,0 +1,314 @@ +#!/bin/bash +# Queries the ABS +# License: GPL3 + +## TODO +# * Add license text +# * Create symlinks from pkgbase to pkgname[@] for easy package finding + +## GOALS +# * Have a searchable database of PKGBUILD metadata +# * Have an interface for source-only builds +# * Possibility to hook up ABS dirs besides ABSROOT (low priority) +# * Tell updates and non available binary packages (working on this) + +source $(dirname $(command -v $0))/toru-utils + +# Saves contents on a named cache +# $1 cache name (repo) +# $2+ contents +function store_cache { + cache=$1; shift + + [ -z "$cache" ] && return 1 + + cat $@ > ${TORUPATH}/${cache}.cache + + return $? +} + +# Return cache contents +# $1 cache name +read_cache() { + cat ${TORUPATH}/${1}.cache 2>/dev/null + + return $? +} + +## +# usage : get_full_version( $epoch, $pkgver, $pkgrel ) +# return : full version spec, including epoch (if necessary), pkgver, pkgrel +## +get_full_version() { + if [[ $1 -eq 0 ]]; then + # zero epoch case, don't include it in version + echo $2-$3 + else + echo $1:$2-$3 + fi +} + +# Outputs an ordered package-fullpkgver array +print_package_array() { + echo "$@" | tr " " "\n" | sort -u +} + + +# Gets repo.db contents (unordered) +# $1 repo +get_db_contents() { + [ ! -r /var/lib/pacman/sync/$1.db ] && return 0 + + bsdtar -tf /var/lib/pacman/sync/$1.db | cut -d'/' -f1 | sort -u +} + +# Get the pkgname +# pkgname from pkgver separator can be either '-' or ' ' +extract_pkgname() { + echo "$@" | tr " " "\n" | sed "s/^\(.\+\)[- ][^-]\+-[^-]\+$/\1/" +} + +# Get all the pkgnames from a file +# pkgname from pkgver separator can be either '-' or ' ' +extract_pkgname_from_file() { + sed "s/^\(.\+\)[- ][^-]\+-[^-]\+$/\1/" $1 +} + +# Split pkgnames from pkgvers +split_pkgname_from_pkgver() { + sed "s/^\(.\+\)-\([^-]\+-[^-]\+\)$/\1 \2/" $1 +} + +# Get the fullpkgver +# pkgname from pkgver separator can be either '-' or ' ' +extract_fullpkgver() { + echo "$@" | tr " " "\n" | sed "s/^.\+[ -]\([^-]\+-[^-]\+\)$/\1/" +} + +# Checks if $1 is a valid repo +is_repo() { + if ! in_array ${1} ${REPOS[@]}; then + $quiet || warning "${1} is not a valid repo (check REPOS array at libretools.conf)" + return 1 + fi +} + +# Updates the database by finding all PKGBUILDS +# Workflow: +# * Find all PKGBUILDs on the ABS repo specified +# * Get all packages already on package repos +# * Compare them +# Args: +update() { + local update_sync_file=false +# The PKGBUILDs found + local -a pkgbuilds=() +# The list of pkgname-fullpkgver + local -a packages_in_abs=() + local -a pkg_updates=() + local -a package_paths=() + +# Traverse all specified repos + for __repo in $@; do +# Check if the repo is set as such, otherwise skip + is_repo ${__repo} || continue + +# Fullpath of the repo + _repopath=$(readlink -f ${__repo}) + +# This is the syncfile, stores the last date as content and mtime + local lastsyncfile=${TORUPATH}/${__repo}.lastsync + +# Find all the PKGBUILDs newer than the last update +# Update newer, otherwise everything + if [[ $force = true || ! -e ${lastsyncfile} ]]; then + + $quiet || warning "Forcing upgrade" +# Get all PKGBUILDs + pkgbuilds=($(find ${_repopath} -maxdepth 2 -type f -name 'PKGBUILD')) + + else + +# Only find newer than lastsyncfile and read everything else from cache + pkgbuilds=($(find ${_repopath} -maxdepth 2 -type f -name 'PKGBUILD' -newer ${lastsyncfile})) + packages_in_abs=($(read_cache ${__repo})) + + $quiet || msg2 "Getting ${#packages_in_abs[@]} packages from cache" + + fi + + package_paths=($(read_cache ${__repo}.paths || true)) + +# Inform how many PKGBUILDS were found and quit immediately if none + $quiet || msg "Found $((${#pkgbuilds[*]}-1)) PKGBUILDs to update" + +# Traverse all found PKGBUILDs + for _pkgbuild in ${pkgbuilds[@]}; do +# Update the sync file because there are pkgbuilds to update + update_sync_file=true + +# Load PKGBUILD's metadata + source ${_pkgbuild} || continue + +# Guess pkgbase from PKGBUILD's basedir + _pkgpath=$(dirname "${_pkgbuild}") + _pkgbase=${pkgbase:-${pkgname[0]}} + +# We won't need this (all unsets are for memory efficiency) + unset build package url md5sums install pkgdesc backup options +# TODO fill a license list + unset license +# TODO create source tarballs? + unset mksource +# TODO solve dependency tree? + unset depends makedepends + + for _pkg in ${pkgname[@]}; do +# Keep removing unneeded stuff + unset package_${_pkg} >/dev/null 2>&1 || true +# Fill the list of packages to find + packages_in_abs+=($_pkg-$(get_full_version ${epoch:-0} $pkgver $pkgrel)) + package_paths+=($_pkg:$_pkgpath) + done # end pkgnames + + unset pkgbase pkgname pkgver pkgrel source epoch + done # end pkgbuilds + +# Sync! (Only if there was an actual sync) + ${update_sync_file} && lastsync ${lastsyncfile} + + if [ "${lastsyncfile}" -nt "${TORUPATH}/${__repo}.paths.cache" ]; then + print_package_array "${package_paths[@]}" > $TMPDIR/paths + store_cache ${__repo}.paths $TMPDIR/paths + fi + +# If there isn't an update cache or it's older than the last update, we check + if [ "${lastsyncfile}" -nt "${TORUPATH}/${__repo}.updates.cache" ]; then + +# Get repo database contents + packages_in_sync=($(get_db_contents ${__repo})) +# Drops arrays into files + print_package_array "${packages_in_abs[@]}" > ${TMPDIR}/packages_in_abs + print_package_array "${packages_in_sync[@]}" > ${TMPDIR}/packages_in_sync + +# Work with files + unset packages_in_abs package_in_sync + +# Use a different separator for pkgnames and pkgvers +# so we can join them by pkgname (first field) + split_pkgname_from_pkgver ${TMPDIR}/packages_in_abs | sort -k1b,1 > ${TMPDIR}/in_abs + split_pkgname_from_pkgver ${TMPDIR}/packages_in_sync | sort -k1b,1 > ${TMPDIR}/in_sync + + $quiet || msg "These packages are available to update" +# Join both files by pkgname, the end result is: +# pkgname syncver absver + join ${TMPDIR}/in_sync ${TMPDIR}/in_abs | \ + while read need_line; do + _pkg=$(echo "${need_line}" | cut -d' ' -f1) + _syncver=$(echo "${need_line}" | cut -d' ' -f2) + _absver=$(echo "${need_line}" | cut -d' ' -f3) + +# If the versions differ we need an update +# TODO move this to update query + if [ "${_syncver}" != "${_absver}" ]; then + $quiet || msg2 "$_pkg update from $_syncver to $_absver" + $quiet && echo "$_pkg" + +# FIXME this works all right but it's unset once the while ends + #pkg_updates+=("$_pkg") + +# Fix for the above problem, but it access the file every time instead of +# puting all packages together once + echo $_pkg >> ${TMPDIR}/updates + + fi + done # end need_line + + unset _pkg _syncver _absver need_line + +# Save the cache + store_cache ${__repo} ${TMPDIR}/packages_in_abs + +# See above FIXME + # print_package_array "${updates[@]}" > ${TMPDIR}/updates + if [ -r ${TMPDIR}/updates ]; then + store_cache ${__repo}.updates ${TMPDIR}/updates + fi + + else + $quiet || msg "Reading updates from cache..." + read_cache ${__repo}.updates + fi + + done # end repos +} + +# Find all the packages that are missing from the repo dbs (aka not built) +missing() { + true +} + +## Finds a PKGBUILD on toru's path cache +## usage: where_is <pkgname> +# Look in all caches but pick the first one +where_is() { + local __repo + local _path + for __repo in ${REPOS[@]}; do + _path=$(grep "^${1}:" "${TORUPATH}/${__repo}.paths.cache" 2>/dev/null | + cut -d: -f2) + + [ -n "${_path}" ] && break + done + + [ -z "$_path" ] && return 1 + + echo ${_path} +} + +# TODO: clean usage instructions +function usage { + echo "" + echo "$0 [options] repo1 ... repon" + echo "" + echo "Make a db containing PKGBUILD metadata." + echo "" + echo "-h : this message" +# echo "-a : update all repos at once" + echo "-u : update repo information" + echo "-q : quiet" + echo "-f : rebuild the db even if it is updated" + echo "-p <pkgname>: return the path for pkgname" + echo "" + exit 1 +} + +## MAIN +commands=() +repos=() +quiet=false +force=false +while getopts 'haqfpum' arg; do + case $arg in + h) usage; exit 0 ;; +# TODO: Update all repos on $REPOS array +# a) update_all_repos ;; + q) quiet=true ;; + f) force=true ;; + u) commands+=(update);; + p) shift $(( OPTIND - 1 )) + where_is "$1" || exit 1;; + m) commands+=(missing);; + esac + + shift $(( OPTIND - 1 )) +done + + +TMPDIR=$(mktemp -d) + +[[ -z ${TMPDIR} ]] && exit 1 + +${commands[0]} ${@} + +exit $? diff --git a/src/toru/toru-info b/src/toru/toru-info new file mode 100755 index 0000000..523f682 --- /dev/null +++ b/src/toru/toru-info @@ -0,0 +1,28 @@ +#!/bin/bash +# Prints info about a given pkgname +source /etc/libretools.conf + +for _pkg in $@; do + _pkgbuild="$(toru-where $_pkg)" + + if [ -f "$_pkgbuild/PKGBUILD" ]; then + source "$_pkgbuild/PKGBUILD" 2>/dev/null || { + warning "Errors on %s" $_pkg + continue + } + + deps="${depends[@]} ${makedepends[@]} ${checkdepends[@]}" + repo="$(basename $(dirname "$_pkgbuild"))" + + unset build package depends makedepends checkdepends optdepends source md5sums + + msg "%s/%s %s-%s" $repo $_pkg $pkgver $pkgrel + msg2 "$pkgdesc" + msg2 "$url" + msg2 "Depends: ${deps}" + else + warning "%s doesn't exist" $_pkg + fi + + unset pkgname pkgver pkgrel pkgdesc url +done diff --git a/src/toru/toru-path b/src/toru/toru-path new file mode 100755 index 0000000..957f49b --- /dev/null +++ b/src/toru/toru-path @@ -0,0 +1,48 @@ +#!/bin/bash + +source $(dirname $(command -v $0))/toru-utils + +TORUPATH=${T:-${TORUPATH}} +VERBOSE=${V:-false} + +if [ ! -w "$TORUPATH" ]; then + error "Toru's path isn't writable. Please check $TORUPATH" + exit 1 +fi + +LASTSYNCFILE=${TORUPATH}/lastsync.paths +PATHFILE=${TORUPATH}/paths.tch + +if [ ! -e "${PATHFILE}" ]; then + tcamgr create "${PATHFILE}" +fi + +# TODO pass other paths via flags +# ABSROOT has trailing slash +fullrepos=() +for (( i = ${#REPOS[@]}-1 ; i >= 0 ; i-- )); do + ${VERBOSE} && msg "Processing [%s]" ${REPOS[$i]} + fullrepos+=("${ABSROOT}${REPOS[$i]}") +done +pkgbuilds=($(get_pkgbuilds ${fullrepos[@]})) + +msg "Updating path cache" +msg2 "${#pkgbuilds[@]} PKGBUILDs to update" +for _pkgbuild in ${pkgbuilds[@]}; do +# plain "$_pkgbuild" + source ${_pkgbuild} >/dev/null 2>&1 || { + error "${_pkgbuild} contains errors, skipping" + continue + } + + fullpath=$(dirname ${_pkgbuild}) + + for _pkg in ${pkgbase} ${pkgname[@]} ${provides[@]}; do + $VERBOSE && msg2 "${_pkg} -> ${fullpath}" + tcamgr put ${PATHFILE} ${_pkg/[<>=]*} ${fullpath} + done + + unset pkgbase pkgname provides +done + +lastsync ${LASTSYNCFILE} diff --git a/src/toru/toru-utils b/src/toru/toru-utils new file mode 100755 index 0000000..316e6b8 --- /dev/null +++ b/src/toru/toru-utils @@ -0,0 +1,76 @@ +#!/bin/bash + +source /etc/abs.conf +source /etc/libretools.conf + +LASTSYNCFILE=${TORUPATH}/lastsync +FORCE=false +QUIET=false +DEBUG=false + +# usage : in_array( $needle, $haystack ) +function in_array { + [[ $2 ]] || return 1 # Not found + + local needle=$1; shift + local item + + for item in "$@"; do + [[ ${item#@} = $needle ]] && return 0 # Found + done + + return 1 # Not Found +} + +# Stores the lastsync date +lastsync() { + local lastsyncfile + + lastsyncfile=$1 + + [ -e ${lastsyncfile} -a ! -w ${lastsyncfile} ] && { + error "The sync date can't be saved. ${lastsyncfile} isn't writable." + return 1 + } + + date +%s > ${lastsyncfile} + touch ${lastsyncfile} +} + +get_dbs() { + local _db + for _db in /var/lib/pacman/sync/*.db; do + bsdtar tf ${_db} | cut -d'/' -f1 | sort -u + done +} + +# repo paths +get_pkgbuilds() { + pkgbuilds=() + + if [[ $FORCE = true || ! -e ${LASTSYNCFILE} ]]; then + + $QUIET || warning "Forcing upgrade" +# Get all PKGBUILDs + extra="" + else +# Only find newer than lastsyncfile and read everything else from cache + extra=" -newer ${LASTSYNCFILE}" + fi + +# Return all PKGBUILDs found + find $@ -mindepth 2 -maxdepth 3 -type f -name 'PKGBUILD' ${extra} +} + +# End inmediately but print a useful message +trap_exit() { + error "$@" + + exit 1 +} + +# Trap signals from makepkg +set -E +trap 'trap_exit "TERM signal caught. Exiting..."' TERM HUP QUIT +trap 'trap_exit "Aborted by user! Exiting..."' INT +trap 'trap_exit "An unknown error has occurred. Exiting..."' ERR diff --git a/src/toru/toru-where b/src/toru/toru-where new file mode 100755 index 0000000..e9ab29d --- /dev/null +++ b/src/toru/toru-where @@ -0,0 +1,7 @@ +#!/bin/bash +# Locates a PKGBUILD dir on toru's path cache +source /etc/libretools.conf + +PATHFILE=${TORUPATH}/paths.tch + +tcamgr get ${PATHFILE} $1 2>/dev/null || echo "" diff --git a/src/treepkg b/src/treepkg new file mode 100755 index 0000000..8c4cc8e --- /dev/null +++ b/src/treepkg @@ -0,0 +1,237 @@ +#!/bin/bash +#set -x +# (c) 2012 Nicolás Reynolds <fauno@parabola.nu> +# +# 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 Affero 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/>. + +source /etc/libretools.conf +source $XDG_CONFIG_HOME/libretools/libretools.conf >/dev/null 2>&1|| true + +term_title "$(basename $0)" + +# Get system variables +source /etc/makepkg.conf +source $HOME/makepkg.conf >/dev/null 2>&1|| true + +# End inmediately but print an useful message +trap_exit() { + term_title "error!" + error "($(basename $0)) $@ (leftovers on ${BUILDDIR})" + exit 1 +} + +# Trap signals from makepkg +set -E +trap 'trap_exit "TERM signal caught. Exiting..."' TERM HUP QUIT +trap 'trap_exit "Aborted by user! Exiting..."' INT +trap 'trap_exit "An unknown error has occurred. Exiting..."' ERR + +# return : full version spec, including epoch (if necessary), pkgver, pkgrel +# usage : get_fullver( ${epoch:-0}, $pkgver, $pkgrel ) +get_fullver() { + if [ $1 -eq 0 ]; then +# zero epoch case, don't include it in version + echo $2-$3 + else + echo $1:$2-$3 + fi + +} + +# Add line to build order cache in CSV format +# *must* be run from the PKGBUILD path +# status;depth;pkgbase;[epoch:]pkgver-pkgrel;path;repo +# $1 status +# $2 pkgname +add_order() { + echo "${1};${DEPTH};${2:-${pkgbase}};${fullver};${PWD};$(guess_repo "$PWD")" >> "${BUILDORDER}" + ${VERBOSE} && msg2 "%${DEPTH}s${2:-${pkgbase}} [${1}]" || true +} + +# Bury a package deeper in the tree +# $1 pkgbase +# $2 nextdepth +bury() { +# Bury only if we are going to build the dep +# Get it's current depth and dir name + local current_depth=$(grep "build;[0-9]\+;${1};" "${BUILDORDER}" | cut -d ';' -f 2) + local current_name="$(printf "%03d" ${current_depth})_${1}" + +# If there's a depth or the package is not the root of the build tree (which +# can lead to funny chicken-and-egg problems), update the depth to the current +# package next-depth and rename the dir too + if [ -z "${current_depth}" ]; then return; fi + if [ -z "${current_name}" ]; then return; fi + if [ ${current_depth} -eq 0 ]; then return; fi + if [ ${current_depth} -ge $2 ]; then return; fi + + ${VERBOSE} && msg "Burying ${1} from ${current_depth} to ${2}" + + { + sed -i "s|^\(build;\)\([0-9]\+\)\(;${1};.*\)$|\1${2}\3|" "${BUILDORDER}" && \ + mv "${BUILDDIR}/${current_name}" "${BUILDDIR}/$(printf "%03d" ${2})_${1}" + } || return 1 +} + +# Guess the repo from the pkgbase path +# $1 path, pwd or toru-where +guess_repo() { + basename "$(dirname "${1}")" +} + +if [ ! -f PKGBUILD ]; then + error "Missing PKGBUILD ($PWD)" + exit 1 +fi + +if ! source PKGBUILD ; then + error "Can't source PKGBUILD" + exit 1 +fi + +# Save resources +unset pkgdesc arch license groups backup install md5sums sha1sums \ + sha256sums source options >/dev/null 2>&1 + +unset build package >/dev/null 2>&1 + +for _pkg in ${pkgname[@]}; do + unset package_${_pkg} >/dev/null 2>&1 || true +done +## + +# Get useful values +pkgbase="${pkgbase:-${pkgname[0]}}" +fullver=$(get_fullver ${epoch:-0} ${pkgver} ${pkgrel}) + +# Get or set the work dir +BUILDDIR="${1:-$(mktemp -d /tmp/${pkgbase}-treepkg-XXXx)}" +BUILDORDER="${BUILDDIR}/BUILDORDER" +DEPTH=${2:-0} +NEXTDEPTH=$((${DEPTH} + 1)) +# This can be set as env vars (ie: $ V=false B=false treepkg) +# TODO Turn into flags? +VERBOSE=${V:-true} +BUILD=${B:-true} +CLEANUP=${C:-true} +# Skip BUILDORDER creation and build anything on BUILDDIR +BUILDNOW=${N:-false} + +if [ ! -z "${1}" -a ${DEPTH} -eq 0 ]; then + BUILDNOW=true +fi + +if ! ${BUILDNOW}; then +# ensure it exists + touch "${BUILDORDER}" + +# If this package is already built quit silently + for _pkg in ${pkgname[@]}; do + if is_built "${_pkg}" "${fullver}"; then + add_order "ignore" + exit 0 + fi + done + +# Ignore if already in build order + egrep -q ";${pkgbase};" "${BUILDORDER}" && exit 0 + +# Add pkgbase to build order + add_order "build" + +# Copy the directory to the build dir +# TODO run makepkg --source to avoid moving garbage around? + cp -r "${PWD}" "${BUILDDIR}/$(printf "%03d" ${DEPTH})_${pkgbase}" + +# Cleanup dep versioning + deps=($(echo "${depends[@]} ${makedepends[@]}" | \ + sed "s/[=<>]\+[^ ]\+//g" | \ + tr ' ' "\n" | \ + sort -u)) + +# NOTE: getting depends from package() is a PITA + for _dep in ${deps[@]}; do +# Move deps deeper in the tree if +# pkgbase - dep1 +# \ dep2 - dep1 +# dep1 should be depth + 1 + egrep -q ";${_dep};" "${BUILDORDER}" && bury "${_dep}" ${NEXTDEPTH} + +# Ask toru where's a PKGBUILD + depdir="$(toru-where ${_dep})" + + if [ -z "${depdir}" -o ! -d "${depdir}" ]; then +# We specify the pkgname because we can't source the dep PKGBUILD +# Normally 'any' packages are missing from our work ABS + add_order "missing" "${_dep}" + continue + fi + + pushd "${depdir}" >/dev/null + +# Run itself over dependencies + $0 "${BUILDDIR}" ${NEXTDEPTH} + + done +# End BUILD now +fi + +# Only build at the end +if [ ${DEPTH} -eq 0 ]; then + ${VERBOSE} && msg "Starting build" || true + + if ${BUILD}; then + ${VERBOSE} && msg "Build tree stored in ${BUILDORDER}" || true + +# Build everything sorting the build dir +# The reverse order ensures we start by the deepest packages + for _pkg in $(ls -r "${BUILDDIR}"); do +# Ignore if there's no PKGBUILD + if [ ! -f "${BUILDDIR}/${_pkg}/PKGBUILD" ]; then continue; fi +# Skip if already built (faster than calling is_build again) + if [ -f "${BUILDDIR}/${_pkg}/built_ok" ]; then continue; fi + + ${VERBOSE} && msg "Building ${_pkg/_/ }" || true + +# Remove leading zeros and space if any + term_title "$(echo ${_pkg/_/ } | sed "s/^0\+ \?//")" + +# Run build command + pushd "${BUILDDIR}/${_pkg}" >/dev/null + sudo pacman -Syu --noconfirm + + ${HOOKPREBUILD} + + ${FULLBUILDCMD} +# Run local release hook with $1 = $repo + ${HOOKLOCALRELEASE} $(egrep ";${_pkg#*_};" "${BUILDORDER}" | cut -d';' -f6) + + touch built_ok + popd >/dev/null + done + + else +# Just print the working dir + ${VERBOSE} || echo "${BUILDORDER}" || true + fi + +if ${CLEANUP} ; then + msg2 "Removing ${BUILDDIR}" + rm -rf "${BUILDDIR}" +fi + +fi + +term_title "done" +exit $? diff --git a/src/update-cleansystem b/src/update-cleansystem new file mode 100755 index 0000000..6bec742 --- /dev/null +++ b/src/update-cleansystem @@ -0,0 +1,68 @@ +#!/bin/bash +# Updates the cleansystem file +# Creates a fake Parabola root and writes to cleansystem all +# packages installable from base and base-devel plus extras. + +set -e +# Copyright 2012 Nicolás Reynolds, Luke Shumaker + +# ---------- GNU General Public License 3 ---------- + +# This file is part of Parabola. + +# Parabola 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. + +# Parabola 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 Parabola. If not, see <http://www.gnu.org/licenses/>. + +set -e + +# libretools.conf gives us libremessages +source /etc/libretools.conf + +cleansystem=/etc/libretools.d/cleansystem + +cmd=${0##*/} +usage() { + echo "Usage: $cmd [<EXTRA_PACKAGES>]" + echo " $cmd -h" + echo "Creates a fake Parabola root and writes to \`$cleansystem' all" + echo "packages installable from base and base-devel plus extras." + echo '' + echo 'Options:' + echo ' -h Show this message' +} + +if [ "$1" == '-h' ]; then + usage + exit 0 +fi + +if [ ! -w "$cleansystem" ]; then + error 'This script must be run as root' + exit 1 +fi + +# Maintain a clean database in the system +db_dir="${DB:-/var/lib/libretools/clean}" +[ ! -d "${db_dir}" ] && mkdir -p "${db_dir}" + +# We sync first because updating info gets printed to stdout too +pacman -b "${db_dir}" --config /etc/pacman.conf -Sy 2>/dev/null +pacman -b "${db_dir}" \ + --config /etc/pacman.conf \ + -Sp --print-format "%n" \ + base base-devel sudo $@ | sort > "$cleansystem" + +# Ensures everything's installed +pacman -Sy --needed --noconfirm base base-devel sudo $@ + +exit $? |