This repository was archived by the owner on Aug 9, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 95
Expand file tree
/
Copy pathabs.sh.in
More file actions
485 lines (433 loc) · 15.1 KB
/
Copy pathabs.sh.in
File metadata and controls
485 lines (433 loc) · 15.1 KB
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
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
#!/bin/bash
#
# abs.sh
# This file is part of Yaourt (http://archlinux.fr/yaourt-en)
RSYNCCMD=$(type -p rsync 2> /dev/null)
RSYNCOPT="-mrtv --no-motd --no-p --no-o --no-g"
ABSCONF=0
load_lib alpm_query
load_lib pkgbuild
# source abs configuration
source_abs_conf() {
((ABSCONF)) && return || ABSCONF=1
local vars=()
local abs_conf
[[ ! $SYNCSERVER ]] && vars+=(SYNCSERVER)
[[ ! $REPOS ]] && vars+=(REPOS)
if [[ $vars ]]; then
abs_conf=$(
[[ -r "@sysconfdir@/abs.conf" ]] &&
source "@sysconfdir@/abs.conf" > /dev/null
[[ -r ~/.abs.conf ]] &&
source ~/.abs.conf > /dev/null
declare -p ${vars[*]} 2>/dev/null | tr '\n' ';'
)
[[ ! $abs_conf ]] && return
# Change vars names because "declare" create a local var
abs_conf=${abs_conf//SYNCSERVER/_SYNCSERVER}
abs_conf=${abs_conf//REPOS/_REPOS}
eval "$abs_conf"
SYNCSERVER=${SYNCSERVER:-$_SYNCSERVER}
[[ ! $REPOS ]] && REPOS=(${_REPOS[@]})
fi
}
# Get sources in current dir
# Usage abs_get_pkgbuild ($repo/$pkg[,$arch,[$pkgbase]])
abs_get_pkgbuild() {
source_abs_conf
local repo=${1%/*} pkg=${1#*/} arch=$2 pkgbase=$3 pkgver=
if [[ ! $arch || ! $pkgbase ]]; then
read arch pkgver < <(pkgquery -1Sif '%a %v' "$repo/$pkg")
pkgbase=$(get_pkgbase $pkg $repo $pkgver)
fi
if ((USE_GIT)) && [[ " ${REPOS[*]} " =~ " $repo " ]]; then
local url
if [[ $repo = "core" || $repo = "extra" ]]; then
url="https://projects.archlinux.org/svntogit/packages.git/snapshot/packages/$pkgbase.tar.gz"
else
url="https://projects.archlinux.org/svntogit/community.git/snapshot/community-packages/$pkgbase.tar.gz"
fi
curl_fetch -L -f "$url" -o - | bsdtar --strip-components 3 --include="*/$pkgbase/trunk/" -xvf -
else
if [[ $RSYNCCMD && $SYNCSERVER && " ${REPOS[*]} " =~ " $repo " ]]; then
$RSYNCCMD $RSYNCOPT "$SYNCSERVER::abs/$arch/$repo/$pkgbase/" . && return 0
fi
# TODO: store abs archive somewhere else.
local abs_tar="$YAOURTTMPDIR/$repo.abs.tar.gz"
local abs_url
local repo_date=$(stat -c "%Z" "${P[dbpath]}/sync/$repo.db")
local abs_repo_date=$(stat -c "%Z" "$abs_tar" 2> /dev/null)
if [[ ! $abs_repo_date ]] || (( ${abs_repo_date%.*} < ${repo_date%.*} )); then
abs_url=$(pkgquery -1Sif "%u" "$repo/$pkg")
abs_url="${abs_url%/*}/$repo.abs.tar.gz"
msg "$repo/$pkgbase: $(gettext 'Download abs archive')"
curl_fetch -L -f -# "$abs_url" -o "$abs_tar" || return 1
fi
bsdtar --strip-components 2 -xvf "$abs_tar" "$repo/$pkgbase"
fi
}
# Build from abs or aur
build_pkg() {
[[ $1 ]] || return 1
while [[ $1 ]]; do
local repo pkg=${1#*/}
[[ $1 != $pkg ]] && repo=${1%/*} || repo="$(sourcerepository "$pkg")"
if [[ $repo = "aur" || $repo = "local" ]]; then
install_from_aur "$pkg"
else
BUILD=1 install_from_abs "$repo/$pkg"
fi
shift;
done
}
# Build packages from repos
install_from_abs() {
local cwd build_deps
declare -a pkginfo=($(pkgquery -1Sif "%r %n %v %a" "$1"))
(( ! BUILD )) && ! custom_pkg "${pkginfo[1]}" &&
bin_pkgs+=("${pkginfo[0]}/${pkginfo[1]}") && return 0
(( BUILD > 1 )) && build_deps=2 || build_deps=0
msg $(_gettext 'Building %s from sources.' "${pkginfo[1]}")
title $(_gettext 'Install %s from sources' "${pkginfo[1]}")
echo
msg $(gettext 'Retrieving PKGBUILD and local sources...')
cwd=$PWD
init_build_dir "$YAOURTTMPDIR/abs-${pkginfo[1]}" || return 1
abs_get_pkgbuild ${pkginfo[0]}/${pkginfo[1]} ${pkginfo[3]} ||
{ cd "$cwd"; return 1; }
# Build, install/export
BUILD=$build_deps package_loop ${pkginfo[1]} 1 ||
manage_error ${pkginfo[1]} ||
{ cd "$cwd"; return 1; }
cd "$cwd"
rm -rf "$YAOURTTMPDIR/abs-${pkginfo[1]}"
}
# Retrieve the list of packages existing in repos with pending upgrade
# Set vars:
# - pkgs_repo_up_info=(properties of packages to upgrade)
# - pkgs_repo=(packages to get directly from repo)
# - pkgs_src=(packages to upgrade from PKGBUILD)
fetch_pkgs_repo_up_list() {
unset pkgs_repo_up_info pkgs_repo pkgs_src upgrade_needed
local packages pkgname repo
# Retrieve list of pending upgrades from repos
(( UPGRADES > 1 )) && local _arg="-uu" || local _arg="-u"
# `pacman -Spu` fails in some cases (e.g: when a package is replaced
# by another one)
if pacman_parse -Sp --noconfirm --print-format "## %n" $_arg \
"${PACMAN_S_ARG[@]}" "${pkg_up[@]}" >"$YAOURTTMPDIR/sysupgrade"; then
packages=($(sed -n 's/^## \(.*\)/\1/p' "$YAOURTTMPDIR/sysupgrade" | sort))
rm "$YAOURTTMPDIR/sysupgrade"
[[ $packages ]] && upgrade_needed=1 || { upgrade_needed=0; return 0; }
else
# `pacman -Spu` failed so we don't know which packages
# will be updated
DETAILUPGRADE=0; upgrade_needed=1; return 1
fi
# package-query invocations are expensive, hence, the result is saved
# in a global variable which can be used later by format_update().
mapfile pkgs_repo_up_info < <(pkgquery -1Sif "%n %r %v %l %d" "${packages[@]}")
while read pkgname repo unused; do
if (( BUILD )) || custom_pkg "$pkgname"; then
pkgs_src+=("$repo/$pkgname")
else
pkgs_repo+=("$repo/$pkgname")
fi
done < <(echo -n "${pkgs_repo_up_info[@]}")
}
# Retrieve the list of AUR packages with pending upgrade
# Set vars:
# - pkgs_aur=(packages to upgrade from AUR)
# - pkgs_aur_up_info=(properties of packages to upgrade from AUR)
fetch_pkgs_aur_up_list() {
unset pkgs_aur_up_info pkgs_aur
local pkgname repo rversion lversion outofdate maintainer pkgdesc
local pkgs_foreign_count pkgs_foreign_info prefix='' i=0 bar="|/-\\"
# Retrieve the list of all foreign packages
mapfile pkgs_foreign_info < <(pkgquery -AQmf "%n %r %v %l %o %m %d")
if [[ $aur_up ]]; then
mapfile -O "${#pkgs_foreign_info[@]}" pkgs_foreign_info < \
<(pkgquery --pkgbase -Aif "%n %r %v - %o %m %d" "${aur_up[@]}")
fi
if ((DETAILUPGRADE)); then
((REFRESH)) && printf -v prefix "\r " || printf -v prefix "\r"
pkgs_foreign_count=$(pacman_parse -Qqm | wc -l)
fi
# Keep only packages with pending upgrade in AUR
while read pkgname repo rversion lversion outofdate maintainer pkgdesc; do
(( DETAILUPGRADE==1 )) && \
echo -en "$prefix$(gettext 'Foreign packages: ')${bar:$((++i%4)):1} $i / $pkgs_foreign_count"
[[ "$repo" = "local" ]] && continue
if [[ "$repo" = "aur" && ${lversion#-} ]]; then
aur_update_exists "$pkgname" "$rversion" "$lversion" "$outofdate" "$maintainer" \
|| continue
fi
# package-query invocations are expensive, hence, the result is saved
# in a global variable which can be used later by format_update().
pkgs_aur_up_info+=("$pkgname $repo $rversion $lversion $pkgdesc"$'\n')
pkgs_aur+=("$repo/$pkgname")
done < <(echo -n "${pkgs_foreign_info[@]}")
(( DETAILUPGRADE==1 && pkgs_foreign_count > 0 )) && echo
}
# Set vars:
# - upgrade_details=(new release, new version then new pkgs)
# Usage: format_update < [one pkg / line ]
# Read from stdin: pkgname repo rversion lversion pkgdesc
format_update() {
declare -a newrelease newversion newpkgs
longestpkg=(0 0)
local pkgname repo rversion lversion pkgdesc \
pkgver lrel rrel lver rver
while read pkgname repo rversion lversion pkgdesc; do
printf -v pkgdesc "%q" "$pkgdesc"
if [[ "$lversion" != "-" ]]; then
pkgver=$lversion
lrel=${lversion#*-}
rrel=${rversion#*-}
lver=${lversion%-*}
rver=${rversion%-*}
if [[ "$rver" = "$lver" ]]; then
# new release not a new version
newrelease+=("1 $repo $pkgname $pkgver $lrel $rrel $pkgdesc")
else
# new version
newversion+=("2 $repo $pkgname $pkgver $rversion - $pkgdesc")
fi
else
# new package (not installed at this time)
pkgver=$rversion
local requiredbypkg=""
local pkg_dep_on=( $(pkgquery -S1if "%N" "$pkgname") )
for pkg in ${pkg_dep_on[@]}; do
[[ " ${pkgs_repo[@]#*/} " =~ " $pkg " ]] && requiredbypkg=$pkg && break
done
[[ ! $requiredbypkg ]] && requiredpkg=$(pkgquery -Sf'%R' "$pkgname")
[[ ! ${requiredbypkg#-} ]] && requiredpkg=$(printf "%q" "$(gettext 'not found')")
newpkgs+=("3 $repo $pkgname $pkgver $requiredbypkg - $pkgdesc")
fi
(( ${#repo} + ${#pkgname} > longestpkg[0] )) && longestpkg[0]=$(( ${#repo} + ${#pkgname}))
(( ${#pkgver} > longestpkg[1] )) && longestpkg[1]=${#pkgver}
done
(( longestpkg[1]+=longestpkg[0] ))
upgrade_details=("${newrelease[@]}" "${newversion[@]}" "${newpkgs[@]}")
}
display_update() {
# Show result
show_upgrades lite
# Show detail on upgrades
while true; do
echo
msg "$(gettext 'Continue upgrade ?') $(yes_no 1)"
prompt "$(gettext '[V]iew package detail [M]anually select packages')"
local answer=$(userinput "YNVM" "Y")
case "$answer" in
V) show_upgrades full;;
M) show_upgrades manual
run_editor "$YAOURTTMPDIR/sysuplist" 0
SYSUPGRADE=2
SP_ARG="" sync_packages "$YAOURTTMPDIR/sysuplist"
return 2
;;
Y) break;;
*) return 1;;
esac
done
}
show_targets() {
local t="$(gettext "$1") "; shift
t+="($#): "
echo
echo_wrap_next_line "$CYELLOW$t$C0" ${#t} "$*"
echo
prompt "$(gettext 'Proceed with upgrade? ') $(yes_no 1)"
useragrees
}
# Searching for packages to update, buid from sources if necessary
sysupgrade() {
local pkg
declare -a aur_up pkg_up
if ((AURUPGRADE)); then
if [[ $ARGS ]]; then
pkg_up=($(pkgquery -1Siif '%n' "${ARGS[@]}"))
if (( ${#ARGS[@]} > ${#pkg_up[@]} )); then
aur_up=($(pkgquery -1Aiif '%n' "${ARGS[@]}"))
fi
fi
else
pkg_up=("${ARGS[@]}")
fi
(( UP_NOCONFIRM )) && { EDITFILES=0 AURCOMMENT=0; BUILD_NOCONFIRM=1; }
# Retrieve the list of packages to upgrade
((REFRESH)) && pacman_refresh $REFRESH
fetch_pkgs_repo_up_list
((AURUPGRADE)) && fetch_pkgs_aur_up_list
# Upgrade packages from sources
if [[ $pkgs_src ]]; then
show_targets 'Source targets' "${pkgs_src[@]#*/}" || return 0
build_pkg "${pkgs_src[@]}"
local ret=$?
# Refresh update list because packages may have been customized
fetch_pkgs_repo_up_list
fi
((upgrade_needed)) || [[ $pkgs_aur ]] || return $ret
# Display update info
if ((DETAILUPGRADE)); then
format_update < \
<(echo -n "${pkgs_repo_up_info[@]}" "${pkgs_aur_up_info[@]}")
display_update || return 0
fi
# Upgrade packages from repos
if ((upgrade_needed)); then
(( UPGRADES > 1 )) && local _arg="-uu" || local _arg="-u"
su_pacman -S "${PACMAN_S_ARG[@]}" $_arg "${pkg_up[@]}" || return $?
fi
# Upgrade AUR packages
if [[ $pkgs_aur ]]; then
(( ! DETAILUPGRADE )) && { show_targets 'AUR targets' "${pkgs_aur[@]#aur/}" || return 0; }
for pkg in ${pkgs_aur[@]}; do
install_from_aur "$pkg" || error $(_gettext 'unable to update %s' "$pkgname")
done
fi
}
# Show package to upgrade
show_upgrades() {
# $1=full or $1=lite or $1=manual
if [[ "$1" = "manual" ]]; then
> "$YAOURTTMPDIR/sysuplist"
local separator=$(echo_fill "" "#" "")
fi
local exuptype=0 line _msg requiredbypkg
for line in "${upgrade_details[@]}"; do
eval line=($line)
if (( exuptype != ${line[0]} )); then
case "${line[0]}" in
1) _msg="$(gettext 'Package upgrade only (new release):')";;
2) _msg="$(gettext 'Software upgrade (new version) :')";;
3) _msg="$(gettext 'New package :')";;
esac
exuptype=${line[0]}
if [[ "$1" = "manual" ]]; then
echo -e "\n$separator\n# $_msg\n$separator" >> "$YAOURTTMPDIR/sysuplist"
else
echo
msg "$_msg"
fi
fi
if [[ "$1" = "manual" ]]; then
echo -n "${line[1]}/${line[2]} # " >> "$YAOURTTMPDIR/sysuplist"
case "${line[0]}" in
1) echo "${line[3]} ${line[4]} -> ${line[5]}";;
2) echo "${line[3]} -> ${line[4]}";;
3) requiredbypkg=${line[4]}
echo "${line[3]} $(_gettext '(required by %s)' "$requiredbypkg")";;
esac >> "$YAOURTTMPDIR/sysuplist"
echo "# ${line[6]}" >> "$YAOURTTMPDIR/sysuplist"
else
case "${line[0]}" in
1) printf "%*s $CBOLD%s$C0 -> $CRED%s$C0" ${longestpkg[1]} "" "${line[4]}" "${line[5]}";;
2) printf "%*s -> $CRED%s$C0" ${longestpkg[1]} "" "${line[4]}";;
3) requiredbypkg=${line[4]}
printf "%*s $CRED%s$C0" ${longestpkg[1]} "" "$(_gettext '(required by %s)' "$requiredbypkg")";;
esac
printf "\r%-*s $CGREEN%s$C0" ${longestpkg[0]} "" "${line[3]}"
echo -e "\r${C[${line[1]}]:-${C[other]}}${line[1]}/$C0${C[pkg]}${line[2]}$C0"
if [[ "$1" = "full" ]]; then
echo_wrap 4 "${line[6]}"
fi
fi
done
}
unset SP_ARG
# Sync packages
sync_packages() {
# Install from a list of packages
if [[ -f $1 ]] && file -b "$1" | grep -qi text ; then
if (( ! SYSUPGRADE )); then
title $(gettext 'Installing from a package list')
msg $(gettext 'Installing from a package list')
fi
AURVOTE=0
set -- $(grep -o '^[^#[:space:]]*' "$1")
fi
[[ $1 ]] || return 0
# Install from arguments
declare -A pkgs_search pkgs_found pkgs_cached repo_pkgs aur_pkgs cached_pkgs
declare -a bin_pkgs
local _arg=("$@") _pkg repo pkg target
[[ $SP_ARG ]] && _arg=($(pacman_parse -T "${_arg[@]}"))
for _pkg in "${_arg[@]}"; do pkgs_search[$_pkg]=1; done
# Search for exact match, pkg which provides it, then in AUR
local tmpfile=$(mktemp --tmpdir="$YAOURTTMPDIR")
pkgquery -f "%r %n %t %v" -1SAii "${!pkgs_search[@]}" 2>/dev/null >$tmpfile
[[ "$?" != "0" ]] && warning "no network connection" ||
while read repo pkg target version; do
((pkgs_search[$target])) || continue
unset pkgs_search[$target]
((pkgs_found[$pkg])) && continue
pkgs_found[$pkg]=1
[[ "$(ls "$CACHE_DIR" | grep "^${pkg}")" ]] &&
pkgs_cached["${pkg}"]="${version}"
if [[ "${repo}" != "aur" ]]; then
repo_pkgs[$pkg]="${repo}/${pkg}"
else
((NEEDED)) && pkgquery -Qqii "$target" && continue
aur_pkgs[$pkg]=1
fi
done < $tmpfile
# In case there is a double version check, eg. pkg1>0.1 pkg2<0.3
# package-query does only one check, so perform the remaining checks
for pkg in "${!pkgs_search[@]}"; do
local _pkg=${pkg%%[<>=]*}
local _cached="$(ls "$CACHE_DIR" | grep "^$_pkg")"
if [[ " ${!pkgs_found[@]} " =~ " $_pkg " ]]; then
pkgquery -q -1SAii "$pkg" && unset pkgs_search[$pkg]
elif [[ $_cached ]]; then
cached_pkgs[$_pkg]="$CACHE_DIR/$_cached" && unset pkgs_search[$pkg]
fi
done
# Install from cached packages
for _pkg in "${!pkgs_cached[@]}"; do
local _cached="$(ls "$CACHE_DIR" | grep "^$_pkg")"
if [[ $_cached ]]; then
[[ "$_cached" = ${_pkg}-${pkgs_cached["$_pkg"]}* ]] &&
cached_pkgs[$_pkg]="$CACHE_DIR/$_cached"
fi
done
(( ! DOWNLOAD_ONLY)) && for _pkg in "${!cached_pkgs[@]}"; do
local _file="${cached_pkgs[$_pkg]}"
su_pacman -U "${PACMAN_S_ARG[@]}" "$_file" &&
unset aur_pkgs[$_pkg] && unset repo_pkgs[$_pkg] ||
manage_error "$_pkg" || return 1
done
bin_pkgs=("${!pkgs_search[@]}")
for _pkg in "${repo_pkgs[@]}"; do
install_from_abs "$_pkg" || return 1
done
if [[ $bin_pkgs ]]; then
if [[ $SP_ARG ]]; then
su_pacman -S --asdeps --needed "${PACMAN_S_ARG[@]}" "${bin_pkgs[@]}" || return 1
else
su_pacman -S "${PACMAN_S_ARG[@]}" "${bin_pkgs[@]}" || return 1
fi
fi
for _pkg in "${!aur_pkgs[@]}"; do
install_from_aur "$_pkg" || return 1
done
return 0
}
# Search to upgrade devel package
upgrade_devel_package() {
declare -a devel_pkgs
title $(gettext 'upgrading SVN/CVS/HG/GIT package')
msg $(gettext 'upgrading SVN/CVS/HG/GIT package')
local _arg="-Qq" pkg
((AURDEVELONLY)) && _arg+="m"
for pkg in $(pacman_parse $_arg | grep "\-\(svn\|cvs\|hg\|git\|bzr\|darcs\)$")
do
is_package_ignored "$pkg" && continue
devel_pkgs+=($pkg)
done
[[ $devel_pkgs ]] || return 0
show_targets 'Targets' "${devel_pkgs[@]}" && build_pkg "${devel_pkgs[@]}"
}
# vim: set ts=4 sw=4 noet: