#!/bin/bash # # createpkg: package builder using http://slack.sarava.org/slackbuilds scripts # feedback: rhatto at riseup.net | gpl # # createpkg 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 2 of the License, or any later version. # # createpkg 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, write to the Free Software Foundation, Inc., 59 Temple # Place - Suite 330, Boston, MA 02111-1307, USA # # /etc/simplepkg/slackbuildrc parameters: # # SLACKBUILDS="/folder/to/place/slackbuilds", defaults to /var/slackbuilds # SVN="svn://repository", defaults do svn://slack.sarava.org/slackbuilds # SYNC="yes|no", whether to always update the repository # # TODO # # - optionally show a dependency tree before create the package # - ok - ??? think if its better to change function check_config to directly source # both /root/.slackbuildrc and /etc/slackbuildrc # - ok - option --list to list all available slackbuilds # - ok - option --search allowing use of wildcards or just part of the package name # - in function solve_dep: resolve program versions # #--------------------------------------------------- # Createpkg functions #--------------------------------------------------- function handle_error { # this function deals with internal createpkg errors # and also with non-zero exit codes from slackbuilds # Input: $1 - error code # Output: Error mensage # # check slackbuild exit status are: # # ERROR_WGET=31; ERROR_MAKE=32; ERROR_INSTALL=33 # ERROR_MD5=34; ERROR_CONF=35; ERROR_HELP=36 # ERROR_TAR=37; ERROR_MKPKG=38 ERROR_GPG=39 # ERROR_PATCH=40; ERROR_VCS=41 # # thanks to rudsonalves at yahoo.com.br for this spec. # we don't want to process when exit status = 0 if [ "$1" == "0" ]; then return fi # exit codes case $1 in 2) usage ;; 3) echo -e "$CL_ALERT $BASENAME: could not update the repository $2 $CL_OFF" ;; 4) echo -e "$CL_ALERT $BASENAME: could not create folder $2 $CL_OFF" ;; 5) echo -e "$CL_ALERT $BASENAME: script not found for $2 $CL_OFF" ;; 31) echo -e "$CL_ERROR $BASENAME: error downloading source for $2 $CL_OFF" ;; 32) echo -e "$CL_ERROR $BASENAME: error compiling $2 source code $CL_OFF" ;; 33) echo -e "$CL_ERROR $BASENAME: error installing $2 $CL_OFF" ;; 34) echo -e "$CL_ERROR $BASENAME: error on source code integrity check for $2 $CL_OFF" ;; 35) echo -e "$CL_ERROR $BASENAME: error configuring the source code for $2 $CL_OFF" ;; 36) exit 0 ;; # its supposed to never happen here :P 37) echo -e "$CL_ERROR $BASENAME: error decompressing source code for $2 $CL_OFF" ;; 38) echo -e "$CL_ERROR $BASENAME: error creating package $2 $CL_OFF" ;; 39) echo -e "$CL_ERROR $BASENAME: error verifying GPG signature the source code for $2 $CL_OFF" ;; 40) echo -e "$CL_ERROR $BASENAME: error patching the source code for $2 $CL_OFF" ;; 41) echo -e "$CL_ERROR $BASENAME: error downloading $2 source from version control system $CL_OFF" ;; *) echo -e "$CL_ERROR $BASENAME: unknown error or user interrupt $CL_OFF" ;; esac exit $1 } function build_repo { # checkout a new slackbuild working copy BASEDIR="`dirname $SLACKBUILDS`" mkdir -p $BASEDIR || handle_error 4 $BASEDIR cd $BASEDIR svn checkout $SVN cd $SLACKBUILDS } function usage { echo -e "$CL_COMMU Usage: createpkg [--install] package-name $CL_OFF" echo -e "$CL_COMMU createpkg --no-deps package-name $CL_OFF" echo -e "$CL_COMMU createpkg --search package-name $CL_OFF" echo -e "$CL_COMMU createpkg --info package-name $CL_OFF" echo -e "$CL_COMMU createpkg --list $CL_OFF" echo -e "$CL_COMMU createpkg --sync $CL_OFF" echo -e "$CL_COMMU createpkg --help $CL_OFF" } function check_config { # check the configuration # TODO: eval also ~/.slackbuildrc #if [ -f "$SLACKBUILDRC" ]; then # source $SLACKBUILDRC #fi TMP=${TMP:=/tmp} REPOS=${REPOS:=$TMP} SLACKBUILDS=${SLACKBUILDS:=/var/slackbuilds} SVN=${SVN:=svn://slack.sarava.org/slackbuilds} SYNC=${SYNC:=no} BASEDIR="`dirname $SLACKBUILDS`" } function solve_dep { pack="$1" cond="$2" ver="$3" #if [ "$cond" != "e" ] && [ "$cond" != "l" ] && [ "$cond" != "ge" ] && [ "$cond" != "le" ] && [ ! -z "$cond" ]; then if [ ! -z "$cond" ]; then # slack-required has a wrong logical sentence, so we ignore it check_version="no" fi for candidate in `ls /var/log/packages/$pack* 2> /dev/null`; do candidate="`package_name $candidate`" if [ "$pack" == "$candidate" ]; then if [ "$check_version" != "no" ]; then # TODO: check if the pack has the correct version true fi found="1" break fi done if [ "$found" != "1" ]; then echo -e "$CL_MENSG $BASENAME: processing $PACKAGE dependency $pack $CL_OFF" SYNC=no CREATEPKG_CHILD=$CREATEPKG_CHILD createpkg --install $pack # check if the package was built and installed exit_code="$?" if [ "$exit_code" != "0" ]; then echo -e "$CL_ALERT $BASENAME: received an error when processing $pack, aborting $CL_OFF" exit $exit_code fi else found="0" fi } function check_repo { if [ ! -d "$SLACKBUILDS" ]; then build_repo fi } function sync_repo { cd $SLACKBUILDS svn update || build_repo } function find_script { #find $SLACKBUILDS | grep -v .svn | grep -e "/$1.SlackBuild$" find $SLACKBUILDS -name $1.SlackBuild } function info_builds { # Show packages info if [ "$PKG_PATH" != "" ]; then for i in $PKG_PATH; do PACKAGE=`basename $i .SlackBuild` NAME_UP=`echo $PACKAGE | tr [a-z] [A-Z]` echo -e "$CL_COMMU $NAME_UP: $CL_OFF" eval "cat $i | grep '^$PACKAGE:' | cut -f2- -d:" echo -e "$CL_OFF" done fi } function list_builds { # List all available SlackBuilds # find $SLACKBUILDS -name *.SlackBuild | sed -r 's,.*/(.*)\.SlackBuild$,\1,' | sort cd $SLACKBUILDS echo "Sarava SlackBuilds list" # level 1 for i in *; do if [ -d $i ]; then echo -e " $i: " ( cd $i # level 2 for j in *; do if [ -d $j ]; then echo -e "$CL_COMMU $j $CL_OFF" ( cd $j BUILD="`ls *.SlackBuild 2>/dev/null`" if [ "$BUILD" != "" ]; then # level 3 for k in $BUILD; do echo -e "$CL_MENSG $k $CL_OFF" done else BUILD="" fi for k in *; do if [ -d $k ]; then echo -e "$CL_MENSG $k.SlackBuild $CL_OFF" fi done ) fi done ) fi done } #--------------------------------------------------- # Starting createpkg #--------------------------------------------------- # Common functions COMMON="/usr/libexec/simplepkg/common.sh" # TODO: SLACKBUILDRC is need? if [ -f ~/.slackbuildrc ]; then SLACKBUILDRC=~/.slackbuildrc else SLACKBUILDRC=/etc/slackbuildrc fi source $SLACKBUILDRC 2>/dev/null # Select color mode: gray, color or none (*) # CL_COMMU - Communication # CL_MENSG - Commum messages # CL_ERROR - Error messages # CL_OFF - turn off color case "$COLOR" in 'gray') CL_COMMU="\033[37;1m" CL_MENSG="\033[37;1m" CL_ERROR="\033[30;1m" CL_ALERT="\033[37m" CL_OFF="\033[m" ;; 'color') CL_COMMU="\033[34;1m" # green CL_MENSG="\033[32;1m" # blue CL_ERROR="\033[31;1m" # red CL_ALERT="\033[33;1m" # yellow CL_OFF="\033[m" # normal ;; *) CL_COMMU="" CL_MENSG="" CL_ERROR="" CL_ALERT="" CL_OFF="" ;; esac # First load simplepkg helper functions if [ -f "$COMMON" ]; then source $COMMON else echo -e "$CL_ERROR error: file $COMMON found, check your $BASENAME installation $CL_OFF" exit 1 fi # This is used to show how many children process we have if [ -z "$CREATEPKG_CHILD" ]; then CREATEPKG_CHILD="1" else #CREATEPKG_CHILD="`echo $CREATEPKG_CHILD + 1 | bc -l`" let CREATEPKG_CHILD++ fi BASENAME="`basename $0`[$CREATEPKG_CHILD]" check_config check_repo case $1 in '--search') [ $# -ne 2 ] && handle_error 2 # two parameters is required find_script $2 exit ;; '--info') [ $# -ne 2 ] && handle_error 2 # two parameters is required PKG_PATH=`find_script $2` info_builds exit ;; '--install') [ $# -ne 2 ] && handle_error 2 # two parameters is required PACKAGE="$2" INSTALL="1" ;; '--no-deps') [ $# -ne 2 ] && handle_error 2 # two parameters is required NO_DEPS="1" PACKAGE="$2" ;; '--sync') sync_repo exit ;; '--help'|'') usage exit ;; '--list') list_builds exit ;; *) if [ "${1:0:1}" != "-" ]; then PACKAGE="$1" else handle_error 2 fi ;; esac # Synchronize repository if [ "$SYNC" == "yes" ]; then sync_repo fi # Get SlackBuild script BUILD_SCRIPT="`find_script $PACKAGE`" # Select one SlackBuild if [ "`echo $BUILD_SCRIPT | wc -w`" -gt 1 ]; then AUX="$PS3" PS3="Choice: " LIST=`echo $BUILD_SCRIPT | sed 's/ /\n/g' | sed -r 's/.*\/(.*)\.SlackBuild$/\1/'`" EXIT" select PACKAGE in `echo $LIST`; do break done if [ "$PACKAGE" = "EXIT" ]; then echo -e "$CL_ERROR error: None package select $CL_OFF" exit 1 fi # Select only one SlackBuild in BUILD_SCRIPT BUILD_SCRIPT=`echo $BUILD_SCRIPT | sed 's/ /\n/g' | grep "/$PACKAGE.SlackBuild"` PS3="$AUX" else PACKAGE=`echo $BUILD_SCRIPT | sed -r 's/.*\/(.*)\.SlackBuild$/\1/'` fi # Check SlackBuild script found if [ -z "$BUILD_SCRIPT" ]; then handle_error 5 $PACKAGE fi # Get dirname and script name from slackbuild SCRIPT_BASE="`dirname $BUILD_SCRIPT`" SCRIPT_NAME="`basename $BUILD_SCRIPT`" echo -e "$CL_MENSG $BASENAME: found script $PACKAGE.SlackBuild, now checking for dependencies $CL_OFF" # Sets the package's slack-required if [ -f "$SCRIPT_BASE/$PACKAGE.slack-required" ]; then SLACK_REQ="$SCRIPT_BASE/$PACKAGE.slack-required" elif [ -f "$SCRIPT_BASE/slack-required" ]; then SLACK_REQ="$SCRIPT_BASE/slack-required" fi if [ ! -z "$SLACK_REQ" -a "$NO_DEPS" != "1" ]; then # this routine checks for dependencies in package's slack-required while read dep; do if [ ! -z "$dep" ]; then program="`echo $dep | awk '{ print $1 }'`" condition="`echo $dep | awk '{ print $2 }' | tr [=\>\<] [egl]`" version="`echo $dep | awk '{ print $3 }' | tr -dc '[:digit:]'`" solve_dep $program $condition $version fi done < <( cat $SLACK_REQ ) echo -e "$CL_MENSG $BASNEMAE: done checking for $PACKAGE dependencies $CL_OFF" else echo -e "$CL_MENSG $BASENAME: no unmet dependencies for $PACKAGE $CL_OFF" fi echo -e "$CL_MENSG $BASENAME: processing $SCRIPT_NAME $CL_OFF" # Built package cd $SCRIPT_BASE # Execute SlackBuild script with variables protection ( INTERACT=no ./$SCRIPT_NAME ) # Check if package was built handle_error $? $PACKAGE PKG_TGZ="`ls -1 -c $REPOS/$PACKAGE-*-*-*tgz | head -n 1`" mkdir -p $PKG_TGZ $REPOS/${SCRIPT_BASE/$BUILD_SCRIPT} if [ "$INSTALL" == "1" ]; then # as we dont have the full package file name, we'll # use the newer file name that matches our wildcard: upgradepkg --install-new $PKG_TGZ fi