Set mimimum requirement for lua to 5.3
[geeqie.git] / geeqie-install-debian.sh
1 #!/bin/sh
2
3 ## @file
4 ## @brief Download, compile, and install Geeqie on Debian-based systems.
5 ##
6 ## If run from a folder that already contains the Geeqie sources, the source
7 ## code will be updated from the repository.
8 ## Dialogs allow the user to install additional features.
9 ##
10
11 version="2022-07-30"
12 description='
13 Geeqie is an image viewer.
14 This script will download, compile, and install Geeqie on Debian-based systems.
15 If run from a folder that already contains the Geeqie sources, the source
16 code will be updated from the repository.
17 Dialogs allow the user to install additional features.
18
19 Command line options are:
20 -v --version The version of this file
21 -h --help Output this text
22 -c --commit=ID Checkout and compile commit ID
23 -t --tag=TAG Checkout and compile TAG (e.g. v1.4 or v1.3)
24 -b --back=N Checkout commit -N (e.g. "-b 1" for last-but-one commit)
25 -l --list List required dependencies
26 '
27
28 # Essential for compiling
29 essential_array="git
30 build-essential
31 libglib2.0-0
32 intltool
33 libtool
34 meson
35 yelp-tools
36 help2man
37 doclifter"
38
39 # Optional for GTK3
40 optional_array="LCMS (for color management)
41 liblcms2-dev
42 exiv2 (for exif handling)
43 libgexiv2-dev
44 evince (for print preview)
45 evince
46 lua (for --remote commands)
47 liblua5.3-dev
48 libffmpegthumbnailer (for mpeg thumbnails)
49 libffmpegthumbnailer-dev
50 libtiff (for tiff support)
51 libtiff-dev
52 libjpeg (for jpeg support)
53 libjpeg-dev
54 librsvg2 (for viewing .svg images)
55 librsvg2-common
56 libwmf (for viewing .wmf images)
57 libwmf0.2-7-gtk
58 exiftran (for image rotation)
59 exiftran
60 imagemagick (for image rotation)
61 imagemagick
62 exiv2 command line (for jpeg export)
63 exiv2
64 jpgicc (for jpeg export color correction)
65 liblcms2-utils
66 pandoc (for generating README help file)
67 pandoc
68 gphoto2 (for tethered photography and camera download plugins)
69 gphoto2
70 libimage-exiftool-perl (for jpeg extraction plugin)
71 libimage-exiftool-perl
72 libheif (for HEIF support)
73 libheif-dev
74 libwebp (for WebP images)
75 libwebp-dev
76 libdjvulibre (for DjVu images)
77 libdjvulibre-dev
78 libopenjp2 (for JP2 images)
79 libopenjp2-7-dev
80 libraw (for CR3 images)
81 libraw-dev
82 libomp (required by libraw)
83 libomp-dev
84 libarchive (for compressed files e.g. zip, including timezone)
85 libarchive-dev
86 libgspell (for spelling checks)
87 libgspell-1-dev
88 libchamplain gtk (for GPS maps)
89 libchamplain-gtk-0.12-dev
90 libchamplain (for GPS maps)
91 libchamplain-0.12-dev
92 libpoppler (for pdf file preview)
93 libpoppler-glib-dev"
94
95 ####################################################################
96 # Get System Info
97 # Derived from: https://github.com/coto/server-easy-install (GPL)
98 ####################################################################
99 lowercase()
100 {
101         printf '%b\n' "$1" | sed "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/"
102 }
103
104 systemProfile()
105 {
106         OS="$(lowercase "$(uname)")"
107         KERNEL=$(uname -r)
108         MACH=$(uname -m)
109
110         if [ "${OS}" = "windowsnt" ]
111         then
112                 OS=windows
113         elif [ "${OS}" = "darwin" ]
114         then
115                 OS=mac
116         else
117                 OS=$(uname)
118                 if [ "${OS}" = "SunOS" ]
119                 then
120                         OS=Solaris
121                         ARCH=$(uname -p)
122                         OSSTR="${OS} ${REV}(${ARCH} $(uname -v))"
123                 elif [ "${OS}" = "AIX" ]
124                 then
125                         # shellcheck disable=SC2034
126                         OSSTR="${OS} $(oslevel) ($(oslevel -r))"
127                 elif [ "${OS}" = "Linux" ]
128                 then
129                         if [ -f /etc/redhat-release ]
130                         then
131                                 DistroBasedOn='RedHat'
132                                 DIST=$(sed s/\ release.*// /etc/redhat-release)
133                                 PSUEDONAME=$(sed s/.*\(// /etc/redhat-release | sed s/\)//)
134                                 REV=$(sed s/.*release\ // /etc/redhat-release | sed s/\ .*//)
135                         elif [ -f /etc/SuSE-release ]
136                         then
137                                 DistroBasedOn='SuSe'
138                                 PSUEDONAME=$(tr "\n" ' ' < /etc/SuSE-release | sed s/VERSION.*//)
139                                 REV=$(tr "\n" ' ' < /etc/SuSE-release | sed s/.*=\ //)
140                         elif [ -f /etc/mandrake-release ]
141                         then
142                                 DistroBasedOn='Mandrake'
143                                 PSUEDONAME=$(sed s/.*\(// /etc/mandrake-release | sed s/\)//)
144                                 REV=$(cat | sed s/.*release\ // /etc/mandrake-release | sed s/\ .*//)
145                         elif [ -f /etc/debian_version ]
146                         then
147                                 DistroBasedOn='Debian'
148                                 if [ -f /etc/lsb-release ]
149                                 then
150                                         DIST=$(grep '^DISTRIB_ID' /etc/lsb-release | awk -F= '{ print $2 }')
151                                         PSUEDONAME=$(grep '^DISTRIB_CODENAME' /etc/lsb-release | awk -F= '{ print $2 }')
152                                         REV=$(grep '^DISTRIB_RELEASE' /etc/lsb-release | awk -F= '{ print $2 }')
153                                 fi
154                         fi
155                         if [ -f /etc/UnitedLinux-release ]
156                         then
157                                 DIST="${DIST}[$(tr "\n" ' ' < /etc/UnitedLinux-release | sed s/VERSION.*//)]"
158                         fi
159                         OS=$(lowercase $OS)
160                         DistroBasedOn=$(lowercase $DistroBasedOn)
161                         readonly OS
162                         readonly DIST
163                         readonly DistroBasedOn
164                         readonly PSUEDONAME
165                         readonly REV
166                         readonly KERNEL
167                         readonly MACH
168                 fi
169         fi
170 }
171
172 install_essential()
173 {
174         i=0
175
176         for file in $essential_array
177         do
178                 if [ $((i % 2)) -ne 0 ]
179                 then
180                         if package_query "$file"
181                         then
182                                 package_install "$file"
183                         fi
184                 fi
185
186                 i=$((i + 1))
187         done
188
189         if [ "$1" = "GTK3" ]
190         then
191                 if package_query "libgtk-3-dev"
192                 then
193                         package_install libgtk-3-dev
194                 fi
195         else
196                 if package_query "libgtk2.0-dev"
197                 then
198                         package_install libgtk2.0-dev
199                 fi
200         fi
201 }
202
203 install_options()
204 {
205         if [ -n "$options" ]
206         then
207                 OLDIFS=$IFS
208                 IFS='|'
209                 # shellcheck disable=SC2086
210                 set $options
211                 while [ $# -gt 0 ]
212                 do
213                         package_install "$1"
214                         shift
215                 done
216                 IFS=$OLDIFS
217         fi
218 }
219
220 uninstall()
221 {
222         current_dir="$(basename "$PWD")"
223         if [ "$current_dir" = "geeqie" ]
224         then
225
226                 sudo --askpass  ninja -C build uninstall
227
228                 if ! zenity --title="Uninstall Geeqie" --width=370 --text="WARNING.\nThis will delete folder:\n\n$PWD\n\nand all sub-folders!" --question --ok-label="Cancel" --cancel-label="OK" 2> /dev/null
229                 then
230                         cd ..
231                         sudo --askpass rm -rf geeqie
232                 fi
233         else
234                 zenity --title="Uninstall Geeqie" --width=370 --text="This is not a geeqie installation folder!\n\n$PWD" --warning 2> /dev/null
235         fi
236
237         exit_install
238 }
239
240 package_query()
241 {
242         if [ "$DistroBasedOn" = "debian" ]
243         then
244
245                 # shellcheck disable=SC2086
246                 res=$(dpkg-query --show --showformat='${Status}' "$1" 2>> $install_log)
247                 if [ "${res}" = "install ok installed" ]
248                 then
249                         status=1
250                 else
251                         status=0
252                 fi
253         fi
254         return $status
255 }
256
257 package_install()
258 {
259         if [ "$DistroBasedOn" = "debian" ]
260         then
261                 # shellcheck disable=SC2024
262                 sudo --askpass apt-get --assume-yes install "$@" >> "$install_log" 2>&1
263         fi
264 }
265
266 exit_install()
267 {
268         rm "$install_pass_script" > /dev/null 2>&1
269
270         if [ -p "$zen_pipe" ]
271         then
272                 printf '%b\n' "100" > "$zen_pipe"
273                 printf '%b\n' "#End" > "$zen_pipe"
274         fi
275
276         zenity --title="$title" --width=370 --text="Geeqie is not installed\nLog file: $install_log" --info 2> /dev/null
277
278         rm "$zen_pipe" > /dev/null 2>&1
279
280         exit 1
281 }
282
283 # Entry point
284
285 IFS='
286 '
287
288 # If uninstall has been run, maybe the current directory no longer exists
289 if [ ! -d "$PWD" ]
290 then
291         zenity --error --title="Install Geeqie and dependencies" --width=370 --text="Folder $PWD does not exist!" 2> /dev/null
292
293         exit
294 fi
295
296 # Check system type
297 systemProfile
298 if [ "$DistroBasedOn" != "debian" ]
299 then
300         zenity --error --title="Install Geeqie and dependencies" --width=370 --text="Unknown operating system:\n
301 Operating System: $OS
302 Distribution: $DIST
303 Psuedoname: $PSUEDONAME
304 Revision: $REV
305 DistroBasedOn: $DistroBasedOn
306 Kernel: $KERNEL
307 Machine: $MACH" 2> /dev/null
308
309         exit
310 fi
311
312 # Parse the command line
313 OPTS=$(getopt -o vhc:t:b:ld: --long version,help,commit:,tag:,back:,list,debug: -- "$@")
314 eval set -- "$OPTS"
315
316 while true
317 do
318         case "$1" in
319                 -v | --version)
320                         printf '%b\n' "$version"
321                         exit
322                         ;;
323                 -h | --help)
324                         printf '%b\n' "$description"
325                         exit
326                         ;;
327                 -c | --commit)
328                         COMMIT="$2"
329                         shift
330                         shift
331                         ;;
332                 -t | --tag)
333                         TAG="$2"
334                         shift
335                         shift
336                         ;;
337                 -b | --back)
338                         BACK="$2"
339                         shift
340                         shift
341                         ;;
342                 -l | --list)
343                         LIST="$2"
344                         shift
345                         shift
346                         ;;
347                 *)
348                         break
349                         ;;
350         esac
351 done
352
353 if [ "$LIST" ]
354 then
355         printf '%b\n' "Essential libraries:"
356         for file in $essential_array
357         do
358                 printf '%b\n' "$file"
359         done
360
361         printf '\n'
362         printf '%b\n' "Optional libraries:"
363         for file in $optional_array
364         do
365                 printf '%b\n' "$file"
366         done
367
368         exit
369 fi
370
371 # If a Geeqie folder already exists here, warn the user
372 if [ -d "geeqie" ]
373 then
374         zenity --info --title="Install Geeqie and dependencies" --width=370 --text="This script is for use on Ubuntu and other\nDebian-based installations.\nIt will download, compile, and install Geeqie source\ncode and its dependencies.\n\nA sub-folder named \"geeqie\" will be created in the\nfolder this script is run from, and the source code\nwill be downloaded to that sub-folder.\n\nA sub-folder of that name already exists.\nPlease try another folder." 2> /dev/null
375
376         exit
377 fi
378
379 # If it looks like a Geeqie download folder, assume an update
380 if [ -d ".git" ] && [ -d "src" ] && [ -f "geeqie.1" ]
381 then
382         mode="update"
383 else
384         # If it looks like something else is already installed here, warn the user
385         if [ -d ".git" ] || [ -d "src" ]
386         then
387                 zenity --info --title="Install Geeqie and dependencies" --width=370 --text="This script is for use on Ubuntu and other\nDebian-based installations.\nIt will download, compile, and install Geeqie source\ncode and its dependencies.\n\nIt looks like you are running this script from a folder which already has software installed.\n\nPlease try another folder." 2> /dev/null
388
389                 exit
390         else
391                 mode="install"
392         fi
393 fi
394
395 # Use GTK3 as default
396 gtk3_installed=TRUE
397
398 if [ "$mode" = "install" ]
399 then
400         message="This script is for use on Ubuntu and other\nDebian-based installations.\nIt will download, compile, and install Geeqie source\ncode and its dependencies.\n\nA sub-folder named \"geeqie\" will be created in the\nfolder this script is run from, and the source code\nwill be downloaded to that sub-folder.\n\nIn subsequent dialogs you may choose which\noptional features to install."
401
402         title="Install Geeqie and dependencies"
403         install_option=TRUE
404 else
405         message="This script is for use on Ubuntu and other\nDebian-based installations.\nIt will update the Geeqie source code and its\ndependencies, and will compile and install Geeqie.\n\nIn subsequent dialogs you may choose which\noptional features to install."
406
407         title="Update Geeqie and re-install"
408         install_option=FALSE
409 fi
410
411 # Ask whether to install GTK3 or uninstall
412
413 if ! gtk_version=$(zenity --title="$title" --width=370 --text="$message" --list --radiolist --column "" --column "" "$gtk3_installed" "Install" FALSE "Uninstall" --cancel-label="Cancel" --ok-label="OK" --hide-header 2> /dev/null)
414 then
415         exit
416 fi
417
418 # Environment variable SUDO_ASKPASS cannot be "zenity --password",
419 # so create a temporary script containing the command
420 install_pass_script=$(mktemp "${TMPDIR:-/tmp}/geeqie.XXXXXXXXXX")
421 printf '%b\n' "#!/bin/sh
422 if zenity --password --title=\"$title\" --width=370 2>/dev/null
423 then
424         exit 1
425 fi" > "$install_pass_script"
426 chmod +x "$install_pass_script"
427 export SUDO_ASKPASS=$install_pass_script
428
429 if [ "$gtk_version" = "Uninstall" ]
430 then
431         uninstall
432         exit
433 fi
434
435 # Put the install log in tmp, to avoid writing to PWD during a new install
436 rm install.log 2> /dev/null
437 install_log=$(mktemp "${TMPDIR:-/tmp}/geeqie.XXXXXXXXXX")
438
439 sleep 100 | zenity --title="$title" --text="Checking for installed files" --width=370 --progress --pulsate 2> /dev/null &
440 zen_pid=$!
441
442 # Get the standard options that are not yet installed
443 i=0
444 for file in $optional_array
445 do
446         if [ $((i % 2)) -eq 0 ]
447         then
448                 package_title="$file"
449         else
450                 if package_query "$file"
451                 then
452                         if [ -z "$option_string" ]
453                         then
454                                 option_string="${install_option:+${install_option}}\n${package_title}\n${file}"
455                         else
456                                 option_string="${option_string:+${option_string}}\n$install_option\n${package_title}\n${file}"
457                         fi
458                 fi
459         fi
460         i=$((i + 1))
461 done
462
463 kill $zen_pid 2> /dev/null
464
465 # Ask the user which options to install
466 if [ -n "$option_string" ]
467 then
468         if ! options=$(printf '%b\n' "$option_string" | zenity --title="$title" --width=400 --height=500 --list --checklist --text 'Select which library files to install:' --column='Select' --column='Library files' --column='Library' --hide-column=3 --print-column=3 2> /dev/null)
469         then
470                 exit_install
471         fi
472 fi
473
474 # Start of Zenity progress section
475 zen_pipe=$(mktemp -u "${TMPDIR:-/tmp}/geeqie.XXXXXXXXXX")
476 mkfifo "$zen_pipe"
477 (tail -f "$zen_pipe" 2> /dev/null) | zenity --progress --title="$title" --width=370 --text="Installing options..." --auto-close --auto-kill --percentage=0 2> /dev/null &
478
479 printf '%b\n' "2" > "$zen_pipe"
480 printf '%b\n' "#Installing essential libraries..." > "$zen_pipe"
481
482 install_essential "$gtk_version"
483
484 printf '%b\n' "4" > "$zen_pipe"
485 printf '%b\n' "#Installing options..." > "$zen_pipe"
486
487 install_options
488
489 printf '%b\n' "6" > "$zen_pipe"
490 printf '%b\n' "#Installing extra loaders..." > "$zen_pipe"
491
492 printf '%b\n' "10" > "$zen_pipe"
493 printf '%b\n' "#Getting new sources from server..." > "$zen_pipe"
494
495 if [ "$mode" = "install" ]
496 then
497         if ! git clone git://geeqie.org/geeqie.git >> "$install_log" 2>&1
498         then
499                 git_error=$(tail -n5 "$install_log" 2>&1)
500                 zenity --title="$title" --width=370 --height=400 --error --text="Git error:\n\n$git_error" 2> /dev/null
501                 exit_install
502         fi
503 else
504         if ! git checkout master >> "$install_log" 2>&1
505         then
506                 git_error="$(tail -n25 "$install_log" 2>&1)"
507                 zenity --title="$title" --width=370 --height=400 --error --text="Git error:\n\n$git_error" 2> /dev/null
508                 exit_install
509         fi
510         if ! git pull >> "$install_log" 2>&1
511         then
512                 git_error=$(tail -n5 "$install_log" 2>&1)
513                 zenity --title="$title" --width=370 --height=400 --error --text="Git error:\n\n$git_error" 2> /dev/null
514                 exit_install
515         fi
516 fi
517
518 printf '%b\n' "20" > "$zen_pipe"
519 printf '%b\n' "#Cleaning installed version..." > "$zen_pipe"
520
521 if [ $mode = "install" ]
522 then
523         cd geeqie || exit 1
524 else
525         sudo --askpass  ninja -C build uninstall
526 fi
527
528 printf '%b\n' "30" > "$zen_pipe"
529 printf '%b\n' "#Checkout required version..." > "$zen_pipe"
530
531 if [ "$BACK" ]
532 then
533         if ! git checkout master~"$BACK" >> "$install_log" 2>&1
534         then
535                 git_error=$(tail -n5 "$install_log" 2>&1)
536                 zenity --title="$title" --width=370 --height=400 --error --text="Git error:\n\n$git_error" 2> /dev/null
537                 exit_install
538         fi
539 elif [ "$COMMIT" ]
540 then
541
542         if ! git checkout "$COMMIT" >> "$install_log" 2>&1
543         then
544                 git_error=$(tail -n5 "$install_log" 2>&1)
545                 zenity --title="$title" --width=370 --height=400 --error --text="Git error:\n\n$git_error" 2> /dev/null
546                 exit_install
547         fi
548 elif [ "$TAG" ]
549 then
550         if ! git checkout "$TAG" >> "$install_log" 2>&1
551         then
552                 git_error=$(tail -n5 "$install_log" 2>&1)
553                 zenity --title="$title" --width=370 --height=400 --error --text="Git error:\n\n$git_error" 2> /dev/null
554                 exit_install
555                 exit
556         fi
557 fi
558
559 printf '%b\n' "40" > "$zen_pipe"
560 printf '%b\n' "#Creating configuration files..." > "$zen_pipe"
561
562 if [ -z "${gtk_version%%GTK3*}" ]
563 then
564         meson setup build
565         printf '%b\n' "90 " > "$zen_pipe"
566         printf '%b\n' "#Installing Geeqie..." > "$zen_pipe"
567         ninja -C build install
568 else
569         meson setup build
570         meson configure build
571         printf '%b\n' "90 " > "$zen_pipe"
572         printf '%b\n' "#Installing Geeqie..." > "$zen_pipe"
573         ninja -C build install
574 fi
575
576 rm "$install_pass_script"
577 mv -f "$install_log" "./build/install.log"
578
579 printf '%b\n' "100 " > "$zen_pipe"
580 rm "$zen_pipe"
581
582 (for i in $(seq 0 4 100)
583 do
584         printf '%b\n' "$i"
585         sleep 0.1
586 done) | zenity --progress --title="$title" --width=370 --text="Geeqie installation complete...\n" --auto-close --percentage=0 2> /dev/null
587
588 exit