-
Notifications
You must be signed in to change notification settings - Fork 0
/
check-updates
executable file
·159 lines (141 loc) · 4.15 KB
/
check-updates
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
#!/bin/bash
#
# License: MIT
# Author: Benoit DOLEZ <[email protected]>
# Copyright: 2019
#
set -o pipefail
set -f
PROGNAME=${0##*/}
SUFFIX="(tar\\.gz|tgz|tar\\.xz|tar\\.bz2|tbz|zip|(src\\.)?rpm)"
CACHEDIR=${CACHEDIR:-/tmp/$PROGNAME}
curlopts=( --connect-timeout 10 -fLs --netrc-optional )
function curl_github_api_pages() {
local pages p
pages=$(set -o pipefail; curl "${curlopts[@]}" -I "$1?per_page=100" |
sed -nre 's,^link:.*[?&]page=([0-9]+)>; rel="last".*,\1,p') || return $?
if [[ -z $pages ]]; then
curl "${curlopts[@]}" "$1?per_page=100"
else
for (( p = 1; p <= pages; p++ )); do
curl "${curlopts[@]}" "$1?per_page=100&page=$p"
sleep 1
done
fi
}
function get-data-lynx() {
local url=$1 ; shift
lynx -dump "$url" | sed -n -r -e 's/^[ 0-9]+\. //p'
}
function get-data-json() {
local url=$1 ; shift
local expression=${1:-.} ; shift
local pattern='(?<=")'${1:-'[a-z+]+://.+'}'(?=")' ; shift
if [[ $url == https://api.github.com/* ]]; then
curl_github_api_pages "$url"
else
curl "${curlopts[@]}" "$url"
fi |jq "$expression" |grep -Pio "$pattern"
}
function get-data() {
local method=( ${1//:/$IFS} ) ; shift
if declare -F -f "$FUNCNAME-$method"; then
"$FUNCNAME-$method" "$1" "${method[@]:1}" || return 1
else
return 1
fi
}
function check-updates() {
local base=$1 ; shift
local current=$1 ; shift
local method=$1 ; shift
local url=$1 ; shift
local vpattern="${1:-[0-9.]+}"
local pattern=$1 ; shift
local rewrite=${1:-"\2\t\1"} ; shift
local source version last current
# pattern need to respect this
# $1 : PATH
# $2 : FILE
# $3 : SUFFIX
if [[ -z $url ]]; then
echo "[FATAL] need at least an url" >&2
exit 1
fi
if [[ -z $base ]]; then
base=${url##*/}
url=${url%/*}
base=${base%%-[0-9]*}
fi
if [[ -z $pattern ]]; then
pattern=".*/($base-($vpattern)\\.$SUFFIX)"
elif [[ ${pattern:0:1} == "-" ]]; then
pattern=".*/($base-($pattern)\\.$SUFFIX)"
elif [[ ${pattern:0:1} == "/" ]] ; then
s=$pattern
pattern=".*/${s%/*}/(${s##*/}\\.$SUFFIX)"
elif [[ ${pattern:0:1} == "<" ]]; then
pattern=".*\\<(${pattern:1})"
elif [[ ${pattern:0:1} == "=" ]]; then
pattern=".*/(${pattern:1})"
else
pattern=".*/($pattern\\.$SUFFIX)"
fi
echo "# $base ($url)" >&2
[[ $VERBOSE ]] && echo "pattern: $pattern" >&2
[[ $VERBOSE ]] && echo "rewrite: $rewrite" >&2
h=( $base-$(echo "$method,$url" | md5sum) )
[[ $VERBOSE ]] && echo "hash: $h" >&2
if [[ $FORCE || ! -s $CACHEDIR/$h.data ]] &&
! get-data "$method" "$url" > $CACHEDIR/$h.data ; then
echo "[ERROR] can't get data for $base ($method)" >&2
return 1
fi
## FIXME : remove .zip when .tgz exists
[[ -z $FORCE && -s $CACHEDIR/$h.list ]] ||
cat $CACHEDIR/$h.data |
sed -r -n -e "s'^$pattern$'\0\t$rewrite'p" |
sort -t $'\t' -u -k 2V,2 > $CACHEDIR/$h.list
while read -r s v f ; do
source=$s ; version=$v ; filename=$f
[[ $ALL && $version ]] && echo "$base $version $source"
done < $CACHEDIR/$h.list
if [[ -z $version ]]; then
echo "[ERROR] can't find version for $base" >&2
return 1
fi
[[ $VERBOSE ]] && echo "> $base $version $source" >&2
if [[ $current != $version ]]; then
ordered=( $(echo -e "$current\n$version\n" | sort -V) )
[[ $VERBOSE ]] &&
echo "[DEBUG] $current ? ${ordered[0]} < ${ordered[1]}" >&2
if [[ ${ordered[1]} != $current ]]; then
echo "** $base ($current) need update to $version **"
return 1
fi
fi
}
while [[ $# -gt 0 ]] ; do
case "$1" in
-f|--filename) FILENAME=$2 ; shift ;;
-v|--verbose) VERBOSE=1 ;;
-a|--all) ALL=1 ;;
-F|--force) FORCE=1 ;;
-*) echo "unknown parameter $1" >&2 ; exit 1 ;;
*) break ;;
esac
shift
done
[[ -d $CACHEDIR ]] || mkdir -p $CACHEDIR
[[ -z $1 && -e $PROGNAME.def ]] && FILENAME=$PROGNAME.def
if [[ $FILENAME ]] ; then
status=0
while read -r base current method url pattern rewrite ; do
[[ -z ${url%%# *} ]] && continue
[[ $1 && $base != $1 ]] && continue
check-updates "$base" "$current" "$method" "$url" "$pattern" "$rewrite" || status=1
done < $FILENAME
exit $status
elif [[ $1 ]] ; then
check-updates "$@"
fi