summaryrefslogtreecommitdiff
path: root/fullpkg
blob: a23a448fb4cc46d8c1297a736215a0ff816c11e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
#!/bin/bash
# TODO
# * Do version checking
# * Detect circular builds
# * Detect pkgnames by provides, replaces, etc. instead of dir tree

source /etc/makepkg.conf
source /etc/abs.conf
source /etc/libretools.conf

[[ -r ~/.config/libretools/libretools.conf ]] && \
    source ~/.config/libretools/libretools.conf

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 " -f          : build even when a package has been built."
    echo " -n absdir   : set ABSROOT to this dir"
    echo " -r reponame : set repo name to reponame"
    echo " -R pkgname  : build pkgname if it is a dep"
    echo
}

force_build='n'
force_array=()
_fullpkgargs=""
failed=()
missing=()

while getopts 'hfn:r:R:' arg; do
    case $arg in
	h) usage; exit 0 ;;
	f) force_build='y' ;;
	R) force_array=(${force_array[@]} $OPTARG); _fullpkgargs+="-R $OPTARG ";;
	n) ABSROOT="$OPTARG" ;;
	r) repo="$OPTARG" ;;
    esac
done

[[ ! -r PKGBUILD ]] && {
    error "This isn't a build directory"
    echo
    usage
    exit 1
}

tmp_dir=$(mktemp -d /tmp/$(basename $PWD).XXXXXX)
queue_file=$(mktemp /tmp/queue.XXXXXX)
ban_file=$(mktemp /tmp/ban.XXXXXX)

## START FUNCTIONS ##

# Queue Management
# * Always get the queue list from the server
# * Add/Remove from queue
# * Check if a package is listed

# TODO
# * Check for concurrence

# Get the queue list from the server
get_queue() {
    rsync -e ssh -aq $PARABOLAHOST:mips64el/queue $queue_file >/dev/null 2>&1 || {
        error "Failed to retrieve queue list"
        return 1
    }
}

# Put the queue list on the server
put_queue() {
    rsync -e ssh -aq $queue_file $PARABOLAHOST:mips64el/queue >/dev/null 2>&1 || {
        error "Failed to put queue list"
        return 1
    }
}

# Add packages to the queue
update_queue() {
    get_queue || return $?

    basename $PWD | sed "s/$/:$PACKAGER/" >> $queue_file || return 2

    put_queue || return $?
}

# Remove a package from the queue
remove_queue() {
    get_queue || return $?

    grep -vw "^$(basename $PWD)" $queue_file > $queue_file.2
    cat $queue_file.2 > $queue_file

    put_queue && rm $queue_file{,.2}  && return 0 || return $?
}

# Checks if a package is listed
check_queue() {
    get_queue || return $?

    packager=$(grep -w "$(basename $PWD)" ${queue_file} | cut -d ':' -f2)

    [[ ! -z $packager ]] && [[ "$packager" != "$PACKAGER" ]] && {
        warning "$(basename $PWD) is being packaged by $packager. Please wait."
        return 1
    }

    return 0
}

# END Queue Management #

# Checks if the package is banned from building
is_banned() {
    rsync -e ssh -aq $PARABOLAHOST:mips64el/ban $ban_file >/dev/null 2>&1 || {
        plain "Failed to get ban list"
        return 1
    }
    grep -w $1 $ban_file >/dev/null 2>&1
    return $?
}

guess_repo() {
    basename $(dirname $(pwd))
}

#  usage : in_array( $needle, $haystack )
# return : 0 - found
#          1 - not found
function in_array {
    [[ $2 ]] || return 1
    local needle=$1; shift
    local item
    for item in "$@"; do
	[[ ${item#@} = $needle ]] && return 0
    done
    return 1 # Not Found
}

function quit {
    remove_queue
    exit 1
}

function cleanup {
    rm $ban_file $queue_file
    rm -rf $tmp_dir
}

# TODO keep track of spawned fullpkgs

## END FUNCTIONS ##

source PKGBUILD
repo=${repo:-$(guess_repo)}
msg "Building ${repo:-missing repo}/${pkgbase:-${pkgname[@]}}: $pkgdesc"

# Pre build tests
if [ $force_build == 'n' ]; then

    # Be able to write files
    if [[ ! -w $queue_file ]]; then
	error "can't write queue file"
	exit 1
    elif [[ ! -w $ban_file ]] ; then
	error "can't write ban file"
	exit 1
    fi

    if is_built "${pkgbase:-${pkgname[0]}}>=${pkgver}-${pkgrel}"; then
	msg2 "This package is built."
	exit 0
    fi

    if is_banned ${pkgbase:-$pkgname}; then 
	error "This package is banned from building. Check the ban list"
	exit 1
    fi

    check_queue || exit 1

fi

# This will be executed at exit for any reason.
trap "quit" EXIT INT QUIT TERM KILL HUP

if ! grep mips64el PKGBUILD >/dev/null; then
  msg "Adding mips64el arch"
  sed -i "s/^\(arch=([^)anym]\+\))/\1 'mips64el')/" "PKGBUILD"
fi

# Clean version checking
deps=$(echo "${depends[@]} ${makedepends[@]} ${pkgdeps[@]}" | \
    sed "s/[=<>]\+[^ ]\+//g" | \
    tr ' ' "\n" | \
    sort -u)

msg "Checking dependencies"
for _dep in ${deps[@]}; do
    is_banned $_dep && continue

    for _repo in ${REPOS[@]}; do
        # TODO find split packages
        [[ -e "$ABSROOT/${_repo}/$_dep/PKGBUILD" ]] && {
            source "$ABSROOT/${_repo}/$_dep/PKGBUILD"
            msg2 "Checking for $_dep>=$pkgver-$pkgrel"
	    
            if ! in_array $_dep ${force_array[@]}; then
              if is_built "$_dep>=$pkgver-$pkgrel"; then
                  plain "this package is built"
                  break
              fi
            else
              _fullpkgargs+="-f "
              _fullpkgargs="$(echo $_fullpkgargs | sed s/"-R $_dep "//)"
              force_array=( $(echo ${forcearray[@]} | tr " " "\n" | grep -vw "^$_dep") )
            fi
	    
            cp -r "$ABSROOT/$_repo/$_dep" $tmp_dir/ || {
                error "Can't copy $_dep to the work dir."
                exit 1
            }

            # Enter the work dir and run this command in it
            pushd $tmp_dir/$_dep >/dev/null

	    $0 -r $_repo $_fullpkgargs

            [[ $? -ne 0 ]] && {
                failed=(${failed[@]} $_dep)
            }

            popd >/dev/null
        }
    done
done

# TODO probably not elegant enough
# TODO only the last fullpkg should show this message
#      and it should contain all failed pkgs
[[ ${#failed[@]} -gt 0 ]] && {
    error "This packages failed to build: ${failed[@]}"
    exit 1
}

# Let everybody know we're building this
update_queue || {
    warning "Couldn't update the queue, let your partners know about this."
}

cp -r ../$(basename $PWD) $tmp_dir/
pushd $tmp_dir/$(basename $PWD) >/dev/null

msg "Syncing database"
sudo pacman -Syu --noconfirm
makepkg --noconfirm  --nocheck -sLcr ; r=$?
case $r in
    0) msg "The build was succesful."
       mipsrelease *.pkg.tar.*
       librestage $repo
       sudo pacman -Sy
       # cleanup is only on succesfull build so failed can be inspected
       cleanup;;
    1) error "There were errors while trying to build the package." ;;
    2) error "The build failed." ;;
esac

exit $r