From e31e6952cbd8c9fe390b1ae82c5c5e3e322685be Mon Sep 17 00:00:00 2001 From: Aleksandr Mezin Date: Fri, 1 Dec 2023 19:34:15 +0200 Subject: [PATCH] [WIP] Meson build system https://github.com/ddterm/gnome-shell-extension-ddterm/issues/648 --- .github/problem-matchers/generic.json | 4 +- .github/problem-matchers/gettext-stats.json | 2 +- .github/workflows/build.yml | 35 +++- .github/workflows/check-po.yml | 22 ++- .github/workflows/pot.yml | 17 +- .gitignore | 13 +- ...zin.ddterm => com.github.amezin.ddterm.in} | 2 +- bin/meson.build | 16 ++ bump-version.sh | 9 +- ddterm/app/icons/meson.build | 13 ++ ddterm/app/meson.build | 43 +++++ ddterm/meson.build | 59 ++++++ ddterm/pref/meson.build | 33 ++++ ddterm/pref/test/meson.build | 18 ++ ddterm/pref/ui/gtk3/meson.build | 24 +++ ddterm/pref/{glade => ui/gtk4}/3to4-fixup.xsl | 0 ddterm/pref/ui/gtk4/meson.build | 66 +++++++ ddterm/pref/ui/meson.build | 34 ++++ ddterm/pref/{glade => ui}/prefs-animation.ui | 0 ddterm/pref/{glade => ui}/prefs-behavior.ui | 0 ddterm/pref/{glade => ui}/prefs-colors.ui | 0 ddterm/pref/{glade => ui}/prefs-command.ui | 0 .../pref/{glade => ui}/prefs-compatibility.ui | 0 ddterm/pref/{glade => ui}/prefs-panel-icon.ui | 0 .../pref/{glade => ui}/prefs-position-size.ui | 0 ddterm/pref/{glade => ui}/prefs-scrolling.ui | 0 ddterm/pref/{glade => ui}/prefs-shortcuts.ui | 0 ddterm/pref/{glade => ui}/prefs-tabs.ui | 0 ddterm/pref/{glade => ui}/prefs-text.ui | 0 ddterm/shell/meson.build | 24 +++ ddterm/util/meson.build | 11 ++ lint/meson.build | 43 +++++ lint/node_modules/meson.build | 5 + {po => locale}/LINGUAS | 0 {po => locale}/README.md | 0 {po => locale}/cs.po | 0 {po => locale}/ddterm@amezin.github.com.pot | 0 {po => locale}/de.po | 0 {po => locale}/el.po | 0 {po => locale}/es.po | 0 {po => locale}/fr.po | 0 {po => locale}/id.po | 0 {po => locale}/it.po | 0 locale/meson.build | 121 ++++++++++++ {po => locale}/nb_NO.po | 0 {po => locale}/pl.po | 0 {po => locale}/pt.po | 0 {po => locale}/remove-potcdate.sin | 0 {po => locale}/ru.po | 0 {po => locale}/zh_CN.po | 0 meson.build | 179 ++++++++++++++++++ metadata.json.in | 8 +- po/update-pot.sh | 26 --- schemas/meson.build | 32 ++++ tools/capture_stdout.py | 21 ++ tools/makezip.py | 29 +++ 56 files changed, 834 insertions(+), 75 deletions(-) rename bin/{com.github.amezin.ddterm => com.github.amezin.ddterm.in} (79%) create mode 100644 bin/meson.build create mode 100644 ddterm/app/icons/meson.build create mode 100644 ddterm/app/meson.build create mode 100644 ddterm/meson.build create mode 100644 ddterm/pref/meson.build create mode 100644 ddterm/pref/test/meson.build create mode 100644 ddterm/pref/ui/gtk3/meson.build rename ddterm/pref/{glade => ui/gtk4}/3to4-fixup.xsl (100%) create mode 100644 ddterm/pref/ui/gtk4/meson.build create mode 100644 ddterm/pref/ui/meson.build rename ddterm/pref/{glade => ui}/prefs-animation.ui (100%) rename ddterm/pref/{glade => ui}/prefs-behavior.ui (100%) rename ddterm/pref/{glade => ui}/prefs-colors.ui (100%) rename ddterm/pref/{glade => ui}/prefs-command.ui (100%) rename ddterm/pref/{glade => ui}/prefs-compatibility.ui (100%) rename ddterm/pref/{glade => ui}/prefs-panel-icon.ui (100%) rename ddterm/pref/{glade => ui}/prefs-position-size.ui (100%) rename ddterm/pref/{glade => ui}/prefs-scrolling.ui (100%) rename ddterm/pref/{glade => ui}/prefs-shortcuts.ui (100%) rename ddterm/pref/{glade => ui}/prefs-tabs.ui (100%) rename ddterm/pref/{glade => ui}/prefs-text.ui (100%) create mode 100644 ddterm/shell/meson.build create mode 100644 ddterm/util/meson.build create mode 100644 lint/meson.build create mode 100644 lint/node_modules/meson.build rename {po => locale}/LINGUAS (100%) rename {po => locale}/README.md (100%) rename {po => locale}/cs.po (100%) rename {po => locale}/ddterm@amezin.github.com.pot (100%) rename {po => locale}/de.po (100%) rename {po => locale}/el.po (100%) rename {po => locale}/es.po (100%) rename {po => locale}/fr.po (100%) rename {po => locale}/id.po (100%) rename {po => locale}/it.po (100%) create mode 100644 locale/meson.build rename {po => locale}/nb_NO.po (100%) rename {po => locale}/pl.po (100%) rename {po => locale}/pt.po (100%) rename {po => locale}/remove-potcdate.sin (100%) rename {po => locale}/ru.po (100%) rename {po => locale}/zh_CN.po (100%) create mode 100644 meson.build delete mode 100755 po/update-pot.sh create mode 100644 schemas/meson.build create mode 100644 tools/capture_stdout.py create mode 100644 tools/makezip.py diff --git a/.github/problem-matchers/generic.json b/.github/problem-matchers/generic.json index 83bf46ea4..d26773421 100644 --- a/.github/problem-matchers/generic.json +++ b/.github/problem-matchers/generic.json @@ -4,7 +4,7 @@ "owner": "generic", "pattern": [ { - "regexp": "^([^\\s:]+):(\\d+)(?::(\\d+))?:?\\s+(?:((?i)warning|error):?)?\\s*(.+)$", + "regexp": "^(?:\\.\\./)?([^\\s:]+):(\\d+)(?::(\\d+))?:?\\s+(?:((?i)warning|error):?)?\\s*(.+)$", "file": 1, "line": 2, "column": 3, @@ -17,7 +17,7 @@ "owner": "generic-nolocation", "pattern": [ { - "regexp": "^(?:([^\\s:]+):?\\s+)?((?i)warning|error):?\\s*(.+)$", + "regexp": "^(?:\\.\\./)?(?:([^\\s:]+):?\\s+)?((?i)warning|error):?\\s*(.+)$", "file": 1, "severity": 2, "message": 3 diff --git a/.github/problem-matchers/gettext-stats.json b/.github/problem-matchers/gettext-stats.json index ed6034a50..ec2c73ff7 100644 --- a/.github/problem-matchers/gettext-stats.json +++ b/.github/problem-matchers/gettext-stats.json @@ -5,7 +5,7 @@ "severity": "warning", "pattern": [ { - "regexp": "msgfmt .* --statistics .* (po/.*\\.po)", + "regexp": "(?:^|\\s)(?:\\.\\./)?(locale/.*\\.po)$", "file": 1 }, { diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e380769e3..3216f1b89 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,11 +44,11 @@ jobs: - name: Install JS dependencies id: npm - run: npm ci + run: npm install if: ${{ always() && steps.checkout.conclusion == 'success' }} - name: Lint JS code - run: make "ESLINT_OPTS=--format .github/eslint-formatter.js" lint + run: npm run-script lint -- --format .github/eslint-formatter.js if: ${{ always() && steps.npm.conclusion == 'success' }} - name: Pre-create pip cache directory @@ -75,15 +75,28 @@ jobs: run: echo "::add-matcher::.github/problem-matchers/generic.json" if: ${{ always() && steps.checkout.conclusion == 'success' }} + - id: meson-setup + name: Prepare build directory + run: meson setup build + if: ${{ always() && steps.checkout.conclusion == 'success' }} + - name: Compile GSettings schemas - run: make schemas 2>&1 | tee schemas.log + run: ninja -j1 schemas 2>&1 | tee schemas.log + working-directory: build shell: bash - if: ${{ always() && steps.checkout.conclusion == 'success' }} + if: ${{ always() && steps.meson-setup.conclusion == 'success' }} - name: Validate Gtk .ui files - run: xvfb-run make gtk-builder-validate 2>&1 | tee gtk-builder.log + run: xvfb-run ninja -j1 validate-ui 2>&1 | tee gtk-builder.log + working-directory: build shell: bash - if: ${{ always() && steps.checkout.conclusion == 'success' }} + if: ${{ always() && steps.meson-setup.conclusion == 'success' }} + + - name: Validate .desktop file + run: ninja -j1 desktop-file-validate 2>&1 | tee desktop-file-validate.log + working-directory: build + shell: bash + if: ${{ always() && steps.meson-setup.conclusion == 'success' }} - name: Ensure Python requirements .txt files are in sync with .in files run: | @@ -102,7 +115,7 @@ jobs: if: ${{ always() && steps.checkout.conclusion == 'success' }} - name: Upload reports to Testspace - run: testspace --verbose eslint.xml "*.log{lint}" + run: testspace --verbose eslint.xml "build/*.log{lint}" if: ${{ always() && steps.setup_testspace.outcome == 'success' }} pack: @@ -119,13 +132,17 @@ jobs: - name: Enable generic error matcher run: echo "::add-matcher::.github/problem-matchers/generic.json" + - name: Prepare build directory + run: meson setup build + - name: Build extension package - run: xvfb-run make ONLY_RELEASE_LOCALES=true pack + run: xvfb-run ninja -j1 pack + working-directory: build - name: Upload extension package as artifact id: upload uses: actions/upload-artifact@v4 with: name: pack - path: "*.shell-extension.zip" + path: "build/*.shell-extension.zip" if-no-files-found: error diff --git a/.github/workflows/check-po.yml b/.github/workflows/check-po.yml index 66f656871..379272485 100644 --- a/.github/workflows/check-po.yml +++ b/.github/workflows/check-po.yml @@ -4,7 +4,6 @@ on: env: FORCE_COLOR: 1 - PIP_DISABLE_PIP_VERSION_CHECK: 1 jobs: configure: @@ -23,7 +22,7 @@ jobs: echo -n linguas= >>$GITHUB_OUTPUT grep -Ev '^\s*#.*' LINGUAS | jq -Rcn '[inputs | scan("\\S+")]' >>$GITHUB_OUTPUT shell: bash - working-directory: po + working-directory: locale check: needs: configure @@ -39,27 +38,30 @@ jobs: steps: - name: Checkout - id: checkout uses: actions/checkout@v4 - run: git config --global --replace-all safe.directory "$GITHUB_WORKSPACE" + - name: Enable generic problem matcher + run: echo "::add-matcher::.github/problem-matchers/generic.json" + - name: Enable gettext stats problem matcher run: echo "::add-matcher::.github/problem-matchers/gettext-stats.json" - - name: Enable generic problem matcher - run: echo "::add-matcher::.github/problem-matchers/generic.json" + - id: meson-setup + name: Prepare build directory + run: meson setup build - name: Compile translation - run: make msgfmt/${{ matrix.lang }} 2>&1 | tee $GITHUB_STEP_SUMMARY + run: ninja -j1 -v msgfmt-${{ matrix.lang }} 2>&1 | tee $GITHUB_STEP_SUMMARY shell: bash + working-directory: build - name: Disable gettext stats problem matcher run: echo "::remove-matcher owner=gettext-stats::" - name: Ensure .po file is in sync with .pot - run: | - touch po/*.pot # Make sure .pot won't be re-generated - make msgcmp/${{ matrix.lang }} 2>&1 + run: ninja -j1 msgcmp-${{ matrix.lang }} shell: bash - if: ${{ always() && steps.checkout.conclusion == 'success' }} + working-directory: build + if: ${{ always() && steps.meson-setup.conclusion == 'success' }} diff --git a/.github/workflows/pot.yml b/.github/workflows/pot.yml index 880782287..950065049 100644 --- a/.github/workflows/pot.yml +++ b/.github/workflows/pot.yml @@ -11,7 +11,7 @@ on: - master paths-ignore: - docs/** - - po/*.po + - locale/*.po - README.md - Vagrantfile - vagrant-provision/** @@ -40,11 +40,20 @@ jobs: - name: Enable generic error matcher run: echo "::add-matcher::.github/problem-matchers/generic.json" - - name: Update .pot files - run: po/update-pot.sh + - name: Prepare build directory + run: meson setup build + if: ${{ always() && steps.checkout.conclusion == 'success' }} + + - name: Update .pot file + run: ninja -j1 pot + working-directory: build + + - name: Merge changes into .po files + run: ninja -j1 msgmerge + working-directory: build - name: Stage changes - run: git add po/*.po po/*.pot + run: git add locale/*.po locale/*.pot - name: Check if there are any changes id: diff diff --git a/.gitignore b/.gitignore index ef8801700..951e52c31 100644 --- a/.gitignore +++ b/.gitignore @@ -1,17 +1,6 @@ *~ -/node_modules/ -# Makefile output -/*.shell-extension.zip -/ddterm/pref/ui/ -/ddterm/com.github.amezin.ddterm.desktop -/ddterm/com.github.amezin.ddterm.desktop.in -/ddterm/com.github.amezin.ddterm.service -/metadata.json -/schemas/gschemas.compiled -/locale/ -/tmp/ -/revision.txt +/node_modules/ # do-in-docker.sh/do-in-podman.sh /.container-home/ diff --git a/bin/com.github.amezin.ddterm b/bin/com.github.amezin.ddterm.in similarity index 79% rename from bin/com.github.amezin.ddterm rename to bin/com.github.amezin.ddterm.in index b127fbca2..2b934deb2 100755 --- a/bin/com.github.amezin.ddterm +++ b/bin/com.github.amezin.ddterm.in @@ -10,4 +10,4 @@ then PATH="$bindir${PATH:+:${PATH}}" fi -exec gjs -m "${bindir%/*}/ddterm/app/main.js" "$@" +exec "@GJS@" -m "${bindir%/*}/ddterm/app/main.js" "$@" diff --git a/bin/meson.build b/bin/meson.build new file mode 100644 index 000000000..de0360602 --- /dev/null +++ b/bin/meson.build @@ -0,0 +1,16 @@ +pack += configure_file( + input: 'com.github.amezin.ddterm.in', + output: '@BASENAME@', + configuration: gjs_config, + install: true, + install_dir: extension_dir / 'bin', + install_mode: 'rwxr-xr-x' +) + +launcher_installed = extension_dir / 'bin' / 'com.github.amezin.ddterm' + +install_symlink( + 'com.github.amezin.ddterm', + pointing_to: launcher_installed, + install_dir: bindir, +) diff --git a/bump-version.sh b/bump-version.sh index 2804ce5d9..d8a922192 100755 --- a/bump-version.sh +++ b/bump-version.sh @@ -4,14 +4,11 @@ set -ex command -V jq -CURRENT_VERSION=$(jq .version metadata.json.in) +CURRENT_VERSION=$(meson rewrite kwargs info project / 2>&1 | jq -r '.kwargs."project#/".version') NEXT_VERSION=$(( ${CURRENT_VERSION} + 1 )) -git tag v${CURRENT_VERSION} - -jq ".version=${NEXT_VERSION}" metadata.json.in > metadata.json.next -mv -f metadata.json.next metadata.json.in - +meson rewrite kwargs set project / version "${NEXT_VERSION}" sed -i "/^pkgver=/c\pkgver=${NEXT_VERSION}" PKGBUILD +git tag "v${CURRENT_VERSION}" git commit -m "[ci skip] Post-release version bump" metadata.json.in PKGBUILD diff --git a/ddterm/app/icons/meson.build b/ddterm/app/icons/meson.build new file mode 100644 index 000000000..f1163f76b --- /dev/null +++ b/ddterm/app/icons/meson.build @@ -0,0 +1,13 @@ +icon_files = files( + 'quotation-symbolic.svg', + 'regex-symbolic.svg', + 'uppercase-symbolic.svg', +) + +foreach icon_file : icon_files + pack += fs.copyfile( + icon_file, + install: true, + install_dir: extension_dir / 'ddterm' / 'app' / 'icons', + ) +endforeach diff --git a/ddterm/app/meson.build b/ddterm/app/meson.build new file mode 100644 index 000000000..08adef3e1 --- /dev/null +++ b/ddterm/app/meson.build @@ -0,0 +1,43 @@ +app_js_files = files( + 'accellabel.js', + 'application.js', + 'appwindow.js', + 'dependencies-notification.js', + 'dependencies.js', + 'gtktheme.js', + 'heapdump.js', + 'init.js', + 'main.js', + 'meta.js', + 'notebook.js', + 'pcre2.js', + 'prefsdialog.js', + 'search.js', + 'settings.js', + 'tablabel.js', + 'tcgetpgrp.js', + 'terminal.js', + 'terminalpage.js', + 'terminalsettings.js', + 'urldetect.js', + 'urldetect_patterns.js', + 'waitstatus.js' +) + +potfiles += app_js_files +potfiles += files('menus.ui') + +foreach app_file : app_js_files + files('dependencies.json', 'menus.ui', 'style.css') + pack += fs.copyfile( + app_file, + install: true, + install_dir: extension_dir / 'ddterm' / 'app', + ) +endforeach + +subdir('icons') + +ui_validate_targets += run_target( + 'validate-app-ui', + command: [gtk3_builder_tool, 'validate', files('menus.ui')], +) diff --git a/ddterm/meson.build b/ddterm/meson.build new file mode 100644 index 000000000..eaa569457 --- /dev/null +++ b/ddterm/meson.build @@ -0,0 +1,59 @@ +ddterm_files = files( + 'com.github.amezin.ddterm.Extension.xml', + 'com.github.amezin.ddterm.HeapDump.xml', + 'com.github.amezin.ddterm.service.in', +) + +foreach ddterm_file : ddterm_files + pack += fs.copyfile( + ddterm_file, + install: true, + install_dir: extension_dir / 'ddterm', + ) +endforeach + +desktop_entry_untranslated = files('com.github.amezin.ddterm.desktop.in.in') +potfiles += desktop_entry_untranslated + +pack += i18n.merge_file( + input: desktop_entry_untranslated, + output: '@BASENAME@', + po_dir: '../locale', + type: 'desktop', +) + +launcher_config = configuration_data() +launcher_config.set('LAUNCHER', launcher_installed) + +desktop_entry_final = i18n.merge_file( + input: configure_file( + input: desktop_entry_untranslated, + output: '@BASENAME@_configured', + configuration: launcher_config, + ), + output: '@BASENAME@', + po_dir: '../locale', + type: 'desktop', + install: true, + install_dir: applications_dir, +) + +configure_file( + input: 'com.github.amezin.ddterm.service.in', + output: '@BASENAME@', + configuration: launcher_config, + install: true, + install_dir: dbus_service_dir, +) + +subdir('app') +subdir('pref') +subdir('shell') +subdir('util') + +desktop_file_validate_tool = find_program('desktop-file-validate', native: true) + +check_targets += run_target( + 'desktop-file-validate', + command: [desktop_file_validate_tool, desktop_entry_final], +) diff --git a/ddterm/pref/meson.build b/ddterm/pref/meson.build new file mode 100644 index 000000000..6e4c6a2a5 --- /dev/null +++ b/ddterm/pref/meson.build @@ -0,0 +1,33 @@ +pref_files = files( + 'adw.js', + 'animation.js', + 'behavior.js', + 'colors.js', + 'command.js', + 'compatibility.js', + 'panelicon.js', + 'positionsize.js', + 'scrolling.js', + 'shortcuts.js', + 'tabs.js', + 'text.js', + 'util.js', + 'widget.js', +) + +potfiles += pref_files + +pref_copy_files = [] + +foreach pref_file : pref_files + pref_copy_files += fs.copyfile( + pref_file, + install: true, + install_dir: extension_dir / 'ddterm' / 'pref', + ) +endforeach + +pack += pref_copy_files + +subdir('ui') +subdir('test') diff --git a/ddterm/pref/test/meson.build b/ddterm/pref/test/meson.build new file mode 100644 index 000000000..c3b22d240 --- /dev/null +++ b/ddterm/pref/test/meson.build @@ -0,0 +1,18 @@ +pref_test_common_files = [ + fs.copyfile('common.js'), + pref_copy_files, + schema_copy, + schemas_compiled, +] + +run_target( + 'pref-gtk3-test', + command: [gjs, '-m', fs.copyfile('gtk3.js')], + depends: [pref_test_common_files, pref_ui_gtk3_files] +) + +run_target( + 'pref-gtk4-test', + command: [gjs, '-m', fs.copyfile('gtk4.js')], + depends: [pref_test_common_files, pref_ui_gtk4_files] +) diff --git a/ddterm/pref/ui/gtk3/meson.build b/ddterm/pref/ui/gtk3/meson.build new file mode 100644 index 000000000..d165a1e8b --- /dev/null +++ b/ddterm/pref/ui/gtk3/meson.build @@ -0,0 +1,24 @@ +pref_ui_gtk3_files = [] + +foreach pref_ui_file: pref_ui_files + pref_ui_gtk3_files += custom_target( + command: [output_capture, gtk3_builder_tool, 'simplify', '@INPUT@'], + input: pref_ui_file, + output: '@PLAINNAME@', + install: true, + install_dir: extension_dir / 'ddterm' / 'pref' / 'ui' / 'gtk3', + ) +endforeach + +pack += pref_ui_gtk3_files + +pref_ui_gtk3_validate_targets = [] + +foreach pref_ui_file: pref_ui_gtk3_files + pref_ui_gtk3_validate_targets += run_target( + 'validate-pref-ui-gtk3-' + fs.name(pref_ui_file.full_path()), + command: [gtk3_builder_tool, 'validate', pref_ui_file], + ) +endforeach + +pref_ui_gtk3_validate_target = alias_target('validate-pref-ui-gtk3', pref_ui_gtk3_validate_targets) diff --git a/ddterm/pref/glade/3to4-fixup.xsl b/ddterm/pref/ui/gtk4/3to4-fixup.xsl similarity index 100% rename from ddterm/pref/glade/3to4-fixup.xsl rename to ddterm/pref/ui/gtk4/3to4-fixup.xsl diff --git a/ddterm/pref/ui/gtk4/meson.build b/ddterm/pref/ui/gtk4/meson.build new file mode 100644 index 000000000..52f42428a --- /dev/null +++ b/ddterm/pref/ui/gtk4/meson.build @@ -0,0 +1,66 @@ +gtk4_dep = dependency( + 'gtk4', + method: 'pkg-config', + required: false, + native: true, +) + +gtk4_builder_tool = find_program( + 'gtk4-builder-tool', + dirs: [ + gtk4_dep.get_variable( + 'exec_prefix', + default_value: gtk4_dep.get_variable('prefix', default_value: prefix) + ) / 'bin', + ], + native: true, +) + +libxslt_dep = dependency( + 'libxslt', + method: 'pkg-config', + required: false, + native: true, +) + +xsltproc = find_program( + 'xsltproc', + dirs: [ + libxslt_dep.get_variable( + 'exec_prefix', + default_value: libxslt_dep.get_variable('prefix', default_value: prefix) + ) / 'bin', + ], + native: true, +) + +pref_ui_gtk4_files = [] + +foreach pref_ui_file: pref_ui_files + fixup = custom_target( + command: [xsltproc, '-o', '@OUTPUT@', files('3to4-fixup.xsl'), '@INPUT@'], + input: pref_ui_file, + output: fs.stem(pref_ui_file) + '.fixup.ui', + ) + + pref_ui_gtk4_files += custom_target( + command: [output_capture, gtk4_builder_tool, 'simplify', '--3to4', '@INPUT@'], + input: fixup, + output: fs.name(pref_ui_file), + install: true, + install_dir: extension_dir / 'ddterm' / 'pref' / 'ui' / 'gtk4', + ) +endforeach + +pack += pref_ui_gtk4_files + +pref_ui_gtk4_validate_targets = [] + +foreach pref_ui_file: pref_ui_gtk4_files + pref_ui_gtk4_validate_targets += run_target( + 'validate-pref-ui-gtk4-' + fs.name(pref_ui_file.full_path()), + command: [gtk4_builder_tool, 'validate', pref_ui_file], + ) +endforeach + +pref_ui_gtk4_validate_target = alias_target('validate-pref-ui-gtk4', pref_ui_gtk4_validate_targets) diff --git a/ddterm/pref/ui/meson.build b/ddterm/pref/ui/meson.build new file mode 100644 index 000000000..e30866225 --- /dev/null +++ b/ddterm/pref/ui/meson.build @@ -0,0 +1,34 @@ +pref_ui_files = files( + 'prefs-animation.ui', + 'prefs-behavior.ui', + 'prefs-colors.ui', + 'prefs-command.ui', + 'prefs-compatibility.ui', + 'prefs-panel-icon.ui', + 'prefs-position-size.ui', + 'prefs-scrolling.ui', + 'prefs-shortcuts.ui', + 'prefs-tabs.ui', + 'prefs-text.ui', +) + +potfiles += pref_ui_files + +pref_ui_src_validate_targets = [] + +foreach pref_ui_file: pref_ui_files + pref_ui_src_validate_targets += run_target( + 'validate-pref-ui-src-' + fs.name(pref_ui_file), + command: [gtk3_builder_tool, 'validate', pref_ui_file], + ) +endforeach + +pref_ui_src_validate_target = alias_target('validate-pref-ui-src', pref_ui_src_validate_targets) + +subdir('gtk3') +subdir('gtk4') + +ui_validate_targets += alias_target( + 'validate-pref-ui', + [pref_ui_src_validate_target, pref_ui_gtk3_validate_target, pref_ui_gtk4_validate_target] +) diff --git a/ddterm/pref/glade/prefs-animation.ui b/ddterm/pref/ui/prefs-animation.ui similarity index 100% rename from ddterm/pref/glade/prefs-animation.ui rename to ddterm/pref/ui/prefs-animation.ui diff --git a/ddterm/pref/glade/prefs-behavior.ui b/ddterm/pref/ui/prefs-behavior.ui similarity index 100% rename from ddterm/pref/glade/prefs-behavior.ui rename to ddterm/pref/ui/prefs-behavior.ui diff --git a/ddterm/pref/glade/prefs-colors.ui b/ddterm/pref/ui/prefs-colors.ui similarity index 100% rename from ddterm/pref/glade/prefs-colors.ui rename to ddterm/pref/ui/prefs-colors.ui diff --git a/ddterm/pref/glade/prefs-command.ui b/ddterm/pref/ui/prefs-command.ui similarity index 100% rename from ddterm/pref/glade/prefs-command.ui rename to ddterm/pref/ui/prefs-command.ui diff --git a/ddterm/pref/glade/prefs-compatibility.ui b/ddterm/pref/ui/prefs-compatibility.ui similarity index 100% rename from ddterm/pref/glade/prefs-compatibility.ui rename to ddterm/pref/ui/prefs-compatibility.ui diff --git a/ddterm/pref/glade/prefs-panel-icon.ui b/ddterm/pref/ui/prefs-panel-icon.ui similarity index 100% rename from ddterm/pref/glade/prefs-panel-icon.ui rename to ddterm/pref/ui/prefs-panel-icon.ui diff --git a/ddterm/pref/glade/prefs-position-size.ui b/ddterm/pref/ui/prefs-position-size.ui similarity index 100% rename from ddterm/pref/glade/prefs-position-size.ui rename to ddterm/pref/ui/prefs-position-size.ui diff --git a/ddterm/pref/glade/prefs-scrolling.ui b/ddterm/pref/ui/prefs-scrolling.ui similarity index 100% rename from ddterm/pref/glade/prefs-scrolling.ui rename to ddterm/pref/ui/prefs-scrolling.ui diff --git a/ddterm/pref/glade/prefs-shortcuts.ui b/ddterm/pref/ui/prefs-shortcuts.ui similarity index 100% rename from ddterm/pref/glade/prefs-shortcuts.ui rename to ddterm/pref/ui/prefs-shortcuts.ui diff --git a/ddterm/pref/glade/prefs-tabs.ui b/ddterm/pref/ui/prefs-tabs.ui similarity index 100% rename from ddterm/pref/glade/prefs-tabs.ui rename to ddterm/pref/ui/prefs-tabs.ui diff --git a/ddterm/pref/glade/prefs-text.ui b/ddterm/pref/ui/prefs-text.ui similarity index 100% rename from ddterm/pref/glade/prefs-text.ui rename to ddterm/pref/ui/prefs-text.ui diff --git a/ddterm/shell/meson.build b/ddterm/shell/meson.build new file mode 100644 index 000000000..d0aae650c --- /dev/null +++ b/ddterm/shell/meson.build @@ -0,0 +1,24 @@ +shell_files = files( + 'appcontrol.js', + 'dbusapi.js', + 'extension.js', + 'geometry.js', + 'install.js', + 'notifications.js', + 'panelicon.js', + 'sd_journal.js', + 'service.js', + 'subprocess.js', + 'windowmatch.js', + 'wm.js', +) + +potfiles += shell_files + +foreach shell_file : shell_files + pack += fs.copyfile( + shell_file, + install: true, + install_dir: extension_dir / 'ddterm' / 'shell', + ) +endforeach diff --git a/ddterm/util/meson.build b/ddterm/util/meson.build new file mode 100644 index 000000000..a5d133d28 --- /dev/null +++ b/ddterm/util/meson.build @@ -0,0 +1,11 @@ +util_files = files( + 'displayconfig.js', +) + +foreach util_file : util_files + pack += fs.copyfile( + util_file, + install: true, + install_dir: extension_dir / 'ddterm' / 'util', + ) +endforeach diff --git a/lint/meson.build b/lint/meson.build new file mode 100644 index 000000000..60e95ddc5 --- /dev/null +++ b/lint/meson.build @@ -0,0 +1,43 @@ +npm_tool = find_program('npm', required: false, disabler: true, native: true) + +npm_install_prefix = meson.current_build_dir() + +npm_project_files = [ + fs.copyfile(meson.project_source_root() / 'package.json'), + fs.copyfile(meson.project_source_root() / 'package-lock.json'), +] + +subdir('node_modules') + +check_targets += run_target( + 'eslint', + command: [ + npm_tool, + '-C', + npm_install_prefix, + 'exec', + '--', + 'eslint', + '--resolve-plugins-relative-to', + npm_install_prefix, + meson.project_source_root() + ], + depends: npm_install, +) + +run_target( + 'eslint-fix', + command: [ + npm_tool, + '-C', + npm_install_prefix, + 'exec', + '--', + 'eslint', + '--resolve-plugins-relative-to', + npm_install_prefix, + '--fix', + meson.project_source_root() + ], + depends: npm_install, +) diff --git a/lint/node_modules/meson.build b/lint/node_modules/meson.build new file mode 100644 index 000000000..8ba5ae99d --- /dev/null +++ b/lint/node_modules/meson.build @@ -0,0 +1,5 @@ +npm_install = custom_target( + command: [npm_tool, '-C', npm_install_prefix, 'install'], + output: '.package-lock.json', + depends: npm_project_files, +) diff --git a/po/LINGUAS b/locale/LINGUAS similarity index 100% rename from po/LINGUAS rename to locale/LINGUAS diff --git a/po/README.md b/locale/README.md similarity index 100% rename from po/README.md rename to locale/README.md diff --git a/po/cs.po b/locale/cs.po similarity index 100% rename from po/cs.po rename to locale/cs.po diff --git a/po/ddterm@amezin.github.com.pot b/locale/ddterm@amezin.github.com.pot similarity index 100% rename from po/ddterm@amezin.github.com.pot rename to locale/ddterm@amezin.github.com.pot diff --git a/po/de.po b/locale/de.po similarity index 100% rename from po/de.po rename to locale/de.po diff --git a/po/el.po b/locale/el.po similarity index 100% rename from po/el.po rename to locale/el.po diff --git a/po/es.po b/locale/es.po similarity index 100% rename from po/es.po rename to locale/es.po diff --git a/po/fr.po b/locale/fr.po similarity index 100% rename from po/fr.po rename to locale/fr.po diff --git a/po/id.po b/locale/id.po similarity index 100% rename from po/id.po rename to locale/id.po diff --git a/po/it.po b/locale/it.po similarity index 100% rename from po/it.po rename to locale/it.po diff --git a/locale/meson.build b/locale/meson.build new file mode 100644 index 000000000..c9fc3b641 --- /dev/null +++ b/locale/meson.build @@ -0,0 +1,121 @@ +languages = [] + +foreach line: fs.read('LINGUAS').split('\n') + line = line.strip() + if not line.startswith('#') + foreach language: line.split() + if language != '' + languages += language + endif + endforeach + endif +endforeach + +gettext_targets = i18n.gettext( + gettext_domain, + languages: languages, + install: true, + install_dir: extension_dir / 'locale' +) + +pack += gettext_targets[0] + +alias_target('locales', gettext_targets[0]) + +potfiles_rel = [] + +if meson.version().version_compare('>=1.3.0') + foreach potfile: potfiles + potfiles_rel += fs.relative_to(potfile, meson.project_source_root()) + endforeach +else + foreach potfile: potfiles + potfiles_rel += run_command( + 'realpath', + '--relative-to=@SOURCE_ROOT@', + potfile, + capture: true, + check: true, + ).stdout().strip(['\n']) + endforeach +endif + +xgettext_tool = find_program('xgettext', required: false, disabler: true, native: true) + +pot_target = custom_target( + command: [ + xgettext_tool, + '--from-code=UTF-8', + '--package-name=ddterm', + '--output=@OUTPUT@', + '--sort-by-file', + '-D', '@SOURCE_ROOT@', + potfiles_rel + ], + input: potfiles, + output: f'@gettext_domain@.pot', +) + +pot_update_target = run_target( + 'pot', + command: [ + 'bash', + '-c', + 'if ! diff -u <(sed -f "$3" "$1") <(sed -f "$3" "$2"); then mv "$2" "$1"; fi', + '--', + '@CURRENT_SOURCE_DIR@' / f'@gettext_domain@.pot', + pot_target, + files('remove-potcdate.sin') + ] +) + +msgmerge_tool = find_program('msgmerge', required: false, disabler: true, native: true) +msgmerge_targets = [] + +foreach language: languages + msgmerge_targets += run_target( + f'msgmerge-@language@', + command: [ + msgmerge_tool, + '--update', + '--previous', + '@CURRENT_SOURCE_DIR@' / f'@language@.po', + '@CURRENT_SOURCE_DIR@' / f'@gettext_domain@.pot', + ] + ) +endforeach + +alias_target('msgmerge', msgmerge_targets) + +msgcmp_tool = find_program('msgcmp', required: false, disabler: true, native: true) +msgfmt_tool = find_program('msgfmt', required: false, disabler: true, native: true) + +msgcmp_targets = [] +msgfmt_targets = [] + +foreach language: languages + msgcmp_targets += run_target( + f'msgcmp-@language@', + command: [ + msgcmp_tool, + '--use-untranslated', + '--use-fuzzy', + '@CURRENT_SOURCE_DIR@' / f'@language@.po', + '@CURRENT_SOURCE_DIR@' / f'@gettext_domain@.pot', + ], + ) + + msgfmt_targets += run_target( + f'msgfmt-@language@', + command: [ + msgfmt_tool, + '--check', + '-o', '/dev/null', + '-v', + '@CURRENT_SOURCE_DIR@' / f'@language@.po', + ], + ) +endforeach + +check_targets += alias_target('msgcmp', msgcmp_targets) +check_targets += alias_target('msgfmt', msgfmt_targets) diff --git a/po/nb_NO.po b/locale/nb_NO.po similarity index 100% rename from po/nb_NO.po rename to locale/nb_NO.po diff --git a/po/pl.po b/locale/pl.po similarity index 100% rename from po/pl.po rename to locale/pl.po diff --git a/po/pt.po b/locale/pt.po similarity index 100% rename from po/pt.po rename to locale/pt.po diff --git a/po/remove-potcdate.sin b/locale/remove-potcdate.sin similarity index 100% rename from po/remove-potcdate.sin rename to locale/remove-potcdate.sin diff --git a/po/ru.po b/locale/ru.po similarity index 100% rename from po/ru.po rename to locale/ru.po diff --git a/po/zh_CN.po b/locale/zh_CN.po similarity index 100% rename from po/zh_CN.po rename to locale/zh_CN.po diff --git a/meson.build b/meson.build new file mode 100644 index 000000000..0f7199ff8 --- /dev/null +++ b/meson.build @@ -0,0 +1,179 @@ +project( + 'ddterm', + version : '49', + meson_version : '>= 1.0.0', + license : 'GPL3+', + default_options : ['prefix=/usr'] +) + +gjs_version_required = '>=1.78.0' + +fs = import('fs') +gnome = import('gnome') +i18n = import('i18n') + +output_capture = [ + meson.project_source_root() / 'tools' / 'capture_stdout.py', '--output', '@OUTPUT@', '--' +] + +uuid = 'ddterm@amezin.github.com' +gettext_domain = uuid +settings_schema = 'com.github.amezin.ddterm' + +prefix = get_option('prefix') +bindir = prefix / get_option('bindir') +datadir = prefix / get_option('datadir') + +extension_dir = datadir / 'gnome-shell' / 'extensions' / uuid +schema_dir = datadir / 'glib-2.0' / 'schemas' +applications_dir = datadir / 'applications' +dbus_service_dir = datadir / 'dbus-1' / 'services' + +pack = [] +potfiles = [] +check_targets = [] + +pack += fs.copyfile( + 'extension.js', + install: true, + install_dir: extension_dir +) + +pack += fs.copyfile( + 'prefs.js', + install: true, + install_dir: extension_dir +) + +pack += fs.copyfile('LICENSE') + +metadata = configuration_data() +metadata.set('version', meson.project_version()) +metadata.set_quoted('uuid', uuid) +metadata.set_quoted('gettext_domain', gettext_domain) +metadata.set_quoted('settings_schema', settings_schema) + +pack += configure_file( + input: 'metadata.json.in', + output: '@BASENAME@', + configuration: metadata, + install: true, + install_dir: extension_dir, +) + +if fs.read('revision.txt.in').strip() == '$Format:%H$' + git = find_program('git', native: true) + + pack += custom_target( + command: [ + output_capture, + git, '-C', '@CURRENT_SOURCE_DIR@', '--git-dir', '.git', 'rev-parse', 'HEAD' + ], + output: 'revision.txt', + build_always_stale: true, + install: true, + install_dir: extension_dir, + ) +else + pack += fs.copyfile( + 'revision.txt.in', + 'revision.txt', + install: true, + install_dir: extension_dir, + ) +endif + +gjs_dep = dependency( + 'gjs-1.0', + version: gjs_version_required, + method: 'pkg-config', + required: false +) + +gjs = find_program( + ['gjs', gjs_dep.get_variable('gjs_console', default_value: 'gjs')], + dirs: [gjs_dep.get_variable('bindir', default_value: bindir)], + version: gjs_version_required, +) + +gjs_config = configuration_data() +gjs_config.set('GJS', gjs.full_path()) + +gio_dep = dependency( + 'gio-2.0', + method: 'pkg-config', + required: false, + native: true, +) + +gtk3_dep = dependency( + 'gtk+-3.0', + method: 'pkg-config', + required: false, + native: true, +) + +gtk3_builder_tool = find_program( + 'gtk-builder-tool', + dirs: [ + gtk3_dep.get_variable( + 'exec_prefix', + default_value: gtk3_dep.get_variable('prefix', default_value: prefix) + ) / 'bin', + ], + native: true, +) + +ui_validate_targets = [] + +subdir('bin') +subdir('schemas') +subdir('ddterm') +subdir('locale') + +check_targets += alias_target('validate-ui', ui_validate_targets) + +gnome.post_install( + glib_compile_schemas: true, + update_desktop_database: true, +) + +pack_target = custom_target( + command: [ + 'tools' / 'makezip.py', '--output', '@OUTPUT@', '--relative-to', '@OUTDIR@', '--', '@INPUT@' + ], + input: pack, + output: f'@uuid@.shell-extension.zip', + build_by_default: true, +) + +alias_target('pack', pack_target) + +extensions_tool = find_program('gnome-extensions', required: false, disabler: true, native: true) + +run_target( + 'user-install', + command: [extensions_tool, 'install', '-f', pack_target], +) + +run_target('user-uninstall', command: [extensions_tool, 'uninstall', uuid]) + +foreach target: ['prefs', 'enable', 'disable', 'reset'] + run_target(target, command: [extensions_tool, target, uuid]) +endforeach + +gapplication_tool = find_program( + 'gapplication', + dirs: [gio_dep.get_variable('bindir', default_value: bindir)], + required: false, + disabler: true, + native: true, +) + +foreach target: ['toggle', 'quit'] + run_target(target, command: [gapplication_tool, 'action', 'com.github.amezin.ddterm', target]) +endforeach + +subdir('lint') + +alias_target('check', check_targets) diff --git a/metadata.json.in b/metadata.json.in index b1acf82af..e5613f75c 100644 --- a/metadata.json.in +++ b/metadata.json.in @@ -1,12 +1,12 @@ { "name": "ddterm", "description": "Another drop down terminal extension for GNOME Shell. With tabs. Works on Wayland natively", - "uuid": "ddterm@amezin.github.com", - "gettext-domain": "ddterm@amezin.github.com", - "settings-schema": "com.github.amezin.ddterm", + "uuid": @uuid@, + "gettext-domain": @gettext_domain@, + "settings-schema": @settings_schema@, "shell-version": [ "45" ], - "version": 49, + "version": @version@, "url": "https://github.com/ddterm/gnome-shell-extension-ddterm" } diff --git a/po/update-pot.sh b/po/update-pot.sh deleted file mode 100755 index 8a4da3514..000000000 --- a/po/update-pot.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash - -SCRIPT_DIR=$(CDPATH="" cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd) -MAKEFILE_DIR="$SCRIPT_DIR/.." - -remove_potcdate() { - sed -f "$SCRIPT_DIR/remove-potcdate.sin" "$@" -} - -set -ex - -# Update .pot file(s), but keep existing POT-Creation-Date if nothing else changed - -for POTFILE in "$SCRIPT_DIR"/*.pot -do - mv "$POTFILE" "$POTFILE~" # backup - make -C "$MAKEFILE_DIR" "$(realpath --relative-to="$MAKEFILE_DIR" "$POTFILE")" - # Compare ignoring POT-Creation-Date - if diff <(remove_potcdate "$POTFILE~") <(remove_potcdate "$POTFILE") - then - mv "$POTFILE~" "$POTFILE" # restore old file if no changes - exit 0 - fi -done - -make -C "$MAKEFILE_DIR" msgmerge-fuzzy diff --git a/schemas/meson.build b/schemas/meson.build new file mode 100644 index 000000000..bf958f072 --- /dev/null +++ b/schemas/meson.build @@ -0,0 +1,32 @@ +schema = files(f'@settings_schema@.gschema.xml') + +glib_compile_schemas_tool = find_program( + [ + 'glib-compile-schemas', + gio_dep.get_variable('glib_compile_schemas', default_value: 'glib-compile-schemas') + ], + dirs: [gio_dep.get_variable('bindir', default_value: bindir)], + required: false, + disabler: true, +) + +schemas_compiled = custom_target( + command: [ + glib_compile_schemas_tool, + '--strict', + '--targetdir=@OUTDIR@', + '@CURRENT_SOURCE_DIR@' + ], + input: schema, + output: 'gschemas.compiled', +) + +check_targets += alias_target('schemas', schemas_compiled) + +schema_copy = fs.copyfile( + schema, + install: true, + install_dir: schema_dir +) + +pack += schema_copy diff --git a/tools/capture_stdout.py b/tools/capture_stdout.py new file mode 100644 index 000000000..ef5f493be --- /dev/null +++ b/tools/capture_stdout.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 + +import argparse +import os + + +def run(output, argv): + os.dup2(os.open(output, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, mode=0o666), 1) + os.execvp(argv[0], argv) + + +def cli(*args, **kwargs): + parser = argparse.ArgumentParser() + parser.add_argument('--output', required=True) + parser.add_argument('argv', nargs='+') + + run(**vars(parser.parse_args(*args, **kwargs))) + + +if __name__ == '__main__': + cli() diff --git a/tools/makezip.py b/tools/makezip.py new file mode 100644 index 000000000..c1605c967 --- /dev/null +++ b/tools/makezip.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 + +import argparse +import os.path +import zipfile + + +def makezip(output, inputs, relative_to): + with zipfile.ZipFile( + output, + mode='w', + compression=zipfile.ZIP_DEFLATED, + compresslevel=9, + ) as out: + for infile in inputs: + out.write(infile, arcname=os.path.relpath(infile, relative_to)) + + +def cli(*args, **kwargs): + parser = argparse.ArgumentParser() + parser.add_argument('--relative-to', default=os.curdir) + parser.add_argument('--output', required=True) + parser.add_argument('inputs', nargs='+') + + makezip(**vars(parser.parse_args(*args, **kwargs))) + + +if __name__ == '__main__': + cli()