#!/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_DIR="/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 # - in function solve_dep: resolve program versions # - mkdir source directory - error... (please check!) #--------------------------------------------------- # Createpkg functions #--------------------------------------------------- CREATEPKG_VERSION="1.0.5.2" function error_codes { # Slackbuilds error codes ERROR_WGET=31 # wget error ERROR_MAKE=32 # make source error ERROR_INSTALL=33 # make install error ERROR_MD5=34 # md5sum error ERROR_CONF=35 # ./configure error ERROR_HELP=36 # dasable ERROR_TAR=37 # tar error ERROR_MKPKG=38 # makepkg error ERROR_GPG=39 # gpg check error ERROR_PATCH=40 # patch error ERROR_VCS=41 # cvs error ERROR_MKDIR=42 # make directory error # Createpkg error codes ERROR_INSTPKG=200 # installpkg error ERROR_DEPEN=201 # dependency error SCRIPT_OR_PACKAGE_NOT_FOUND=202 # Script or package not found } function eecho { # echoes a message # usage: eecho # message-type can be: commun, messag, error, normal echo -e "${1}${2}${normal}" } 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; ERROR_MKDIR=42 # # thanks to rudsonalves at yahoo.com.br for this spec. # we don't want to process when exit status = 0 [ "$1" == "0" ] && return # Exit codes case $1 in 2) usage ;; 3) eecho $alert "$BASENAME: could not update the repository $2" ;; 4) eecho $alert "$BASENAME: could not create folder $2" ;; 5) eecho $alert "$BASENAME: script not found for $2" ;; $ERROR_WGET) eecho $error "$BASENAME: error downloading source/package for $2" ;; $ERROR_MAKE) eecho $error "$BASENAME: error compiling $2 source code" ;; $ERROR_INSTALL) eecho $error "$BASENAME: error installing $2" ;; $ERROR_MD5) eecho $error "$BASENAME: error on source code integrity check for $2" ;; $ERROR_CONF) eecho $error "$BASENAME: error configuring the source code for $2" ;; $ERROR_HELP) exit 0 ;; # its supposed to never happen here :P $ERROR_TAR) eecho $error "$BASENAME: error decompressing source code for $2" ;; $ERROR_MKPKG) eecho $error "$BASENAME: error creating package $2" ;; $ERROR_GPG) eecho $error "$BASENAME: error verifying GPG signature the source code for $2" ;; $ERROR_PATCH) eecho $error "$BASENAME: error patching the source code for $2" ;; $ERROR_VCS) eecho $error "$BASENAME: error downloading $2 source from version control system" ;; $ERROR_MKDIR) eecho $error "$BASENAME: make directory $2 error, aborting" ;; $ERROR_INSTPKG) eecho $error "$BASENAME: install package $2 error, aborting" ;; $ERROR_DEPEN) eecho $error "$BASENAME: dependency solve error, aborting" ;; *) eecho $error "$BASENAME: unknown error or user interrupt" ;; $SCRIPT_OR_PACKAGE_NOT_FOUND) eecho $error "$BASENAME: SlackBuild or package not found" ;; esac exit $1 } function build_repo { # Checkout a new slackbuild working copy BASEDIR="`dirname $SLACKBUILDS_DIR`" mkdir -p $BASEDIR || handle_error 4 $BASEDIR cd $BASEDIR svn checkout $SVN cd $SLACKBUILDS_DIR } function usage { # Help message eecho $commun "Createpkg version $CREATEPKG_VERSION\n" eecho $commun "Usage: createpkg [--install/-i] package-name" eecho $commun " createpkg --no-deps/-np package-name" eecho $commun " createpkg --search/-s package-name" eecho $commun " createpkg --info/-f package-name" eecho $commun " createpkg --list/-l" eecho $commun " createpkg --sync" eecho $commun " createpkg --help/-h" } function check_config { # check the configuration TMP=${TMP:=/tmp}; REPOS=${REPOS:=$TMP}; # Create $TMP and $REPOS if need [ ! -e $TPM ] && mkdir $TMP [ ! -e $REPOS ] && mkdir $REPOS # SLACKBUILDS_DIR=${SLACKBUILDS_DIR:=/var/slackbuilds} SVN=${SVN:=svn://slack.sarava.org/slackbuilds} SYNC=${SYNC:=no} BASEDIR="`dirname $SLACKBUILDS_DIR`" } function solve_dep { # Solve dependency local PACK="$1" local COND="$2" local VER="$3" # Check package in local system PACK="`echo $PACK | sed -e 's/\+/\\\+/'`" INSTALLED=`eval "ls /var/log/packages/ | egrep -E '^$PACK-[^-]+-[^-]+-[^-]+$'"` CHECK=$? # TODO: Make check version procedures if [ -z "$INSTALLED" ]; then if [ $CHECK -ne 0 ]; then # Check package in SlackBuilds tree eecho $messag "$BASENAME: processing $PACKAGE dependency $PACK" SYNC=no CREATEPKG_CHILD=$CREATEPKG_CHILD createpkg --install $PACK # check if the package was built and installed EXIT_CODE="$?" if [ "$EXIT_CODE" == "5" ]; then # exit code 5 == slackbuild not found # try to use simplaret ARCH=$DEFAULT_ARCH simplaret --update ARCH=$DEFAULT_ARCH simplaret --install $PACK EXIT_CODE="$?" if [ "$EXIT_CODE" != "0" ]; then handle_error $SCRIPT_OR_PACKAGE_NOT_FOUND $PACK fi elif [ "$EXIT_CODE" != "0" ]; then handle_error $EXIT_CODE $PACK fi fi fi } function check_repo { # Verify if repository exist [ ! -d "$SLACKBUILDS_DIR" ] && build_repo } function sync_repo { # Synchronize repository cd $SLACKBUILDS_DIR exit # svn update || build_repo #simplaret --update } function find_slackbuild { # Find SlackBuild script in the repository find $SLACKBUILDS_DIR -iname $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]` eecho $commun "$NAME_UP: " PKG_DIR=`dirname $i` if [ -e $PKG_DIR/slack-desc ]; then eval "cat $PKG_DIR/slack-desc | grep '^$PACKAGE:' | cut -f2- -d:" eecho $normal else eval "cat $i | grep '^$PACKAGE:' | cut -f2- -d:" eecho $normal fi if [ -e $PKG_DIR/slack-required ]; then eecho $commun "slack-required" cat $PKG_DIR/slack-required | sed 's/^/ /' fi done fi } function list_builds { # List all available SlackBuilds cd $SLACKBUILDS_DIR 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 eecho $commun " $j" ( cd $j BUILD="`ls *.SlackBuild 2>/dev/null`" if [ "$BUILD" != "" ]; then # level 3 for k in $BUILD; do eecho $messag " $k" done else BUILD="" fi for k in *; do if [ -d $k ]; then eecho $messag " $k.SlackBuild" fi done ) fi done ) fi done } function color_select { # Select color mode: gray, color or none (*) # commun - Communication # messag - Commum messages # error - Error messages # normal - turn off color case "$1" in 'gray') commun="\033[37;1m" messag="\033[37;1m" error="\033[30;1m" alert="\033[37m" normal="\033[m" ;; 'color') commun="\033[34;1m" # green messag="\033[32;1m" # blue error="\033[31;1m" # red alert="\033[33;1m" # yellow normal="\033[m" # normal ;; *) commun="" messag="" error="" alert="" normal="" ;; esac } #--------------------------------------------------- # Starting createpkg #--------------------------------------------------- # Common functions COMMON="/usr/libexec/simplepkg/common.sh" SIMPLEPKG_CONF="/etc/simplepkg/simplepkg.conf" BASENAME="`basename $0`" if [ -f "$COMMON" ]; then source $COMMON else echo "error: file $COMMON found, check your $BASENAME installation" mk_exit 0 fi # Load simplepkg.conf variables eval_config $BASENAME # Enable debug mode #set -x # Loading error codes error_codes # First load simplepkg helper functions source $COMMON && source $SIMPLEPKG_CONF if [ $? -ne 0 ]; then eecho $error "error: file $COMMON not found, check your $BASENAME installation" exit 1 fi # Load slackbuildrc definitions if [ -f ~/.slackbuildrc ]; then source ~/.slackbuildrc else source /etc/slackbuildrc 2>/dev/null fi # Select color mode: gray, color or none (*) color_select $COLOR # This is used to show how many children process we have if [ -z "$CREATEPKG_CHILD" ]; then CREATEPKG_CHILD="1" else let CREATEPKG_CHILD++ fi BASENAME="`basename $0`[$CREATEPKG_CHILD]" check_config check_repo case $1 in '--search'|'-s') [ $# -ne 2 ] && handle_error 2 # two parameters is required find_slackbuild $2 exit ;; '--info'|'-f') [ $# -ne 2 ] && handle_error 2 # two parameters is required PKG_PATH=`find_slackbuild $2` info_builds exit ;; '--install'|'-i') [ $# -ne 2 ] && handle_error 2 # two parameters is required PACKAGE="$2" INSTALL="1" ;; '--no-deps'|'-nd') [ $# -ne 2 ] && handle_error 2 # two parameters is required NO_DEPS="1" PACKAGE="$2" ;; '--sync') sync_repo exit 0 ;; '--help'|'-h'|'') usage exit 0 ;; '--list'|'-l') list_builds exit 0 ;; *) if [ "${1:0:1}" != "-" ]; then PACKAGE="$1" else handle_error 2 fi ;; esac # Synchronize repository [ "$SYNC" == "yes" ] && sync_repo # Get SlackBuild script BUILD_SCRIPT="`find_slackbuild $PACKAGE`" # Check SlackBuild script found if [ -z "$BUILD_SCRIPT" ]; then handle_error 5 $PACKAGE fi # 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 eecho $error "error: None package select" 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/'` PACKAGE=`basename $BUILD_SCRIPT .SlackBuild` fi # Get dirname and script name from slackbuild SCRIPT_BASE="`dirname $BUILD_SCRIPT`" SCRIPT_NAME="`basename $BUILD_SCRIPT`" eecho $messag "$BASENAME: found script $PACKAGE.SlackBuild, now checking for dependencies" # Sets the package's slack-required if [ -f "$SCRIPT_BASE/$PACKAGE.slack-required" ]; then SLACK_REQUIRED="$SCRIPT_BASE/$PACKAGE.slack-required" elif [ -f "$SCRIPT_BASE/slack-required" ]; then SLACK_REQUIRED="$SCRIPT_BASE/slack-required" fi if [ ! -z "$SLACK_REQUIRED" -a "$NO_DEPS" != "1" ]; then # this routine checks for dependencies in package's slack-required ( grep '^[^#]' $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 true done ) if [ $? -ne 0 ]; then eecho $messag "$BASENAME: dependency solve error" exit 1 fi eecho $messag "$BASENAME: done checking for $PACKAGE dependencies" else eecho $messag "$BASENAME: no unmet dependencies for $PACKAGE" fi eecho $messag "$BASENAME: processing $SCRIPT_NAME" # Change to script base directory cd $SCRIPT_BASE # Execute SlackBuild script with variables protection ( REPOS=$MAKEPKG_REPOS INTERACT=no sh ./$SCRIPT_NAME ) # Check if package was built handle_error $? $PACKAGE # Get package name PKG_NAME="`ls -1 -c $MAKEPKG_REPOS/$PACKAGE-*-*-*.tgz | head -n 1 | xargs basename`" # Select repository directory [ $MOVE_BIN_PACKAGE -eq 0 ] && NEW_REPOS=$MAKEPKG_REPOS/$( echo ${SCRIPT_BASE#$SLACKBUILDS_DIR/} ) || NEW_REPOS=$MAKEPKG_REPOS # Create repository directory [ ! -e $NEW_REPOS ] && mkdir -p $NEW_REPOS 2>/dev/null # Remove old packages from repository tree [ $REMOVE_OLD_PACKAGE -eq 0 ] && rm $NEW_REPOS/$PACKAGE-*-*-*.tgz 2>/dev/null # Move package to SlackBuilds-like tree [ $MOVE_BIN_PACKAGE -eq 0 ] && mv $MAKEPKG_REPOS/$PKG_NAME $NEW_REPOS/ # Install package 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 $NEW_REPOS/$PKG_NAME fi