From 32eaf49938354968c6d1713ec3596f56d54ab05d 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 | 47 +- .github/workflows/check-po.yml | 20 +- .github/workflows/pot.yml | 18 +- .gitignore | 13 +- Makefile | 500 ------------------ PKGBUILD | 9 +- ...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 | 41 ++ ddterm/meson.build | 60 +++ ddterm/pref/meson.build | 31 ++ 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 | 32 ++ 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 + docs/Translations.md | 5 +- lint/meson.build | 27 + lint/node_modules/meson.build | 6 + locale | 1 + meson.build | 178 +++++++ metadata.json.in | 8 +- po/POTFILES.in | 35 ++ po/gen-potfiles.py | 66 +++ po/meson.build | 41 ++ po/remove-potcdate.sin | 19 - po/update-pot.sh | 26 - schemas/meson.build | 32 ++ tools/capture_stdout.py | 21 + tools/makezip.py | 29 + 47 files changed, 850 insertions(+), 604 deletions(-) delete mode 100755 Makefile rename bin/{com.github.amezin.ddterm => com.github.amezin.ddterm.in} (78%) 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 create mode 120000 locale create mode 100644 meson.build create mode 100644 po/POTFILES.in create mode 100755 po/gen-potfiles.py create mode 100644 po/meson.build delete mode 100644 po/remove-potcdate.sin 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..94beff0ba 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,40 @@ 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: Update POTFILES.in + run: ninja -j1 potfiles && git diff + working-directory: build + shell: bash + if: ${{ always() && steps.meson-setup.conclusion == 'success' }} + + - name: Update .pot file and merge changes into .po files + run: ninja -j1 msgmerge && git diff + 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 +127,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 +144,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..84ec72844 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,26 @@ jobs: steps: - name: Checkout - id: checkout uses: actions/checkout@v4 - run: git config --global --replace-all safe.directory "$GITHUB_WORKSPACE" - - 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" + - name: Enable gettext stats problem matcher + run: echo "::add-matcher::.github/problem-matchers/gettext-stats.json" + - name: Compile translation - run: make msgfmt/${{ matrix.lang }} 2>&1 | tee $GITHUB_STEP_SUMMARY + run: | + echo locale/${{ matrix.lang }}.po + msgfmt --check -v -o /dev/null locale/${{ matrix.lang }}.po 2>&1 | tee $GITHUB_STEP_SUMMARY shell: bash - 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: msgcmp --use-untranslated --use-fuzzy locale/${{ matrix.lang }}.po locale/*.pot shell: bash - if: ${{ always() && steps.checkout.conclusion == 'success' }} + if: ${{ always() && steps.meson-setup.conclusion == 'success' }} diff --git a/.github/workflows/pot.yml b/.github/workflows/pot.yml index 880782287..f56c56b25 100644 --- a/.github/workflows/pot.yml +++ b/.github/workflows/pot.yml @@ -11,7 +11,7 @@ on: - master paths-ignore: - docs/** - - po/*.po + - locale/** - README.md - Vagrantfile - vagrant-provision/** @@ -40,11 +40,19 @@ 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 + + - name: Update POTFILES.in + run: ninja -j1 potfiles + working-directory: build + + - name: Update .pot file and 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 @@ -52,7 +60,7 @@ jobs: with: result-encoding: string script: | - const { stdout } = await exec.getExecOutput('git', ['diff', '--cached']); + const { stdout } = await exec.getExecOutput('git', ['diff', '--cached', '--ignore-matching-lines=^"POT-Creation-Date: ']); return stdout.trim(); - name: Commit 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/Makefile b/Makefile deleted file mode 100755 index dae82623c..000000000 --- a/Makefile +++ /dev/null @@ -1,500 +0,0 @@ -#!/usr/bin/env -S make -f - -# See docs/BUILD.md - -SHELL := /bin/bash - -EXTENSION_UUID := ddterm@amezin.github.com - -TRUE_VALUES := yes YES true TRUE on ON 1 -is-true = $(filter 1,$(words $(filter $(TRUE_VALUES),$(1)))) - -all: -.PHONY: all - -find-tool = $(or $(shell command -v $(1)),tool-not-found/$(1)) - -define tool-not-found-message -$* not found and is required. -You could use do-in-docker.sh or do-in-podman.sh to avoid installing build dependencies. -Please check docs/BUILD.md -endef - -tool-not-found/%: - $(error $(tool-not-found-message)) - -CLEAN := -TRANSLATABLE_SOURCES := -PACK_CONTENT := - -# Git revision file - -ifeq ($(file $@ - -else - -revision.txt: revision.txt.in - cat $< >$@ - -endif - -CLEAN += revision.txt -PACK_CONTENT += revision.txt - -# GSettings schemas - -SCHEMAS := $(wildcard schemas/*.gschema.xml) -SCHEMAS_COMPILED := schemas/gschemas.compiled -SCHEMAS_ALL := $(SCHEMAS) $(SCHEMAS_COMPILED) - -GLIB_COMPILE_SCHEMAS := $(call find-tool,glib-compile-schemas) - -$(SCHEMAS_COMPILED): $(SCHEMAS) $(GLIB_COMPILE_SCHEMAS) - $(GLIB_COMPILE_SCHEMAS) --strict $(dir $@) - -CLEAN += $(SCHEMAS_COMPILED) -PACK_CONTENT += $(SCHEMAS) - -schemas: $(SCHEMAS_COMPILED) -.PHONY: schemas -all: schemas - -# Locales - -LINGUAS_FILE := po/LINGUAS -LOCALES_RELEASE := cs de el fr it nb_NO pl pt ru zh_CN -LOCALE_SOURCE_PATTERN := po/%.po -LOCALES_ALL := $(shell grep -Ev '^\s*#.*' $(LINGUAS_FILE)) - -ONLY_RELEASE_LOCALES := no - -ifeq ($(call is-true,$(ONLY_RELEASE_LOCALES)),1) -LOCALES := $(LOCALES_RELEASE) -else -LOCALES := $(LOCALES_ALL) -endif - -LOCALE_COMPILED_PATTERN := locale/%/LC_MESSAGES/$(EXTENSION_UUID).mo -LOCALES_COMPILED := $(patsubst %,$(LOCALE_COMPILED_PATTERN),$(LOCALES)) - -MSGFMT := $(call find-tool,msgfmt) - -$(LOCALES_COMPILED): $(LOCALE_COMPILED_PATTERN): $(LOCALE_SOURCE_PATTERN) $(MSGFMT) - mkdir -p $(dir $@) - $(MSGFMT) --check --strict --statistics -o $@ $< - -$(addprefix msgfmt/,$(LOCALES)): msgfmt/%: $(LOCALE_COMPILED_PATTERN) - -CLEAN += $(LOCALES_COMPILED) -PACK_CONTENT += $(LOCALES_COMPILED) - -locales msgfmt: $(LOCALES_COMPILED) -.PHONY: locales msgfmt - -# Glade UI - -PREFS_GLADE_UI := $(wildcard ddterm/pref/glade/*.ui) -PREFS_GLADE_UI_PATTERN := ddterm/pref/glade/%.ui -TRANSLATABLE_SOURCES += $(APP_GLADE_UI) $(PREFS_GLADE_UI) - -ddterm/pref/ui: - mkdir -p $@ - -# Gtk 3 .ui - -GTK_BUILDER_TOOL := $(call find-tool,gtk-builder-tool) - -ddterm/pref/ui/gtk3: | ddterm/pref/ui - mkdir -p $@ - -PREFS_UI_GTK3_PATTERN := ddterm/pref/ui/gtk3/%.ui -PREFS_UI_GTK3 := $(patsubst $(PREFS_GLADE_UI_PATTERN),$(PREFS_UI_GTK3_PATTERN),$(PREFS_GLADE_UI)) - -$(PREFS_UI_GTK3): $(PREFS_UI_GTK3_PATTERN): $(PREFS_GLADE_UI_PATTERN) $(GTK_BUILDER_TOOL) | ddterm/pref/ui/gtk3 - $(GTK_BUILDER_TOOL) simplify $< >$@ - -GTK3_GENERATED_UI := $(APP_UI) $(PREFS_UI_GTK3) -GTK3_HANDCRAFTED_UI := ddterm/app/menus.ui -GTK3_UI := $(GTK3_GENERATED_UI) $(GTK3_HANDCRAFTED_UI) - -CLEAN += $(GTK3_GENERATED_UI) -PACK_CONTENT += $(GTK3_UI) -TRANSLATABLE_SOURCES += $(GTK3_HANDCRAFTED_UI) - -# Gtk 4 .ui - -GTK4_BUILDER_TOOL := $(call find-tool,gtk4-builder-tool) -XSLTPROC := $(call find-tool,xsltproc) - -ddterm/pref/ui/gtk4 ddterm/pref/ui/gtk4/3to4-fixup ddterm/pref/ui/gtk4/3to4: - mkdir -p $@ - -ddterm/pref/ui/gtk4/3to4-fixup ddterm/pref/ui/gtk4/3to4: | ddterm/pref/ui/gtk4 - -PREFS_UI_3TO4_FIXUP_PATTERN := ddterm/pref/ui/gtk4/3to4-fixup/%.ui -PREFS_UI_3TO4_FIXUP := $(patsubst $(PREFS_GLADE_UI_PATTERN),$(PREFS_UI_3TO4_FIXUP_PATTERN),$(PREFS_GLADE_UI)) - -$(PREFS_UI_3TO4_FIXUP): $(PREFS_UI_3TO4_FIXUP_PATTERN): $(PREFS_GLADE_UI_PATTERN) ddterm/pref/glade/3to4-fixup.xsl $(XSLTPROC) | ddterm/pref/ui/gtk4/3to4-fixup - $(XSLTPROC) ddterm/pref/glade/3to4-fixup.xsl $< >$@ - -PREFS_UI_3TO4_PATTERN := ddterm/pref/ui/gtk4/3to4/%.ui -PREFS_UI_3TO4 := $(patsubst $(PREFS_UI_3TO4_FIXUP_PATTERN),$(PREFS_UI_3TO4_PATTERN),$(PREFS_UI_3TO4_FIXUP)) - -$(PREFS_UI_3TO4): $(PREFS_UI_3TO4_PATTERN): $(PREFS_UI_3TO4_FIXUP_PATTERN) $(GTK4_BUILDER_TOOL) | ddterm/pref/ui/gtk4/3to4 - $(GTK4_BUILDER_TOOL) simplify --3to4 $< >$@ - -PREFS_UI_GTK4_PATTERN := ddterm/pref/ui/gtk4/%.ui -PREFS_UI_GTK4 := $(patsubst $(PREFS_UI_3TO4_PATTERN),$(PREFS_UI_GTK4_PATTERN),$(PREFS_UI_3TO4)) - -$(PREFS_UI_GTK4): $(PREFS_UI_GTK4_PATTERN): $(PREFS_UI_3TO4_PATTERN) $(GTK4_BUILDER_TOOL) | ddterm/pref/ui/gtk4 - $(GTK4_BUILDER_TOOL) simplify $< >$@ - -CLEAN += $(PREFS_UI_3TO4_FIXUP) $(PREFS_UI_3TO4) $(PREFS_UI_GTK4) - -GTK4_UI := $(PREFS_UI_GTK4) - -PACK_CONTENT += $(GTK4_UI) - -# metadata.json - -# Prevent people from trying to feed source archives to 'gnome-extensions install'. -# https://github.com/ddterm/gnome-shell-extension-ddterm/issues/61 - -metadata.json: metadata.json.in - cp $< $@ - -PACK_CONTENT += metadata.json -CLEAN += metadata.json - -# JS sources - -JS_SOURCE_WILDCARDS := \ - *.js \ - ddterm/*.js \ - ddterm/app/*.js \ - ddterm/backport/*.js \ - ddterm/pref/*.js \ - ddterm/shell/*.js \ - ddterm/util/*.js \ - misc/*.js \ - -JS_SOURCES := $(wildcard $(JS_SOURCE_WILDCARDS)) -LAUNCHER := bin/com.github.amezin.ddterm -EXECUTABLES := $(LAUNCHER) - -TRANSLATABLE_SOURCES += $(JS_SOURCES) -PACK_CONTENT += $(EXECUTABLES) $(filter-out $(EXECUTABLES),$(JS_SOURCES)) - -# .desktop entry - -UNTRANSLATED_DESKTOP_ENTRY := ddterm/com.github.amezin.ddterm.desktop.in.in -TRANSLATABLE_SOURCES += $(UNTRANSLATED_DESKTOP_ENTRY) - -UNCONFIGURED_DESKTOP_ENTRY := $(basename $(UNTRANSLATED_DESKTOP_ENTRY)) - -$(UNCONFIGURED_DESKTOP_ENTRY): $(UNTRANSLATED_DESKTOP_ENTRY) $(MSGFMT) - $(MSGFMT) --desktop -o $@ --template=$< -d po - -$(UNCONFIGURED_DESKTOP_ENTRY): $(patsubst %,$(LOCALE_SOURCE_PATTERN),$(LOCALES)) -$(UNCONFIGURED_DESKTOP_ENTRY): $(LINGUAS_FILE) - -$(UNCONFIGURED_DESKTOP_ENTRY): export LINGUAS := $(LOCALES) - -CLEAN += $(UNCONFIGURED_DESKTOP_ENTRY) - -UNCONFIGURED_DBUS_SERVICE := ddterm/com.github.amezin.ddterm.service.in - -# package - -PACK_CONTENT += \ - ddterm/app/style.css \ - ddterm/app/dependencies.json \ - $(wildcard ddterm/app/icons/*) \ - ddterm/com.github.amezin.ddterm.Extension.xml \ - ddterm/com.github.amezin.ddterm.HeapDump.xml \ - $(UNCONFIGURED_DESKTOP_ENTRY) \ - $(UNCONFIGURED_DBUS_SERVICE) \ - LICENSE \ - -PACK_CONTENT := $(sort $(PACK_CONTENT)) - -build: $(PACK_CONTENT) -.PHONY: build - -ZIP := $(call find-tool,zip) - -EXTENSION_PACK := $(EXTENSION_UUID).shell-extension.zip -$(EXTENSION_PACK): $(PACK_CONTENT) $(ZIP) $(LINGUAS_FILE) - $(RM) $@ - $(ZIP) -y -nw $@ -- $(PACK_CONTENT) - -pack: $(EXTENSION_PACK) -.PHONY: pack - -all: pack -CLEAN += $(EXTENSION_PACK) - -# install/uninstall package - user - -user-install: $(EXTENSION_PACK) develop-uninstall - gnome-extensions install -f $< - -user-uninstall: develop-uninstall - gnome-extensions uninstall $(EXTENSION_UUID) - -.PHONY: user-install user-uninstall - -# install/uninstall package - system-wide - -# https://www.gnu.org/software/make/manual/html_node/Command-Variables.html -INSTALL := install -INSTALL_PROGRAM := $(INSTALL) -INSTALL_DATA := $(INSTALL) -m 644 - -# https://www.gnu.org/software/make/manual/html_node/Directory-Variables.html -prefix := /usr -exec_prefix := $(prefix) -datarootdir := $(prefix)/share -datadir := $(datarootdir) -bindir := $(exec_prefix)/bin - -extensiondir := $(datadir)/gnome-shell/extensions - -CONFIGURED_DESKTOP_ENTRY := $(basename $(UNCONFIGURED_DESKTOP_ENTRY)) -CONFIGURED_DBUS_SERVICE := $(basename $(UNCONFIGURED_DBUS_SERVICE)) - -SYS_INSTALLED_EXTENSION_DIR := $(extensiondir)/$(EXTENSION_UUID) -SYS_INSTALLED_CONTENT := $(addprefix $(SYS_INSTALLED_EXTENSION_DIR)/,$(filter-out $(SCHEMAS_ALL),$(PACK_CONTENT))) -SYS_INSTALLED_SCHEMAS := $(addprefix $(datadir)/glib-2.0/,$(SCHEMAS)) -SYS_INSTALLED_DESKTOP_ENTRY := $(datadir)/applications/$(notdir $(CONFIGURED_DESKTOP_ENTRY)) -SYS_INSTALLED_DBUS_SERVICE := $(datadir)/dbus-1/services/$(notdir $(CONFIGURED_DBUS_SERVICE)) -SYS_INSTALLED_EXECUTABLES := $(addprefix $(SYS_INSTALLED_EXTENSION_DIR)/,$(EXECUTABLES)) -SYS_INSTALLED_LAUNCHER := $(filter %$(LAUNCHER),$(SYS_INSTALLED_EXECUTABLES)) -SYS_INSTALLED_LAUNCHER_SYMLINK := $(bindir)/$(notdir $(LAUNCHER)) -SYS_INSTALLED_ALL := \ - $(SYS_INSTALLED_CONTENT) \ - $(SYS_INSTALLED_SCHEMAS) \ - $(SYS_INSTALLED_DESKTOP_ENTRY) \ - $(SYS_INSTALLED_DBUS_SERVICE) \ - $(SYS_INSTALLED_LAUNCHER_SYMLINK) \ - -SYS_INSTALLED_DIRS := $(sort $(dir $(SYS_INSTALLED_ALL))) - -$(addprefix $(DESTDIR),$(SYS_INSTALLED_DIRS)): - mkdir -p $@ - -installdirs: $(addprefix $(DESTDIR),$(SYS_INSTALLED_DIRS)) - -$(addprefix $(DESTDIR),$(SYS_INSTALLED_CONTENT)): $(DESTDIR)$(SYS_INSTALLED_EXTENSION_DIR)/%: % | installdirs - $(INSTALL) $< $@ - -$(addprefix $(DESTDIR),$(SYS_INSTALLED_SCHEMAS)): $(DESTDIR)$(datadir)/glib-2.0/%: % | installdirs - $(INSTALL) $< $@ - -$(addprefix $(DESTDIR),$(SYS_INSTALLED_CONTENT) $(SYS_INSTALLED_SCHEMAS)): INSTALL := $(INSTALL_DATA) -$(addprefix $(DESTDIR),$(SYS_INSTALLED_EXECUTABLES)): INSTALL := $(INSTALL_PROGRAM) - -$(CONFIGURED_DESKTOP_ENTRY) $(CONFIGURED_DBUS_SERVICE): - sed -e 's:@LAUNCHER@:$(SYS_INSTALLED_LAUNCHER):g' $< >$@ - -$(CONFIGURED_DESKTOP_ENTRY): $(UNCONFIGURED_DESKTOP_ENTRY) -$(CONFIGURED_DBUS_SERVICE): $(UNCONFIGURED_DBUS_SERVICE) - -CLEAN += $(CONFIGURED_DESKTOP_ENTRY) $(CONFIGURED_DBUS_SERVICE) - -DESKTOP_FILE_VALIDATE_TOOL := $(call find-tool,desktop-file-validate) - -desktop-file-validate: $(DESKTOP_FILE_VALIDATE_TOOL) $(CONFIGURED_DESKTOP_ENTRY) - $^ - -.PHONY: desktop-file-validate - -ifneq (tool-not-found/desktop-file-validate,$(DESKTOP_FILE_VALIDATE_TOOL)) -all: desktop-file-validate -endif - -$(addprefix $(DESTDIR),$(SYS_INSTALLED_DESKTOP_ENTRY) $(SYS_INSTALLED_DBUS_SERVICE)): | installdirs - $(INSTALL_DATA) $< $@ - -$(addprefix $(DESTDIR),$(SYS_INSTALLED_DESKTOP_ENTRY)): $(CONFIGURED_DESKTOP_ENTRY) -$(addprefix $(DESTDIR),$(SYS_INSTALLED_DBUS_SERVICE)): $(CONFIGURED_DBUS_SERVICE) - -$(addprefix $(DESTDIR),$(SYS_INSTALLED_LAUNCHER_SYMLINK)): | installdirs - ln -s $(SYS_INSTALLED_LAUNCHER) $@ - -system-schemas-compile system-schemas-compile-nodeps: $(GLIB_COMPILE_SCHEMAS) - $(GLIB_COMPILE_SCHEMAS) $(DESTDIR)$(datadir)/glib-2.0/schemas - -system-schemas-compile: $(addprefix $(DESTDIR),$(SYS_INSTALLED_SCHEMAS)) - -.PHONY: system-schemas-compile system-schemas-compile-nodeps - -system-install: $(addprefix $(DESTDIR),$(SYS_INSTALLED_ALL)) - -system-uninstall: - $(RM) $(addprefix $(DESTDIR),$(SYS_INSTALLED_ALL)) - $(RM) -r $(DESTDIR)$(SYS_INSTALLED_EXTENSION_DIR) - -.PHONY: system-install system-uninstall installdirs - -ifeq ($(DESTDIR),) -system-install: system-schemas-compile -system-uninstall: system-schemas-compile-nodeps -endif - -# System/user install autodetect - -ifneq ($(DESTDIR),) -INSTALL_FLAVOR := system -else ifeq ($(shell id -u),0) -INSTALL_FLAVOR := system -else -INSTALL_FLAVOR := user -endif - -install: $(INSTALL_FLAVOR)-install -uninstall: $(INSTALL_FLAVOR)-uninstall - -.PHONY: install uninstall - -# develop/symlink install - -DEVELOP_SYMLINK := $(HOME)/.local/share/gnome-shell/extensions/$(EXTENSION_UUID) - -develop: build - mkdir -p "$(dir $(DEVELOP_SYMLINK))" - @if [[ -e "$(DEVELOP_SYMLINK)" && ! -L "$(DEVELOP_SYMLINK)" ]]; then \ - echo "$(DEVELOP_SYMLINK) exists and is not a symlink, not overwriting"; exit 1; \ - fi - if [[ "$(abspath .)" != "$(abspath $(DEVELOP_SYMLINK))" ]]; then \ - ln -snf "$(abspath .)" "$(DEVELOP_SYMLINK)"; \ - fi - -develop-uninstall: - if [[ -L "$(DEVELOP_SYMLINK)" ]]; then \ - unlink "$(DEVELOP_SYMLINK)"; \ - fi - -.PHONY: develop develop-uninstall - -# clean - -clean: - $(RM) $(CLEAN) - -.PHONY: clean - -# .ui validation - -GTK3_VALIDATE_UI := $(addprefix gtk-builder-validate/,$(GTK3_UI)) - -$(GTK3_VALIDATE_UI): gtk-builder-validate/%: % $(GTK_BUILDER_TOOL) - $(GTK_BUILDER_TOOL) validate $< - -.PHONY: $(GTK3_VALIDATE_UI) - -GTK4_VALIDATE_UI := $(addprefix gtk-builder-validate/,$(GTK4_UI)) - -$(GTK4_VALIDATE_UI): gtk-builder-validate/%: % $(GTK4_BUILDER_TOOL) - $(GTK4_BUILDER_TOOL) validate $< - -.PHONY: $(GTK4_VALIDATE_UI) - -gtk-builder-validate: $(GTK3_VALIDATE_UI) $(GTK4_VALIDATE_UI) - -all: gtk-builder-validate -.PHONY: gtk-builder-validate - -# Translation helpers - -POT_FILE := po/$(EXTENSION_UUID).pot -XGETTEXT := $(call find-tool,xgettext) - -$(POT_FILE): $(TRANSLATABLE_SOURCES) $(XGETTEXT) - $(XGETTEXT) \ - --from-code=UTF-8 \ - --default-domain=$(EXTENSION_UUID) \ - --package-name=ddterm \ - --add-comments \ - --output=$@ \ - $(sort $(TRANSLATABLE_SOURCES)) - -pot: $(POT_FILE) -.PHONY: pot - -MSGCMP_GOALS := $(addprefix msgcmp/, $(LOCALES)) -MSGCMP_FLAGS := --use-untranslated --use-fuzzy -MSGCMP := $(call find-tool,msgcmp) - -$(MSGCMP_GOALS): msgcmp/%: $(LOCALE_SOURCE_PATTERN) $(POT_FILE) $(MSGCMP) - $(MSGCMP) $(MSGCMP_FLAGS) $< $(POT_FILE) - -msgcmp: $(MSGCMP_GOALS) - -msgcmp-strict: override MSGCMP_FLAGS := -msgcmp-strict: $(MSGCMP_GOALS) - -.PHONY: msgcmp msgcmp-strict $(MSGCMP_GOALS) - -MSGMERGE_GOALS := $(addprefix msgmerge/, $(LOCALES)) -MSGMERGE_FLAGS := --no-fuzzy-matching --update -MSGMERGE := $(call find-tool,msgmerge) - -$(MSGMERGE_GOALS): msgmerge/%: $(LOCALE_SOURCE_PATTERN) $(POT_FILE) $(MSGMERGE) - $(MSGMERGE) $(MSGMERGE_FLAGS) $< $(POT_FILE) - -msgmerge: $(MSGMERGE_GOALS) - -msgmerge-fuzzy: override MSGMERGE_FLAGS := --update --previous -msgmerge-fuzzy: $(MSGMERGE_GOALS) - -.PHONY: msgmerge $(MSGMERGE_GOALS) - -# ESLint - -ESLINT_CMD := node_modules/.bin/eslint -ESLINT_OPTS := -NPM_INSTALLED += $(ESLINT_CMD) - -lint/eslintrc-gjs.yml: - curl -o $@ 'https://gitlab.gnome.org/GNOME/gnome-shell/-/raw/39ed7f83fd97a5a3f688d77adb73e00fd24b7bfe/lint/eslintrc-gjs.yml' - -lint: $(ESLINT_CMD) lint/eslintrc-gjs.yml - $< $(ESLINT_OPTS) . - -.PHONY: lint -all: lint - -# Automagic 'npm install' - -NPM_INSTALL := yes - -ifeq ($(call is-true,$(NPM_INSTALL)),1) - -$(NPM_INSTALLED): node_modules/.package-lock.json -NPM := $(call find-tool,npm) - -node_modules/.package-lock.json: package.json package-lock.json $(NPM) - $(NPM) install - -npm: node_modules/.package-lock.json -.PHONY: npm - -endif - -# Various helpers - -prefs enable disable reset info show: - gnome-extensions $@ $(EXTENSION_UUID) - -.PHONY: prefs enable disable reset info show - -toggle quit begin-subscription-leak-check end-subscription-leak-check: - gapplication action com.github.amezin.ddterm $@ - -.PHONY: toggle quit begin-subscription-leak-check end-subscription-leak-check diff --git a/PKGBUILD b/PKGBUILD index 7a9a71350..2ce498e12 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -8,7 +8,7 @@ license=('GPL3') conflicts=('gnome-shell-extension-ddterm') provides=('gnome-shell-extension-ddterm') depends=('gjs' 'gtk3' 'vte3') -makedepends=('git' 'gtk4' 'libxslt') +makedepends=('meson' 'git' 'gtk4' 'libxslt') source=("$pkgname::git+file://$(git rev-parse --show-toplevel)") md5sums=('SKIP') @@ -18,11 +18,10 @@ pkgver() { } build() { - cd "$pkgname" - make build + arch-meson $pkgname build + meson compile -C build } package() { - cd "$pkgname" - make DESTDIR="$pkgdir/" install + meson install -C build --destdir "$pkgdir" } diff --git a/bin/com.github.amezin.ddterm b/bin/com.github.amezin.ddterm.in similarity index 78% rename from bin/com.github.amezin.ddterm rename to bin/com.github.amezin.ddterm.in index 1d078776d..bdbda2f3e 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..98810a284 --- /dev/null +++ b/ddterm/app/meson.build @@ -0,0 +1,41 @@ +app_js_files = files( + 'accellabel.js', + 'application.js', + 'appwindow.js', + 'dependencies.js', + 'extensiondbus.js', + 'gtktheme.js', + 'heapdump.js', + 'init.js', + 'main.js', + 'meta.js', + 'notebook.js', + 'pcre2.js', + 'prefsdialog.js', + 'resources.js', + 'search.js', + 'settings.js', + 'tablabel.js', + 'tcgetpgrp.js', + 'terminal.js', + 'terminalpage.js', + 'terminalsettings.js', + 'urldetect.js', + 'urldetect_patterns.js', + 'waitstatus.js' +) + +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..79d1d3008 --- /dev/null +++ b/ddterm/meson.build @@ -0,0 +1,60 @@ +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') + +pack += i18n.merge_file( + input: desktop_entry_untranslated, + output: '@BASENAME@', + po_dir: '../locale', + type: 'desktop', + install: true, + install_dir: extension_dir / 'ddterm', +) + +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..21175929d --- /dev/null +++ b/ddterm/pref/meson.build @@ -0,0 +1,31 @@ +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', +) + +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..c237f1481 --- /dev/null +++ b/ddterm/pref/ui/meson.build @@ -0,0 +1,32 @@ +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', +) + +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..26b0863c3 --- /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', + 'packagekit.js', + 'panelicon.js', + 'sd_journal.js', + 'service.js', + 'subprocess.js', + 'windowmatch.js', + 'wlclipboard.js', + 'wm.js', +) + +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/docs/Translations.md b/docs/Translations.md index b2d800d6d..af92b0d44 100644 --- a/docs/Translations.md +++ b/docs/Translations.md @@ -11,9 +11,8 @@ a pull request on GitHub. ## Other tools -CI system automatically upates `.pot` and `.po` files using -[`update-pot.sh`](/po/update-pot.sh) script, so there should be no need to run -it manually. +CI system automatically adds new strings to `.pot` and `.po` files, using +`msgmerge` build target. There should be no need to run it manually. You can add/edit a `.po` file with the tool of your choice and create a pull request. diff --git a/lint/meson.build b/lint/meson.build new file mode 100644 index 000000000..44fe8058e --- /dev/null +++ b/lint/meson.build @@ -0,0 +1,27 @@ +npm_tool = find_program('npm', required: false, disabler: true, native: true) + +npm_install_prefix = meson.current_build_dir() +npm_command = [npm_tool, '-C', npm_install_prefix] + +npm_project_files = [ + fs.copyfile(meson.project_source_root() / 'package.json'), + fs.copyfile(meson.project_source_root() / 'package-lock.json'), +] + +subdir('node_modules') + +eslint_command = [ + npm_command, 'exec', '--', 'eslint', '--resolve-plugins-relative-to', npm_install_prefix +] + +check_targets += run_target( + 'eslint', + command: [eslint_command, meson.project_source_root()], + depends: npm_install, +) + +run_target( + 'eslint-fix', + command: [eslint_command, '--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..485e733cb --- /dev/null +++ b/lint/node_modules/meson.build @@ -0,0 +1,6 @@ +npm_install = custom_target( + command: [npm_command, 'install'], + output: '.package-lock.json', + depends: npm_project_files, + console: true, +) diff --git a/locale b/locale new file mode 120000 index 000000000..1664e9e3b --- /dev/null +++ b/locale @@ -0,0 +1 @@ +po \ No newline at end of file diff --git a/meson.build b/meson.build new file mode 100644 index 000000000..34db289b6 --- /dev/null +++ b/meson.build @@ -0,0 +1,178 @@ +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 = [] +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 9fed1eaa5..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": 50, + "version": @version@, "url": "https://github.com/ddterm/gnome-shell-extension-ddterm" } diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 000000000..0ef2349be --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,35 @@ +ddterm/app/application.js +ddterm/app/appwindow.js +ddterm/app/dependencies.js +ddterm/app/menus.ui +ddterm/app/notebook.js +ddterm/app/prefsdialog.js +ddterm/app/search.js +ddterm/app/tablabel.js +ddterm/app/terminalpage.js +ddterm/com.github.amezin.ddterm.desktop.in.in +ddterm/pref/adw.js +ddterm/pref/animation.js +ddterm/pref/behavior.js +ddterm/pref/colors.js +ddterm/pref/command.js +ddterm/pref/compatibility.js +ddterm/pref/ui/prefs-animation.ui +ddterm/pref/ui/prefs-behavior.ui +ddterm/pref/ui/prefs-colors.ui +ddterm/pref/ui/prefs-command.ui +ddterm/pref/ui/prefs-compatibility.ui +ddterm/pref/ui/prefs-panel-icon.ui +ddterm/pref/ui/prefs-position-size.ui +ddterm/pref/ui/prefs-scrolling.ui +ddterm/pref/ui/prefs-shortcuts.ui +ddterm/pref/ui/prefs-tabs.ui +ddterm/pref/ui/prefs-text.ui +ddterm/pref/panelicon.js +ddterm/pref/positionsize.js +ddterm/pref/scrolling.js +ddterm/pref/shortcuts.js +ddterm/pref/tabs.js +ddterm/pref/text.js +ddterm/shell/notifications.js +ddterm/shell/panelicon.js diff --git a/po/gen-potfiles.py b/po/gen-potfiles.py new file mode 100755 index 000000000..d39475f65 --- /dev/null +++ b/po/gen-potfiles.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 + +import os.path +import subprocess + + +PATTERNS = [ + ':/**/*.js', + ':/**/*.ui', + ':/**/*.desktop.in', + ':/**/*.desktop.in.in', + # exclude, just in case + ':!/test/', + ':!/tools/', +] + + +def check_file_translatable(filename, xgettext='xgettext', xgettext_args=('--from-code=UTF-8',)): + argv = [xgettext, *xgettext_args, '-o-', filename] + return subprocess.check_output(argv).strip() != b'' + + +def all_git_files(git='git', chdir=os.curdir): + argv = [git, '-C', chdir, 'ls-files', '-z', '--deduplicate', '--full-name', '--'] + PATTERNS + + return [ + os.fsdecode(filename) + for filename in subprocess.check_output(argv).split(b'\0') + if filename + ] + + +def get_toplevel(git='git', chdir=os.curdir): + argv = [git, '-C', chdir, 'rev-parse', '--show-toplevel'] + return os.fsdecode(subprocess.check_output(argv).rstrip(b'\n')) + + +def gen(output, git='git', xgettext='xgettext', chdir=os.curdir, xgettext_args=('--from-code=UTF-8',)): + toplevel = get_toplevel(git=git, chdir=chdir) + + content = sorted( + filename + for filename in all_git_files(git=git, chdir=chdir) + if check_file_translatable(os.path.join(toplevel, filename), xgettext=xgettext, xgettext_args=xgettext_args) + ) + + print(f'# This file is generated by {os.path.basename(__file__)}, do not edit', file=output) + + for line in content: + print(line, file=output) + + +def cli(): + import argparse + parser = argparse.ArgumentParser() + parser.add_argument('-o', '--output', type=argparse.FileType('w')) + parser.add_argument('--git', default='git') + parser.add_argument('--xgettext', default='xgettext') + parser.add_argument('-C', dest='chdir', default=os.curdir) + parser.add_argument('xgettext_args', nargs='*', default=('--from-code=UTF-8',)) + + gen(**vars(parser.parse_args())) + + +if __name__ == '__main__': + cli() diff --git a/po/meson.build b/po/meson.build new file mode 100644 index 000000000..ba866c361 --- /dev/null +++ b/po/meson.build @@ -0,0 +1,41 @@ +gettext_args = [ + '--from-code=UTF-8', + '--add-comments', + '--check=ellipsis-unicode', + '--check=space-ellipsis', + '--check=bullet-unicode', + # TODO: '--check=quote-unicode', +] + +gettext_targets = i18n.gettext( + gettext_domain, + args: gettext_args, + install: true, + install_dir: extension_dir / 'locale' +) + +alias_target('locales', gettext_targets[0]) +alias_target('pot', gettext_targets[1]) +alias_target('msgmerge', gettext_targets[2]) + +pack += gettext_targets[0] + +xgettext = find_program('xgettext', native: true, disabler: true, required: false) +git = find_program('git', native: true, disabler: true, required: false) + +run_target( + 'potfiles', + command: [ + 'gen-potfiles.py', + '-C', + '@CURRENT_SOURCE_DIR@', + '--git', + git, + '--xgettext', + xgettext, + '-o', + '@CURRENT_SOURCE_DIR@' / 'POTFILES.in', + '--', + gettext_args + ] +) diff --git a/po/remove-potcdate.sin b/po/remove-potcdate.sin deleted file mode 100644 index 2436c49e7..000000000 --- a/po/remove-potcdate.sin +++ /dev/null @@ -1,19 +0,0 @@ -# Sed script that remove the POT-Creation-Date line in the header entry -# from a POT file. -# -# The distinction between the first and the following occurrences of the -# pattern is achieved by looking at the hold space. -/^"POT-Creation-Date: .*"$/{ -x -# Test if the hold space is empty. -s/P/P/ -ta -# Yes it was empty. First occurrence. Remove the line. -g -d -bb -:a -# The hold space was nonempty. Following occurrences. Do nothing. -x -:b -} 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()