You are not logged in.

#1 2012-01-26 02:11:53

HirnBrot
Member
Registered: 2010-09-22
Posts: 13

An abs replacement

Hi,

a couple of weeks ago I made a small replacement for abs (the program, not the build service) in bash, using the git mirror as backend.

Now, I don't know if it is okay to clone the entire git mirror, I tried posting on the mailing list but got no answer.

http://www.archlinux.org/svn/ wrote:

DO NOT CHECK OUT THE ENTIRE SVN REPO. Your address may be blocked.

If any developer reads this, feel free to tell me what you think.

Features:

- Download and update the archlinux package repository
- Copy all build files (PKGBUILD,*.install, patches etc) to ./$pkgname (with abs.sh -b $PKG)
- Show git log of PKGBUILD (with abs.sh -l $PKG)
- Check if a package is in a certain repo (with abs.sh -t $REPO $PKG) or list an entire repos packages (without having it in pacman.conf)
- find a PKGBUILD that builds a certain package (with abs.sh -p $PKG) (Not tested much, just recently added)
- browse a packages directory with $EDITOR (I only know it works with vim but doesn't with nano) (with abs.sh -s $PKG)
- Suggest packages if $PKG wasn't found (also, as much regex as find does)

Limitations:

- Setup currently is more involved than I'd like (set $absdir and $communitydir to an existing directory (not the same), and run "abs.sh -i")
- Code is _really_ ugly as I'm not that well-versed in bash (for now I'm treating it as a proof of concept)
- The filestructure mimics that of the actual repo and because of that is more ugly than the current abs, with core/extra in one dir and community/multilib in another
- One cannot choose which repositories to download (and {kde,gnome}-unstable are not included AFAIK)
- Some random bugs
- No public git repo currently
- option parsing is quite limited (for now, just use one option on each operation)

Dependencies:
depends=(bash findutils git diffutils util-linux)


#!/bin/bash
#abs.sh , a proof-of-concept replacement for abs
#   Copyright (C) 2012  Fabian Homborg <FHomborg@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/>.

set -e
set -u

absdir=~/dev/arch-packages
communitydir=~/dev/community-packages
arch=$(arch)
configfile=""
communityrepo="git://projects.archlinux.org/svntogit/community.git/"
archrepo="git://projects.archlinux.org/svntogit/packages.git"
packagedir=""
packagename=""
[[ -e $configfile ]] && source $configfile

pkglog() {
    findpkg $1
    cd $packagedir/trunk
    git log PKGBUILD
}

abs() {
    [[ ! -z $absdir ]] && echo "Updating Core/Extra repo" && cd $absdir/ && git pull
    [[ ! -z $communitydir ]] && echo "Updating Community repo" && cd $communitydir && git pull
}

findpkg() {
    packagename=$1
    if [[ -d $absdir/$1 ]]; then
        echo "Package is in Core/Extra"
        packagedir="$absdir/$1"
        return 0
    else
        if [[ -d $communitydir/$1 ]]; then
            echo "Package is in Community"
            packagedir="$communitydir/$1"
            return 0
        else
            echo "Package not found"
            others=$(find $absdir $communitydir -maxdepth 1 -name "*$1*" -type d)
            othernum=$(echo "$others" | wc -l)
            if [[ 0 -lt "$othernum" ]]; then    #Why this is 1 eludes me
                echo "Did you mean:"
                echo "$others" | cat -b
                read num
                [[ "$num" -gt 0 ]] && [[ "$num" -le "$othernum" ]] || return 4
                packagedir=$(echo "$others" | head -n "$num" | tail -n 1)
                packagename=$(basename $packagedir)
                unset num
                unset others
                return 0
            else
                exit 4 # Yes, exit here, package could not be found
            fi
        fi
    fi
}

pkgprovider(){
    # 0 All okay
    # 1 No parameter
    # 2 Nothing found
    [[ -z $1 ]] && return 1
            providers=$(grep -R "pkgname=" $absdir/*/trunk/PKGBUILD | grep "$1" | cut -d":" -f1 | sed -e "s:$absdir/::" -e "s:$communitydir/::" -e "s:/trunk/PKGBUILD::")
            if [[ ! -z $providers ]]; then
                echo $providers
                return 0
            fi
            echo "Nothing found"
            return 2
            }

pkgbuild() {
    # Move all necessary build files to $PWD/$PKGNAME
    # Usage: pkgbuild $PKG
    # Example: pkgbuild gcc
    #
    # Returncodes:
    # 0 All OK
    # 1 Reponumber invalid
    # 2 mkdir failed
    # 3 copying failed
    # 4 package not found
    # 5 No option passed (Shouldn't reach this)
    [[ -z ${1-} ]] && return 5
    pkg=$1
    pkgdir=$absdir/$pkg
    findpkg $1
    [[ 0 -lt $? ]] && exit 4
    pkg=$packagename
    if [[ -z $packagedir ]]; then
        return 4
    fi
    a=$(ls $packagedir/repos/ | grep "$arch\|any") 
    repocount=$(echo "$a" | wc -l)
    if [[ $repocount -ge 2 ]]; then
        echo "Which repo? (0 to exit)"
        echo "$a" | cat -b
        read num
        # 0<$num<=$repocount (AND $num is an integer)
        # Bail out on $num=0
        if ([[ "$num" -le "$repocount" ]] && [[ "$num" -gt 0 ]]); then
                repo=$(echo "$a" | head -n "$num" | tail -n 1)
        else 
            return 1
        fi
    else
        if [[ $repocount -eq 0 ]]; then
            echo "Package $pkg is not in repositories"
            return 4
        fi
        repo=$a
    fi
    echo "Copying $pkg build files from $repo to ./$pkg"
    mkdir $pkg || return 2
    cp $packagedir/repos/$repo/* ./$pkg || return 3
}

testingpkgs(){
    if [[ -z ${1-} ]]; then
        repo="testing"
    else
        repo=$1
    fi
    pkg=${2-}
    if [[ -z $pkg ]]; then
        cd $absdir
        find */repos/ -name *$repo* -type d | cut -d"/" -f1 | uniq
        cd $communitydir
        find */repos/ -name *$repo* -type d | cut -d"/" -f1 | uniq
    else
        findpkg $pkg
        if [[ -d $packagedir/repos/$repo-$arch ]];then
            echo "$packagename is in $repo-$arch"
        else
            if [[ -d $packagedir/repos/$repo-any ]]; then
                echo "$packagename is in $repo-any"
            else
                echo "$packagename is not in repo-$arch"
            fi
        fi
    fi
}

init(){
    if [[ ! "$absdir" == "" ]]; then
        if [[ -d "$absdir" ]]; then
            cd $absdir
            echo "Initializing $absdir"
            git clone $archrepo ./ || echo "$absdir is not empty. Is it already initialized?"
        fi
    fi
    if [[ ! "$communitydir" == "" ]]; then
        if [[ -d "$communitydir" ]]; then
            cd $communitydir
            git clone $communityrepo ./ || echo "$communitydir is not empty. Is it already initialized?"
        fi
    fi
}

diffIt(){
    if [[ -e ./PKGBUILD ]]; then
        findpkg $1
        diff -u ./PKGBUILD $packagedir/trunk/PKGBUILD
    else
        echo "No PKGBUILD in working directory"
        exit 1
    fi
}

USAGEMESSAGE='abs -[tlbuspi] [$REPO] $PKG
-t : Check if $PKG is in $repo
     Without $PKG, show all packages in $repo
-l : Show git-log for $PKG
-b : Copy build files for $PKG to current working directory
-u : Update abs-tree
-s : Show $PKG in $EDITOR (NOTE: This currently opens the _parent directory_ in $EDITOR, so it needs an editor capable of opening directories)
-p : Find PKGBUILDs that build $PKG
-i : Initialize the repos'

case ${1-} in
    "-p"|"--provider") pkgprovider ${2-};;
    "-h"|"--help" ) echo "USAGE: $USAGEMESSAGE";;
    "-t" ) testingpkgs ${2-} ${3-};;
    "-l"|"--log" ) pkglog $2;;
    "-b"|"--build" ) pkgbuild $2;;
    "-u"|"" ) abs;;
    "-i"|"--init" ) init;;
    "-d" | "--diff" ) diffIt $2;;
    "-s" | "--show" ) findpkg $2; $EDITOR $packagedir;;
    * ) echo "USAGE: $USAGEMESSAGE";;
esac

Offline

#2 2012-12-08 22:03:06

technic
Member
Registered: 2012-09-02
Posts: 7

Re: An abs replacement

Hi I also think using git is better. It would be great to have own fork of PKGBUILD tree and easily merge it with upstream. When there is update available rebuild only packages that differs. Could you please tell me if similar tool already exists ? Maybe you have updates of this bash script ?

Offline

#3 2012-12-08 23:26:53

Allan
Pacman
From: Brisbane, AU
Registered: 2007-06-09
Posts: 11,365
Website

Re: An abs replacement

HirnBrot wrote:

I don't know if it is okay to clone the entire git mirror,

That should be fine.

Offline

#4 2012-12-09 15:13:39

HirnBrot
Member
Registered: 2010-09-22
Posts: 13

Re: An abs replacement

technic wrote:

It would be great to have own fork of PKGBUILD tree and easily merge it with upstream. When there is update available rebuild only packages that differs. Could you please tell me if similar tool already exists ?

This doesn't do that and AFAIK it would require a huge rewrite/change. I'm also not aware of anything that does that. I'll look into it.

technic wrote:

Maybe you have updates of this bash script ?

I have some updates, the last one was on August 12th.

I've been using it pretty much every day since I posted here and I quite like it.

Allan wrote:

That should be fine.

Thanks.

Do you think the idea is valid?

Offline

Board footer

Powered by FluxBB