]> git.pld-linux.org Git - packages/apertium.git/blob - apertium-get
- release 2 (by relup.sh)
[packages/apertium.git] / apertium-get
1 #!/bin/bash
2
3 [[ "${BASH_SOURCE[0]}" != "${0}" ]] || set -e -u
4
5 ### Globals:
6
7 declare -r gitroot=https://raw.githubusercontent.com/apertium
8 declare -ar pmodules=(trunk staging nursery incubator)
9 declare -ar lmodules=(languages incubator)
10
11 declare -r svnroot_giella=https://victorio.uit.no/langtech/trunk
12
13
14 ### Functions:
15 discover_url_apertium () {
16     local -r dir=$1
17     local url=
18     local -a modules
19     if [[ ${dir} = *-*-* ]]; then
20         modules=( "${pmodules[@]}" )
21     else
22         modules=( "${lmodules[@]}" )
23     fi
24     for module in "${modules[@]}"; do
25         submodules=$(curl -Ss --fail "${gitroot}/apertium-${module}/master/.gitmodules")
26         # url="${svnroot}${module}/${dir}"
27         if url=$(grep "[[:space:]]*url = .*/${dir}.git$" <<<"${submodules}"); then
28             url=${url#*url = }
29             # TODO: Option to use ssh urls?
30             url=${url/git@github.com:/https:\/\/github.com\/}
31             echo "Assuming git url of ${dir} is ${url}" >&2
32             echo "${url}"
33             return 0
34         fi
35     done
36     echo "WARNING: Couldn't find git url of ${dir}" >&2
37     if ! msg=$(curl -Ss --fail "${gitroot}/apertium-languages/master/.gitmodules"); then
38         printf "\n%s\n\n" "${msg}" >&2
39         echo "You may want to see http://wiki.apertium.org/wiki/Using_SVN#Host_not_found_when_using_proxy" >&2
40         echo "or make sure you have a working internet connection." >&2
41     fi
42     return 1
43 }
44 discover_url_giella () {
45     local -r dir=$1
46     local -r url="${svnroot_giella}/${dir}"
47     echo "Assuming SVN url of ${dir} is ${url}" >&2
48     echo "${url}"
49 }
50
51 dir_of_dep () {
52     if [[ $1 = giella-* ]]; then
53         echo "langs/${1##giella-}"
54     else
55         echo "$1"
56     fi
57 }
58 bins_of_dep () {
59     if [[ $1 = giella-* ]]; then
60         echo "langs/${1##giella-}/tools/mt/apertium"
61     else
62         echo "$1"
63     fi
64 }
65
66 make_dep () {
67     local -r dep=$1
68     local -r dir=$(dir_of_dep "${dep}")
69     # Let cwd be GTHOME from here on in; langs should exist under this dir:
70     GTHOME=$(pwd)
71     GTCORE=$GTHOME/gtcore
72     export GTHOME
73     export GTCORE
74     (
75         cd "${dir}"
76         pwd
77         ./autogen.sh
78         if [[ ${dep} = giella-* ]]; then
79             ./configure --enable-apertium --with-hfst --enable-syntax
80             V=1 make                    # giella so memory hungry, -j1
81         elif [[ ${dep} = gtcore ]]; then
82             ./configure
83             make -j3
84         else
85             make -j3
86         fi
87     )
88 }
89
90 is_dep_updated () {
91     local -r dep=$1
92     local -r dir=$(dir_of_dep "${dep}")
93     if [[ -d ${dir} ]]; then
94         if [[ -d "${dir}/.git" ]]; then
95             if [[ -z "$(cd "${dir}" && git fetch --dry-run)" ]]; then
96                 echo yes
97                 return 0
98             else
99                 echo no
100                 return 0
101             fi
102         fi
103         if [[ -z $(svn status -qu "${dir}") ]]; then
104             echo yes
105             return 0
106         fi
107     fi
108     echo no
109 }
110
111 get_dep () {
112     local -r depth=$1
113     local -r dep=$2
114     local -r dir=$(dir_of_dep "${dep}")
115     local url=
116     if [[ -d ${dir} ]]; then
117         (
118             cd "${dir}"
119             printf "Updating existing %s (%s)\n" "${dir}" "$(pwd)"
120             if [[ -d .git ]]; then
121                 git pull
122             else
123                 svn up
124             fi
125         )
126     else
127         if [[ ${dep} = giella-* || ${dep} = gtcore ]]; then
128             url=$(discover_url_giella "${dir}") && svn checkout "${url}" "${dir}"
129         else
130             url=$(discover_url_apertium "${dir}") && if [[ $depth -gt 0 ]]; then
131                 git clone --depth "${depth}" "${url}" "${dir}"
132             else
133                 git clone "${url}" "${dir}"
134             fi
135         fi
136     fi
137 }
138
139 in_array () {
140     local e
141     for e in "${@:2}"; do
142         [[ "$e" == "$1" ]] && return 0
143     done
144     return 1
145 }
146
147 get_pair () {
148     local -r depth=$1
149     local -r keep_going=$2
150     local -r skip_if_up_to_date=$3
151     local -r pair=apertium-${4##apertium-}
152     # shellcheck disable=SC2124
153     local -r skip="${@:5}" # intentionally assigning array to string
154
155     if [[ ${skip_if_up_to_date} == true && $(is_dep_updated "${pair}") == "yes" ]]; then
156         printf "Existing pair %s is already up to date. Skipping build step.\\n" "${pair}"
157         return 0
158     fi
159
160     get_dep "${depth}" "${pair}"
161     # Mac has ancient bash, so no declare -A for us
162     local -a deps=()
163     local -a depn=()
164     while read -r n dep; do
165         local orglang
166         orglang=$(split_org_langs "${dep}")
167         local lang=${orglang##* }
168         # shellcheck disable=SC2068
169         if in_array "${lang}" ${skip[@]}; then # intentionally unquoted skip
170             echo
171             echo "Skipping data ${dep} as instructed."
172             echo
173         else
174             deps+=( "${dep}" )
175             depn+=( "${n}" )
176         fi
177     done < <(awk -F'[][[:space:]]+' '/^ *AP_CHECK_LING\(/ && $2 && $4 {print $2, $4}' "${pair}"/configure.ac)
178
179     if [[ ${#deps[@]} -ne 0 ]]; then
180         for dep in "${deps[@]}"; do
181             if ! get_data "${depth}" "${skip_if_up_to_date}" "${keep_going}" "${dep}"; then
182                 echo
183                 echo "WARNING: Couldn't get dependency ${dep}; pair ${pair} might not get set up correctly."
184                 echo
185                 if ${keep_going}; then
186                     echo "WARNING: Continuing on as if nothing happened ..."
187                     echo
188                     sleep 1
189                 else
190                     exit 1
191                 fi
192             fi
193         done
194     fi
195     cd "${pair}"
196     autogen="./autogen.sh "
197     for i in "${!depn[@]}"; do
198         binsdir=$(bins_of_dep "${deps[i]}")
199         autogen="${autogen} --with-lang${depn[i]}=../${binsdir}"
200     done
201     ${autogen}
202     make -j3
203     make test || echo "make test failed, but that's probably fine."
204
205     cat <<EOF
206
207 All done!
208
209 You can now "cd ${pair}" or one of the dependencies, edit some files
210 and type "make -j3 langs" to compile again.
211
212 EOF
213 }
214
215 split_org_langs () {
216     local -r org=$( if [[ $1 = giella-* ]]; then echo giella; else echo apertium; fi )
217     local -r langs=${1#${org}-}
218     echo "${org} ${langs}"
219 }
220
221 maybe_symlink_GTHOME () {
222     if [[ -d $1 ]]; then
223         echo
224         echo "Found $1 here, using that."
225         echo
226     elif [[ -z ${GTHOME+x} ]]; then
227         echo
228         echo "GTHOME is unset; will have to build $1 without it."
229         echo
230     elif [[ -d $GTHOME/$1 ]]; then
231         echo
232         echo "Found $1 in your \$GTHOME, symlinking to that to avoid recompilation."
233         echo
234         test -d langs || mkdir langs
235         ln -sf "$GTHOME/$1" "$1"
236     else
237         echo
238         echo "GTHOME is set but there is no $GTHOME/$1; will have to build $1 from scratch."
239         echo
240     fi
241 }
242
243 get_data () {
244     local -r depth=$1
245     local -r keep_going=$2
246     local -r skip_if_up_to_date=$3
247     local -r orglangs=$(split_org_langs "$4")
248     local -r org=${orglangs%% *}
249     local -r langs=${orglangs##* }
250
251     if [[ ${langs} = *-* ]]; then
252         get_pair "$@"
253     else
254         local -r mdep=${org}-${langs}
255         if [[ $org = giella ]]; then
256             maybe_symlink_GTHOME "langs/${langs}"
257             maybe_symlink_GTHOME gtcore
258             get_dep "${depth}" gtcore
259             make_dep gtcore
260         fi
261
262         if [[ ${skip_if_up_to_date} == true && $(is_dep_updated "${mdep}") == "yes" ]]; then
263             printf "Dependency %s is up-to-date, skipping update and build.\\n" "$3"
264         else
265             if get_dep "${depth}" "${mdep}"; then
266                 make_dep "${mdep}"
267             else
268                 return 1
269             fi
270         fi
271     fi
272 }
273
274 show_help () {
275     cat <<EOF
276 USAGE
277        ${0##*/} PAIR
278        ${0##*/} -l [MODULE...]
279
280 DESCRIPTION
281        Run with just one argument, it will download and set up the
282        Apertium development data for the specified language pair.
283
284        With the -l option, it will list available language pairs. Give
285        one or more MODULE arguments to list only pairs in that SVN
286        module (one of "trunk", "staging", "nursery", "incubator").
287        The same behavior can be invoked for language modules using -m.
288
289 OPTIONS
290        -h          display this help and exit
291        -l          list available packages instead of setting up data
292        -m          list available language modules instead of setting up
293                    data
294        -k          keep going even if a dependency fails
295        -s          skip the build step for up-to-date dependencies/pairs
296        -x DEP      skip data dependency DEP (useful if DEP is installed
297                    through a package manager); may be specified multiple
298                    times
299        -d DEPTH    specify a --depth to 'git clone'
300
301 EXAMPLES
302        ${0##*/} nno-nob
303
304        Download and set up apertium-nno-nob, along with its nno and
305        nob dependencies.
306
307        sudo apt-get install giella-sme
308        ${0##*/} -x sme sme-nob
309
310        Install giella-sme through apt-get, then install download and set
311        up apertium-sme-nob, along with the nob dependency (but not sme).
312
313        ${0##*/} -l trunk
314
315        List available language pairs in SVN trunk.
316
317        ${0##*/} -l | grep kaz
318
319        List available language pairs involving Kazakh.
320 EOF
321 }
322
323 is_in () {
324     local -r pattern="$1"
325     local element
326     shift
327
328     for element; do
329         [[ ${element} = "${pattern}" ]] && return 0
330     done
331     return 1
332 }
333
334
335 list_modules () {
336     curl -Ss --fail "${gitroot}/apertium-${module}/master/.gitmodules" \
337         | grep "[[:space:]]*url = .*.git$"                             \
338         | sed 's%.*url = .*/%%'                                        \
339         | sed 's/[.]git$//'                                            \
340         | sed 's/^apertium-//'
341     echo
342 }
343
344 list_pairs () {
345     local -a modules=("$@")
346     local module
347
348     # Defaulting to all modules:
349     if [[ ${#modules[@]} -eq 0 ]]; then
350         modules=( "${pmodules[@]}" )
351     fi
352     # Sanity-check input:
353     for module in "${modules[@]}"; do
354         if ! is_in "${module}" "${pmodules[@]}"; then
355             echo "ERROR: '${module}' not recognised as a language pair module"'!' >&2
356             echo >&2
357             show_help >&2
358             exit 1
359         fi
360     done
361
362     for module in "${modules[@]}"; do
363         echo "# Pairs in ${module}:"
364         list_modules "${module}" |grep -e '-'
365         echo
366     done
367 }
368
369 list_language_modules() {
370     local -a modules=("$@")
371     local module
372
373     # Defaulting to all modules:
374     if [[ ${#modules[@]} -eq 0 ]]; then
375         modules=( "${lmodules[@]}" )
376     fi
377     # Sanity-check input:
378     for module in "${modules[@]}"; do
379         if ! is_in "${module}" "${lmodules[@]}"; then
380             echo "ERROR: '${module}' not recognised as an language module module"'!' >&2
381             echo >&2
382             show_help >&2
383             exit 1
384         fi
385     done
386
387     for module in "${modules[@]}"; do
388         echo "# Language modules in ${module}:"
389         list_modules "${module}" | grep -ve '-'
390     done
391 }
392
393 sanity_check () {
394     if ! command -V git >/dev/null; then
395         cat >&2 <<EOF
396
397 You need to install git first!
398
399 If you use apt-get, it's typically:
400
401   sudo apt-get install git
402
403 If you use rpm/dnf, it's typically:
404
405   sudo dnf install git
406
407 EOF
408     fi
409 }
410
411 main () {
412     sanity_check
413     local do_list_pairs=false
414     local keep_going=false
415     local do_list_language_modules=false
416     local skip_if_up_to_date=false
417     local -a skip=()
418     local depth=0
419     while getopts ":hklmsx:d:" opt; do
420         case "$opt" in
421             h)
422                 show_help
423                 exit 0
424                 ;;
425             x)
426                 skip+=( "${OPTARG}" )
427                 ;;
428             d)
429                 depth="${OPTARG}"
430                 ;;
431             l)
432                 do_list_pairs=true
433                 ;;
434             m)
435                 do_list_language_modules=true
436                 ;;
437             k)
438                 keep_going=true
439                 ;;
440             s)
441                 skip_if_up_to_date=true
442                 ;;
443             \?)
444                 echo "ERROR: Invalid option: -$OPTARG" >&2
445                 echo >&2
446                 show_help >&2
447                 exit 1
448                 ;;
449         esac
450     done
451     shift "$((OPTIND-1))"
452
453     if ${do_list_pairs}; then
454         list_pairs "$@"
455     elif ${do_list_language_modules}; then
456         list_language_modules "$@"
457     else
458         if [[ $# -lt 1 ]]; then
459             echo "ERROR: No language pair specified." >&2
460             echo >&2
461             show_help >&2
462             exit 1
463         fi
464         for d in "$@"; do
465             get_data "${depth}" "${keep_going}" "${skip_if_up_to_date}" "$d" "${skip[@]:-}"
466         done
467     fi
468 }
469
470 if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then
471     echo "${BASH_SOURCE[0]} is being sourced; chmod +x and use ./${BASH_SOURCE[0]} to actually run." >&2
472 else
473     main "$@"
474 fi
This page took 0.116546 seconds and 3 git commands to generate.