Preparing for release v2.2
[geeqie.git] / meson.build
index 6bdb235..153552f 100644 (file)
@@ -25,8 +25,8 @@
 # bindir        /usr/local/bin                          geeqie executable
 # gq_bindir     /usr/local/lib/geeqie               *   plugins scripts
 # datadir       /usr/local/share/
-#               /usr/local/share/applications           geeqie.desktop
-# [gq_]appdir   /usr/local/share/geeqie/            *   template.desktop
+#               /usr/local/share/applications           org.geeqie.Geeqie.desktop
+# [gq_]appdir   /usr/local/share/geeqie/            *   org,geeqie.template.desktop
 # desktopdir    /usr/local/share/geeqie/applications    plugin desktop files
 # appdatadir    /usr/local/share/metainfo               org.geeqie.Geeqie.appdata.xml
 # icondir       /usr/local/share/pixmaps                geeqie.png icon
@@ -44,25 +44,21 @@ project(
     'cpp',
     version : run_command('./version.sh', check : true).stdout().strip(),
     license : ['GPL-2.0-or-later'],
-    meson_version : '>=0.56.2',
+    meson_version : '>=1.0.0',
     default_options : ['cpp_std=c++14', 'warning_level=3', 'buildtype=debugoptimized', 'cpp_link_args=-rdynamic']
 )
 
-# To inhibit warnings from the generated files icons_inline.h and ui_icons.h
+# To inhibit warnings from the generated file icons.h
 add_global_arguments('-Wno-overlength-strings', language : 'c')
 
 # To compile originally-C files as C++
 add_global_arguments('-Wno-error=deprecated-declarations', language : 'cpp')
-add_global_arguments('-Wno-error=sign-compare', language : 'cpp')
-add_global_arguments('-Wno-error=return-type', language : 'cpp')
-add_global_arguments('-Wno-error=literal-suffix', language : 'cpp')
-add_global_arguments('-Wno-error=write-strings', language : 'cpp')
 
 # Project requirements
 project_sources = []
 gnome = import('gnome')
 thread_dep = dependency('threads')
-cc = meson.get_compiler('c')
+cc = meson.get_compiler('cpp')
 i18n = import('i18n')
 fs = import('fs')
 configuration_inc = include_directories('.')
@@ -76,7 +72,6 @@ if option.enabled()
 endif
 
 # External programs
-gdk_pixbuf_csource = find_program('gdk-pixbuf-csource', required : true)
 glib_compile_resources = find_program('glib-compile-resources', required : true)
 glib_genmarshal = find_program('glib-genmarshal', required : true)
 
@@ -416,12 +411,7 @@ lua_dep = []
 req_version = '>=5.3'
 option = get_option('lua')
 if not option.disabled()
-    foreach name : ['lua', 'lua5.3', 'lua-5.3', 'lua53']
-        lua_dep = dependency(name, version: req_version, required: get_option('lua'))
-        if lua_dep.found()
-            break
-        endif
-    endforeach
+    lua_dep = dependency('lua', 'lua5.3', 'lua-5.3', 'lua53', version: req_version, required: get_option('lua'))
     if lua_dep.found()
         conf_data.set('HAVE_LUA', 1)
         summary({'lua' : ['lua supported:', true]}, section : 'Configuration', bool_yn : true)
@@ -538,19 +528,19 @@ else
     summary({'videothumbnailer' : ['disabled -thumbnails of video files supported', false]}, section : 'Configuration', bool_yn : true)
 endif
 
-# libpixbufloader-webp is not loaded as part of libgdk-pixbuf. Just issue
-# a warning if not installed
-libwebp_dir = dependency('gdk-pixbuf-2.0', method: 'pkg-config').get_variable(pkgconfig: 'gdk_pixbuf_moduledir', internal: 'gdk_pixbuf_moduledir')
-
-if libwebp_dir.contains('loaders')
-    libwebp_dep = cc.find_library('pixbufloader-webp', dirs : libwebp_dir, required : false)
+libwebp_dep = []
+req_version = '>=0.6.1'
+option = get_option('webp')
+if not option.disabled()
+    libwebp_dep = dependency('libwebp', version : req_version, required : get_option('webp'))
     if libwebp_dep.found()
+        conf_data.set('HAVE_WEBP', 1)
         summary({'webp' : ['webp files supported:', true]}, section : 'Configuration', bool_yn : true)
     else
-        summary({'webp' : ['webp-pixbuf-loader not installed - webp files supported:', false]}, section : 'Configuration', bool_yn : true)
+        summary({'webp' : ['libwebp ' + req_version + ' not found - webp files supported:', false]}, section : 'Configuration', bool_yn : true)
     endif
 else
-    summary({'webp' : ['webp-pixbuf-loader not installed - webp files supported:', false]}, section : 'Configuration', bool_yn : true)
+    summary({'webp' : ['disabled - webp files supported:', false]}, section : 'Configuration', bool_yn : true)
 endif
 
 # Check for nl_langinfo and _NL_TIME_FIRST_WEEKDAY
@@ -591,6 +581,9 @@ configure_file(input : 'config.h.in',
 script_sources = []
 subdir('scripts')
 
+# For markdownlint on .md files
+mdl_sources = []
+
 # For gtk builder checks on .ui files
 ui_sources = []
 
@@ -625,8 +618,8 @@ install_data('geeqie.png', install_dir : icondir)
 install_data('geeqie.1', install_dir : mandir1)
 
 i18n.merge_file(
-    input : 'geeqie.desktop.in',
-    output : 'geeqie.desktop',
+    input : 'org.geeqie.Geeqie.desktop.in',
+    output : 'org.geeqie.Geeqie.desktop',
     type : 'desktop',
     po_dir : podir,
     install : true,
@@ -643,40 +636,163 @@ i18n.merge_file(
 configure_file(input: 'geeqie.spec.in', output: 'geeqie.spec', configuration: conf_data)
 
 # Basic test of the executable
+# is_parallel false is to avoid problems with images tests
 xvfb = find_program('xvfb-run', required : false)
 if xvfb.found()
-    test('Basic test', xvfb, args: ['--auto-servernum', geeqie_exe, '--version'], timeout: 100)
+    test('Basic test', xvfb, args: ['--auto-servernum', geeqie_exe, '--version'], is_parallel : false, timeout: 100)
     summary({'xvfb' : ['Test runs:', true]}, section : 'Testing', bool_yn : true)
 else
     summary({'xvfb' : ['Test runs:', false]}, section : 'Testing', bool_yn : true)
 endif
 
-# Shellcheck
-shellcheck_exe = find_program('shellcheck', required : false)
-script_sources += files('gen_changelog.sh',
-'geeqie-install-debian.sh',
-'version.sh')
+# The tests are run on GitHub with all options disabled, and then
+# with all or most options enabled. Shellcheck and GtkBuilder need only
+# be run once when options are disabled. Use option archive as a flag.
+# Image tests use option devel as a flag so that normal users do not
+# download the test image database.
 
-if shellcheck_exe.found()
-    foreach script : script_sources
-        test('Shellcheck', shellcheck_exe, args: ['--norc', '--shell=sh', '--enable=add-default-case,avoid-nullary-conditions,check-unassigned-uppercase,deprecate-which,quote-safe-variables', script], timeout: 100)
-    endforeach
-    summary({'shellcheck' : ['Test runs:', true]}, section : 'Testing', bool_yn : true)
+# Shellcheck
+option = get_option('archive')
+if option.disabled()
+    shellcheck_exe = find_program('shellcheck', required : false)
+    script_sources += files('gen_changelog.sh',
+    'geeqie-install-debian.sh',
+    'version.sh')
+
+    if shellcheck_exe.found()
+        foreach script : script_sources
+            script_path = '@0@'.format(script)
+            test('Shellcheck_ ' + script_path, shellcheck_exe, args: ['--norc', '--shell=sh', '--enable=add-default-case,avoid-nullary-conditions,check-unassigned-uppercase,deprecate-which,quote-safe-variables', script], timeout: 100)
+        endforeach
+        summary({'shellcheck' : ['Test runs:', true]}, section : 'Testing', bool_yn : true)
+    else
+        summary({'shellcheck' : ['Test runs:', false]}, section : 'Testing', bool_yn : true)
+    endif
 else
     summary({'shellcheck' : ['Test runs:', false]}, section : 'Testing', bool_yn : true)
 endif
 
-# GtkBuilder .ui check
-if xvfb.found()
-    gtk_builder_tool = find_program('gtk-builder-tool', required : false)
-    if gtk_builder_tool.found()
-        foreach ui_file : ui_sources
-            test('UI Build', xvfb, args: ['--auto-servernum', gtk_builder_tool.full_path(), 'validate', ui_file], timeout: 100)
+# Markdownlint
+option = get_option('archive')
+if option.disabled()
+    mdl_exe = find_program('mdl', required : false)
+
+    if mdl_exe.found()
+        mdl_sources += files('CHECKLIST.md',
+        'CODING.md',
+        'DEVELOPER-NOTES.md',
+        'README.md',
+        join_paths(meson.project_source_root(), '.github', 'ISSUE_TEMPLATE.md'))
+
+        style = join_paths(meson.project_source_root(), '.mdl.rb')
+        foreach md_file : mdl_sources
+            md_path = '@0@'.format(md_file)
+            test('Mdl_check_ ' + md_path, mdl_exe, args: ['--style', style, md_file], timeout: 100)
         endforeach
-        summary({'gtk-builder-tool' : ['Test runs:', true]}, section : 'Testing', bool_yn : true)
+        summary({'markdownlint' : ['Test runs:', true]}, section : 'Testing', bool_yn : true)
+    else
+        summary({'markdownlint' : ['Test runs:', false]}, section : 'Testing', bool_yn : true)
+    endif
+else
+    summary({'markdownlint' : ['Test runs:', false]}, section : 'Testing', bool_yn : true)
+endif
+
+# GtkBuilder .ui check
+option = get_option('archive')
+if option.disabled()
+    if xvfb.found()
+        gtk_builder_tool = find_program('gtk-builder-tool', required : false)
+        if gtk_builder_tool.found()
+            foreach ui_file : ui_sources
+                ui_path = '@0@'.format(ui_file)
+                test('UI Build_ ' + ui_path, xvfb, args: ['--auto-servernum', gtk_builder_tool.full_path(), 'validate', ui_file], timeout: 100)
+            endforeach
+            summary({'gtk-builder-tool' : ['Test runs:', true]}, section : 'Testing', bool_yn : true)
+        else
+            summary({'gtk-builder-tool' : ['Test runs:', false]}, section : 'Testing', bool_yn : true)
+        endif
     else
-        summary({'gtk-builder-tool' : ['Test runs:', false]}, section : 'Testing', bool_yn : true)
+        summary({'gtk-builder-tool xvfb' : ['Test runs:', false]}, section : 'Testing', bool_yn : true)
     endif
 else
     summary({'gtk-builder-tool xvfb' : ['Test runs:', false]}, section : 'Testing', bool_yn : true)
 endif
+
+# Image checks
+option = get_option('devel')
+if option.enabled()
+    if xvfb.found()
+        get_test_images_sh = find_program('get-test-images.sh', dirs : scriptsdir, required : true)
+        image_test_sh = find_program('image-test.sh', dirs : scriptsdir, required : true)
+
+        images_dir = join_paths(meson.current_build_dir(), 'test-images.p')
+
+        message('Downloading test images')
+        sources_list = run_command(get_test_images_sh, images_dir,  'https://github.com/caclark/geeqie-test.git', check: true)
+
+        sources = sources_list.stdout().strip().split('\n')
+
+        foreach image : sources
+            image_path = '@0@'.format(image)
+            path_array = image_path.split('/')
+            image_name = path_array[path_array.length() - 1]
+
+            if image_name.startswith('fail')
+                test('Image_ ' + image_name, image_test_sh, args: [geeqie_exe, image], is_parallel : false, should_fail : true, timeout: 100)
+            else
+                test('Image_ ' + image_name, image_test_sh, args: [geeqie_exe, image], is_parallel : false, timeout: 100)
+            endif
+        endforeach
+        summary({'Image tests' : ['Test runs:', true]}, section : 'Testing', bool_yn : true)
+    else
+        summary({'Image tests' : ['Test runs:', false]}, section : 'Testing', bool_yn : true)
+    endif
+else
+    summary({'Image tests' : ['Test runs:', false]}, section : 'Testing', bool_yn : true)
+endif
+
+# Code correctness checks
+if running_from_git
+    clang_tidy_exe = find_program('clang-tidy', required : false)
+    if clang_tidy_exe.found()
+        git_exe = find_program('git', required : true)
+        modified_file_list = run_command(git_exe, 'diff', '--name-only', check: true)
+        modified_files = modified_file_list.stdout().strip().split('\n')
+
+        foreach modified_file : modified_files
+            if modified_file.endswith('.cc')
+                modified_file_path = '@0@'.format(modified_file)
+                path_array = modified_file_path.split('/')
+                modified_file_name = path_array[path_array.length() - 1]
+                modified_file_full_path = join_paths(meson.project_source_root(), modified_file)
+
+                test('Code Correctness_ ' + modified_file_name, clang_tidy_exe, args : ['-p', './build', '-quiet', modified_file_full_path], timeout : 100)
+            endif
+        endforeach
+
+        summary({'Code Correctness' : ['Test runs:', true]}, section : 'Testing', bool_yn : true)
+    else
+        summary({'Code Correctness' : ['Test runs:', false]}, section : 'Testing', bool_yn : true)
+    endif
+else
+    summary({'Code Correctness' : ['Test runs:', false]}, section : 'Testing', bool_yn : true)
+endif
+
+# Lua test
+option = get_option('lua')
+if not option.disabled()
+    if lua_dep.found()
+        if xvfb.found()
+            lua_test_sh = find_program('lua-test.sh', dirs : scriptsdir, required : true)
+            test('Lua test', lua_test_sh, args: [geeqie_exe], is_parallel : false, timeout: 100)
+
+            summary({'lua' : ['Test runs:', true]}, section : 'Testing', bool_yn : true)
+        else
+            summary({'lua' : ['Test runs:', false]}, section : 'Testing', bool_yn : true)
+        endif
+    else
+        summary({'lua' : ['Test runs:', false]}, section : 'Testing', bool_yn : true)
+    endif
+else
+    summary({'lua' : ['Test runs:', false]}, section : 'Testing', bool_yn : true)
+endif