diff --git a/.github/faketty.sh b/.github/faketty.sh new file mode 100755 index 000000000..330419215 --- /dev/null +++ b/.github/faketty.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +exec script -q -e -c "stty cols 80; $(printf "%q " "$@")" 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 d02d6ec80..2bc3ad0f1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,6 +27,7 @@ on: env: FORCE_COLOR: 1 PIP_DISABLE_PIP_VERSION_CHECK: 1 + TERM: xterm-color defaults: run: @@ -60,11 +61,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 @@ -90,14 +91,33 @@ jobs: run: echo "::add-matcher::.github/problem-matchers/generic.json" if: ${{ always() && steps.checkout.conclusion == 'success' }} - - name: Compile GSettings schemas - run: make schemas 2>&1 | tee schemas.log + - name: Upgrade Meson + run: | + # renovate: datasource=pypi depName=meson + MESON_VERSION=1.3.1 + pip3 install "meson==${MESON_VERSION}" if: ${{ always() && steps.checkout.conclusion == 'success' }} - - name: Validate Gtk .ui files - run: xvfb-run make gtk-builder-validate 2>&1 | tee gtk-builder.log + - id: meson-setup + name: Prepare build directory + run: .github/faketty.sh meson setup build if: ${{ always() && steps.checkout.conclusion == 'success' }} + - name: Run glib-compile-schemas checks + run: ../.github/faketty.sh meson test -v -j1 --no-rebuild --suite glib-compile-schemas --logbase glib-compile-schemas + working-directory: build + if: ${{ always() && steps.meson-setup.conclusion == 'success' }} + + - name: Run desktop-file-validate checks + run: ../.github/faketty.sh meson test -v -j1 --suite desktop-file-validate --logbase desktop-file-validate + working-directory: build + if: ${{ always() && steps.meson-setup.conclusion == 'success' }} + + - name: Run gtk-builder-validate checks + run: xvfb-run ../.github/faketty.sh meson test -v -j1 --suite gtk-builder-validate --logbase gtk-builder-validate + working-directory: build + if: ${{ always() && steps.meson-setup.conclusion == 'success' }} + - name: Ensure Python requirements .txt files are in sync with .in files run: | tox --sitepackages -e pip-compile @@ -115,36 +135,20 @@ jobs: if: ${{ always() && steps.checkout.conclusion == 'success' }} - name: Upload reports to Testspace - run: testspace --verbose eslint.xml "*.log{lint}" + run: testspace --verbose eslint.xml "*.log{lint}" "build/meson-logs/*.txt{lint}" if: ${{ always() && steps.setup_testspace.outcome == 'success' }} -<<<<<<< HEAD -======= - pack: - runs-on: ubuntu-latest - container: - image: ghcr.io/ddterm/ci-docker-image:meson - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - run: git config --global --replace-all safe.directory "$GITHUB_WORKSPACE" - - - name: Enable generic error matcher - run: echo "::add-matcher::.github/problem-matchers/generic.json" - ->>>>>>> 6b1304f ([WIP] Switch to meson docker image) - name: Build extension package id: pack - run: xvfb-run make pack - if: ${{ always() && steps.checkout.conclusion == 'success' }} + run: xvfb-run ninja -j1 pack + working-directory: build + if: ${{ always() && steps.meson-setup.conclusion == 'success' }} - 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 if: ${{ always() && steps.pack.conclusion == 'success' }} diff --git a/.github/workflows/check-po.yml b/.github/workflows/check-po.yml index 0f67d0fbc..655f110a1 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 defaults: run: @@ -27,7 +26,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 @@ -43,25 +42,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 - if: ${{ always() && steps.checkout.conclusion == 'success' }} + run: msgcmp --use-untranslated --use-fuzzy locale/${{ matrix.lang }}.po locale/*.pot + shell: bash + if: ${{ always() && steps.meson-setup.conclusion == 'success' }} diff --git a/.github/workflows/pot.yml b/.github/workflows/pot.yml index 880782287..87ce38597 100644 --- a/.github/workflows/pot.yml +++ b/.github/workflows/pot.yml @@ -1,20 +1,30 @@ -concurrency: - group: ${{ github.workflow }}/${{ github.ref }} - -name: pot - on: workflow_dispatch: + inputs: + commit: + description: Commit changes + required: false + default: false + type: boolean + workflow_call: - push: - branches: - - master - paths-ignore: - - docs/** - - po/*.po - - README.md - - Vagrantfile - - vagrant-provision/** + inputs: + commit: + description: Commit changes + required: false + default: false + type: boolean + secrets: + APP_ID: + description: 'ID of the committer application' + required: false + APP_KEY: + description: 'Private key of the committer application' + required: false + +env: + FORCE_COLOR: 1 + TERM: xterm-color jobs: pot: @@ -23,28 +33,31 @@ jobs: image: ghcr.io/ddterm/ci-docker-image:meson steps: - - name: Get app token - id: app-token - uses: actions/create-github-app-token@v1 - with: - app-id: ${{ secrets.APP_ID }} - private-key: ${{ secrets.APP_KEY }} - - name: Checkout uses: actions/checkout@v4 - with: - token: ${{ steps.app-token.outputs.token }} - run: git config --global --replace-all safe.directory "$GITHUB_WORKSPACE" - 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: .github/faketty.sh meson setup build + + - name: Update POTFILES.in + run: ninja -j1 potfiles + working-directory: build + + - name: Update .pot file + run: ninja -j1 msgmerge + working-directory: build + + - name: Update .po files + run: for pofile in *.po; do msgmerge --update --previous "$pofile" *.pot; done + working-directory: po - name: Stage changes - run: git add po/*.po po/*.pot + run: git add po/*.po po/*.pot po/POTFILES.in - name: Check if there are any changes id: diff @@ -52,12 +65,20 @@ 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: Get commit token + id: app-token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.APP_KEY }} + if: inputs.commit + - name: Commit uses: ddterm/github-api-commit-action@ccf9b520c5698380ad3b9619c5add427369b7ef1 - if: steps.diff.outputs.result != '' with: token: ${{ steps.app-token.outputs.token }} commit-message: 'Update translation files' + if: inputs.commit && steps.diff.outputs.result diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 28bf243af..c14b109fe 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -6,7 +6,10 @@ on: pull_request: paths-ignore: - docs/** - - po/** + - po/*.po + - po/*.pot + - po/POTFILES + - po/POTFILES.in - README.md - Vagrantfile - vagrant-provision/** @@ -24,3 +27,9 @@ jobs: test: needs: build uses: ./.github/workflows/test.yml + + translations: + uses: ./.github/workflows/pot.yml + with: + commit: false + secrets: inherit diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 429149d72..c8e45f76d 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -12,7 +12,10 @@ on: - v* paths-ignore: - docs/** - - po/** + - po/*.po + - po/*.pot + - po/POTFILES + - po/POTFILES.in - README.md - Vagrantfile - vagrant-provision/** @@ -26,3 +29,9 @@ jobs: test: needs: build uses: ./.github/workflows/test.yml + + translations: + uses: ./.github/workflows/pot.yml + with: + commit: ${{ github.ref_type == 'branch' && github.ref_name == github.event.repository.default_branch }} + secrets: inherit diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 19e9bcc6e..e627a915a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -46,7 +46,7 @@ jobs: - name: Check version matches the tag run: | - test "v$(jq .version metadata.json.in)" = "${{ github.event.release.tag_name }}" + test "v$(meson rewrite kwargs info project / 2>&1 | jq -r '.kwargs."project#/".version')" = "${{ github.event.release.tag_name }}" - name: Bump version run: | 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 a543893e6..000000000 --- a/Makefile +++ /dev/null @@ -1,491 +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 -LOCALE_SOURCE_PATTERN := po/%.po -LOCALES := $(shell grep -Ev '^\s*#.*' $(LINGUAS_FILE)) - -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 662821fb4..abb43ed55 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' 'xorg-server-xvfb') +makedepends=('meson' 'git' 'gtk4' 'libxslt' 'xorg-server-xvfb') source=("$pkgname::git+file://$(git rev-parse --show-toplevel)") md5sums=('SKIP') @@ -18,13 +18,12 @@ pkgver() { } build() { - cd "$pkgname" + arch-meson $pkgname build # gtk-builder-tool needs X or Wayland - LIBGL_ALWAYS_SOFTWARE=1 xvfb-run -- make build + LIBGL_ALWAYS_SOFTWARE=1 xvfb-run -- meson compile -C build } package() { - cd "$pkgname" - make DESTDIR="$pkgdir/" install + meson install -C build --destdir "$pkgdir" } diff --git a/Vagrantfile b/Vagrantfile index 9055f5a29..753d275e8 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -4,13 +4,15 @@ # See docs/Vagrant.md require 'open3' +require 'pathname' CPUS = 4 MEMORY = 2048 -PROJECT_DIR = File.dirname(File.expand_path(__FILE__)) -SYNCED_FOLDER = "/home/vagrant/#{File.basename(PROJECT_DIR)}" +PROJECT_DIR = Pathname.new(__FILE__).realpath.dirname +SYNCED_FOLDER = "/home/vagrant/#{PROJECT_DIR.basename}" UUID = 'ddterm@amezin.github.com' -PACK_FILE_NAME = "#{UUID}.shell-extension.zip" +PACK_FILE = ENV.fetch('DDTERM_BUILT_PACK', Pathname.getwd / "#{UUID}.shell-extension.zip") +PACK_FILE_NAME = PACK_FILE.basename stdout, status = Open3.capture2( 'git', @@ -55,8 +57,8 @@ Vagrant.configure("2") do |config| config.vm.provision 'copy', type: 'file', - source: PACK_FILE_NAME, - destination: '$HOME/', + source: PACK_FILE, + destination: "$HOME/#{PACK_FILE_NAME}", before: 'install', run: 'always' 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 a289e7c1b..964c239b9 100755 --- a/bump-version.sh +++ b/bump-version.sh @@ -4,14 +4,10 @@ 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 add metadata.json.in PKGBUILD +git add meson.build 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..96cabd877 --- /dev/null +++ b/ddterm/app/meson.build @@ -0,0 +1,49 @@ +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' +) + +app_ui_files = files( + 'menus.ui', +) + +foreach app_file : app_js_files + app_ui_files + files('dependencies.json', 'style.css') + pack += fs.copyfile( + app_file, + install: true, + install_dir: extension_dir / 'ddterm' / 'app', + ) +endforeach + +subdir('icons') + +foreach app_ui_file : app_ui_files + test( + fs.parent(app_ui_file) / fs.name(app_ui_file), + gtk3_builder_tool, + args: ['validate', app_ui_file], + suite: ['gtk-builder-validate'], + ) +endforeach diff --git a/ddterm/meson.build b/ddterm/meson.build new file mode 100644 index 000000000..166919f70 --- /dev/null +++ b/ddterm/meson.build @@ -0,0 +1,62 @@ +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') + +test( + desktop_entry_final.full_path(), + desktop_file_validate_tool, + args: [desktop_entry_final], + suite: ['desktop-file-validate'], +) 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..558765427 --- /dev/null +++ b/ddterm/pref/ui/gtk3/meson.build @@ -0,0 +1,22 @@ +pref_ui_gtk3_files = [] + +foreach pref_ui_file: pref_ui_files + out_file = 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', + ) + + test( + out_file.full_path(), + gtk3_builder_tool, + args: ['validate', out_file], + suite: ['gtk-builder-validate'], + ) + + pref_ui_gtk3_files += out_file +endforeach + +pack += pref_ui_gtk3_files 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..6283f4739 --- /dev/null +++ b/ddterm/pref/ui/gtk4/meson.build @@ -0,0 +1,31 @@ +gtk4_builder_tool = find_program('gtk4-builder-tool') +xsltproc = find_program('xsltproc') + +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', + ) + + out_file = 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', + ) + + pref_ui_gtk4_files += out_file + + test( + out_file.full_path(), + gtk4_builder_tool, + args: ['validate', out_file], + suite: ['gtk-builder-validate'], + ) +endforeach + +pack += pref_ui_gtk4_files diff --git a/ddterm/pref/ui/meson.build b/ddterm/pref/ui/meson.build new file mode 100644 index 000000000..2aefe6c7f --- /dev/null +++ b/ddterm/pref/ui/meson.build @@ -0,0 +1,25 @@ +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', +) + +foreach pref_ui_file: pref_ui_files + test( + fs.parent(pref_ui_file) / fs.name(pref_ui_file), + gtk3_builder_tool, + args: ['validate', pref_ui_file], + suite: ['gtk-builder-validate'], + ) +endforeach + +subdir('gtk3') +subdir('gtk4') 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/BUILD.md b/docs/BUILD.md index 6afb37a17..9680e9455 100644 --- a/docs/BUILD.md +++ b/docs/BUILD.md @@ -9,20 +9,15 @@ GitHub UI provides multiple options for downloading the source code as a `.zip` (or, sometimes, `.tar.gz`) archive - for releases, and arbitrary commits. -# 2. Working directory +# 2. Set up the build environment -`cd` into the source code directory. All the following commands should be run -there. - - $ cd gnome-shell-extension-ddterm - -# 3. Setup the build environment - -## 3.a) Install the necessary dependencies +## 2.a) Install the necessary dependencies To build the extension package, you should have the following tools installed: -- GNU `make` +- [Meson build system](https://mesonbuild.com/) - available as a package named +`meson` in multiple distributions. It automatically brings in a tool called +[`ninja`](https://ninja-build.org/) (package `ninja-build`) and Python 3. - `gtk-builder-tool` (`libgtk-3-bin` package on Ubuntu, `gtk3-devel` on Fedora, `gtk3` package on Arch) @@ -36,82 +31,92 @@ on Fedora, `gtk4` package on Arch) - `zip` -## 3.b) Build in a container +## 2.b) Build in a container Alternatively, you can use `docker` or `podman` to perform build steps in a container - the same image/environment that's used by the CI system. To do it, run build command with `./do-in-docker.sh` or `./do-in-podman.sh` wrapper: - $ ./do-in-docker.sh make pack + $ ./do-in-docker.sh meson setup build-dir + +# 3. Build the package + +To build the package, `cd` into the directory with the source code: -# 4. `make pack` + $ cd gnome-shell-extension-ddterm + +and run the following commands: -To build the package, run `make pack`: + $ meson setup build-dir + $ ninja -C build-dir pack - $ make pack +Meson puts all built/generated files into a separate directory, in this document +it will be `build-dir`. If you want to build in a docker/podman container, prepend `./do-in-docker.sh`/ `./do-in-podman.sh`: - $ ./do-in-docker.sh make pack + $ ./do-in-docker.sh meson setup build-dir + $ ./do-in-docker.sh ninja -C build-dir pack + +After these steps, you should have the package: +`build-dir/ddterm@amezin.github.com.shell-extension.zip`. -# 5. Install the package +If the process fails, please double-check that you have all the dependencies +(2.a) installed. + +# 4. Install the package The installation process is described in [INSTALL.md - continue from step 2](INSTALL.md#2-install-the-package). -Alternatively, you could use `make` to install the package too. +Alternatively, you could use `meson`/`ninja` to install the package too - +but only if you didn't use containers for the build. -## 5.1. `make install` +## 4.1.a) `meson install` -To install the package, run: +You should never run `meson install` with `./run-in-docker.sh` or +`./run-in-podman.sh`. If build has been performed in the container, +installation on the host system through `meson install` will fail. - $ make install +You may run `meson install` under `sudo` to install the package system-wide +(to `/usr/share/gnome-shell/extensions`): -You should never run `make install` with `./run-in-docker.sh` or -`./run-in-podman.sh`. You want the extension installed on your host system, not -in the container. + $ sudo meson install -C build-dir -You could run `make install` under `sudo` to install the package system-wide -(to `/usr/share/gnome-shell/extensions`): +Or, the same command with ninja: - $ sudo make install + $ ninja -C build-dir install + +Installed files can be removed with the following command: + + $ ninja -C build-dir uninstall However, `sudo` installation is not recommended. Instead, you should build and -use OS-specific packages (`.deb`, `.rpm`). `make DESTDIR=... install` should -work fine in DEB and RPM build scripts. +use OS-specific packages (`.deb`, `.rpm`). `meson install ... --destdir ...` +should work fine in DEB and RPM build scripts. See Arch Linux +[PKGBUILD](/PKGBUILD) for example. + +## 4.1.b) `user-install` -There are explicit targets for system-wide and user installation: +The following command builds the package, if necessary, and installs it +inside user's `$HOME` directory (i.e. typical install location for extensions): - $ make user-install - $ sudo make system-install + $ ninja -C build-dir user-install -`make install` just switches between them according to the current uid. +The extension can be uninstalled using the following command: -## 5.2. Restart GNOME Shell + $ ninja -C build-dir user-install + +## 4.2. Restart GNOME Shell Described in [INSTALL.md - step 3](INSTALL.md#3-restart-gnome-shell). -## 5.3. Enable the extension +## 4.3. Enable the extension You can enable the extension as described in [INSTALL.md - step 4](INSTALL.md#4-enable-the-extension), or by running: - $ make enable + $ ninja -C build-dir enable You'll have to perform this step only once. - -# `make develop` - -Instead of building and installing the package, you can simply symlink the -repository into GNOME Shell's extensions directory. `make develop` can do it -for you: - - $ git clone https://github.com/ddterm/gnome-shell-extension-ddterm.git - $ cd gnome-shell-extension-ddterm - $ make develop - -`make develop` replaces steps 5 and 6.1, but you still have to restart GNOME -Shell afterwards, and enable the extension if you didn't. - -`make develop` may be more convenient when you're developing/modifying the code. diff --git a/docs/Test.md b/docs/Test.md index 0d08842b4..4d14819ea 100644 --- a/docs/Test.md +++ b/docs/Test.md @@ -28,11 +28,20 @@ Or to do both at the same time: ### Run tests - $ tox [--sitepackages] -- + $ tox [--sitepackages] -- [--pack=path] -Without `--sitepackages` you'll have to install PyGObject's build dependencies. +Before running tests, you need to [build the extension package](/docs/BUILD.md). -Options: +You either have to specify: + + `--pack=path/to/built/ddterm@amezin.github.com.shell-extension.zip` + +or run tox from `meson devenv -C build-dir` shell. + +Without `--sitepackages` you'll have to install PyGObject's build dependencies, +and PyGObject will be automatically built from source by `tox`. + +#### Other options: `--image=IMAGE` - run tests using the specified container image `IMAGE`. Can be repeated multiple times to run tests with multiple images. @@ -43,8 +52,6 @@ with multiple images. `--screenshot-failing-only` - capture screenshots only for failing tests. -`--pack=PACK` - install ddterm from the specified `PACK` package file. - `-n numprocesses` - run `numprocesses` parallel test processes. If no options are specified, reasonable defaults are used. 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/docs/Vagrant.md b/docs/Vagrant.md index 7dcca774c..fe37f8cbf 100644 --- a/docs/Vagrant.md +++ b/docs/Vagrant.md @@ -16,14 +16,20 @@ QEMU/libvirt VMs use SPICE for display. So you'll have to install ddterm will be installed into the VM from the extension package. So if you haven't built the package yet, you'll need to do so: - $ make pack + $ meson setup build-dir + $ ninja -C build-dir pack Then: - $ vagrant up fedora39 + $ meson devenv -C build-dir -w . vagrant up fedora39 will start Fedora 39 VM, and will install ddterm into the VM. +Instead of prefixing `vagrant` command with `meson devenv ...` every time, +it's possible to just run `meson devenv -C build-dir` once. It will start a new +shell with all necessary environment variables, and raw `vagrant` commands will +work in that shell without additional setup. + Then connect to the VM using `virt-manager`. VMs are started in user session, so if you can't find the VM in `virt-manager`, click `File`->`Add Connection...`, choose `QEMU/KVM user session`, click `Connect`. @@ -36,11 +42,11 @@ session by default. If you've made some changes to ddterm sources, and want to test them, rebuild the package: - $ make pack + $ ninja -C build-dir pack and reinstall it: - $ vagrant provision fedora39 + $ meson devenv -C build-dir -w . vagrant provision fedora39 GNOME Shell session in the VM will automatically be terminated, you'll have to login again - because GNOME Shell can't reload extensions without a complete 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..72e11eecb --- /dev/null +++ b/meson.build @@ -0,0 +1,186 @@ +project( + 'ddterm', + version : '50', + meson_version : '>= 1.0.0', + license : 'GPL3+', + default_options : ['prefix=/usr'] +) + +gjs = find_program('gjs', version: '>=1.78.0') + +fs = import('fs') +i18n = import('i18n') + +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 = [] + +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, +) + +output_capture = ['sh', '-c', 'exec >"$0" "$@"', '@OUTPUT@'] +need_git_version = fs.read('revision.txt.in').strip() == '$Format:%H$' + +git = find_program('git', disabler: true, required: need_git_version) + +if need_git_version + 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_config = configuration_data() +gjs_config.set('GJS', gjs.full_path()) + +gtk3_builder_tool = find_program('gtk-builder-tool') + +subdir('bin') +subdir('schemas') +subdir('ddterm') +subdir('locale') + +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) + +meson.add_devenv({'DDTERM_BUILT_PACK': pack_target.full_path()}) + +extensions_tool = find_program('gnome-extensions', required: false, disabler: 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', + required: false, + disabler: true, +) + +foreach target: ['toggle', 'quit'] + run_target(target, command: [gapplication_tool, 'action', 'com.github.amezin.ddterm', target]) +endforeach + +npm_tool = find_program('npm', required: false, disabler: true) + +if meson.version().version_compare('>=1.3.0') + ignore_dir = fs.relative_to( + meson.current_build_dir(), + meson.current_source_dir(), + ) +else + ignore_dir = run_command( + 'python3', + '-c', + 'import os.path; import sys; print(os.path.relpath(*sys.argv[1:]))', + meson.current_build_dir(), + meson.current_source_dir(), + capture: true, + check: true, + ).stdout().strip() +endif + +npm_install_stamp = meson.current_build_dir() / 'npm-install' +npm_env = {'DDTERM_POST_INSTALL_STAMP': npm_install_stamp} +meson.add_devenv(npm_env) + +npm_install = custom_target( + command: [npm_tool, '-C', '@CURRENT_SOURCE_DIR@', 'install'], + output: fs.name(npm_install_stamp), + depend_files: files('package.json', 'package-lock.json'), + console: true, + env: npm_env, +) + +eslint_extra_args = ['--ignore-pattern', ignore_dir] + +run_target( + 'eslint', + command: [npm_tool, '-C', '@CURRENT_SOURCE_DIR@', 'run-script', '--', 'lint'] + eslint_extra_args, + depends: npm_install, +) + +run_target( + 'eslint-fix', + command: [npm_tool, '-C', '@CURRENT_SOURCE_DIR@', 'run-script', '--', 'lint:fix'] + eslint_extra_args, + depends: npm_install, +) + +test( + 'eslint', + npm_tool, + args: ['run-script', '--', 'lint'] + eslint_extra_args, + depends: npm_install, + workdir: meson.current_source_dir(), + suite: ['eslint'], +) 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/package-lock.json b/package-lock.json index d53a0c126..dd28ab7e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,7 @@ "packages": { "": { "name": "gnome-shell-extension-ddterm", + "hasInstallScript": true, "devDependencies": { "eslint": "8.56.0", "eslint-formatter-checkstyle": "^8.40.0", diff --git a/package.json b/package.json index d9a7253f8..8dc5d8e2e 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ }, "scripts": { "lint": "eslint .", - "lint:fix": "eslint --fix ." + "lint:fix": "eslint --fix .", + "postinstall": "if [ -n \"$DDTERM_POST_INSTALL_STAMP\" ]; then touch \"$DDTERM_POST_INSTALL_STAMP\"; fi" } } 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..6e4ae5c52 --- /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..6c2321ae7 --- /dev/null +++ b/po/meson.build @@ -0,0 +1,40 @@ +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', 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/renovate.json b/renovate.json index 18e7f4135..0a11b854b 100644 --- a/renovate.json +++ b/renovate.json @@ -12,7 +12,7 @@ }, "regexManagers": [ { - "fileMatch": [".+\\.sh$"], + "fileMatch": [".+\\.sh$", "^\\.github/workflows/.+\\.ya?ml"], "matchStrings": [ "#\\s*renovate:\\s+datasource=(?[^\\s]+)\\s+depName=(?[^\\s]+)(\\s+(lookupName|packageName)=(?[^\\s]+))?(\\s+versioning=(?[^\\s]+))?\\n\\s*\\w+=[\"']?(?[^\\s\"']+)[\"']?(\\s|$)" ] diff --git a/schemas/meson.build b/schemas/meson.build new file mode 100644 index 000000000..2f0dfe006 --- /dev/null +++ b/schemas/meson.build @@ -0,0 +1,31 @@ +schema = files(f'@settings_schema@.gschema.xml') + +glib_compile_schemas_tool = find_program('glib-compile-schemas') + +schemas_compiled = custom_target( + command: [ + glib_compile_schemas_tool, + '--strict', + '--targetdir=@OUTDIR@', + '@CURRENT_SOURCE_DIR@' + ], + input: schema, + output: 'gschemas.compiled', +) + +test( + fs.parent(schema) / fs.name(schema), + glib_compile_schemas_tool, + args: ['--strict', '--dry-run', meson.current_source_dir()], + suite: ['glib-compile-schemas'], +) + +schema_copy = fs.copyfile( + schema, + install: true, + install_dir: schema_dir +) + +pack += schema_copy + +meson.add_install_script(glib_compile_schemas_tool, schema_dir, skip_if_destdir: true) diff --git a/test/conftest.py b/test/conftest.py index d2b1d1877..4f8fb667d 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -1,4 +1,5 @@ import json +import os import pathlib import re import subprocess @@ -37,10 +38,7 @@ def container_image(request): @pytest.fixture(scope='session') def extension_pack(request): - pack = request.config.getoption('--pack') - - if pack: - return pack.resolve() + return request.config.getoption('--pack').resolve() def pytest_addoption(parser): @@ -67,11 +65,14 @@ def pytest_addoption(parser): help='podman command/executable path' ) + pack_from_env = os.getenv('DDTERM_BUILT_PACK') + parser.addoption( '--pack', - default=None, + default=pathlib.Path(pack_from_env) if pack_from_env else None, + required=not pack_from_env, type=pathlib.Path, - help='install ddterm from the specified package file' + help='built ddterm extension package (ddterm@amezin.github.com.shell-extension.zip)', ) @@ -133,13 +134,8 @@ def syslog_server(tmp_path_factory, log_sync): @pytest.fixture(scope='session') def ddterm_metadata(extension_pack): - if extension_pack: - with zipfile.ZipFile(extension_pack) as z: - with z.open('metadata.json') as f: - return json.load(f) - - else: - with open(SRC_DIR / 'metadata.json', 'r') as f: + with zipfile.ZipFile(extension_pack) as z: + with z.open('metadata.json') as f: return json.load(f) @@ -157,11 +153,7 @@ def container_create_lock(request): @pytest.fixture(scope='session') def container_volumes(ddterm_metadata, test_metadata, extension_pack, tmp_path_factory): sys_install_dir = gnome_container.GnomeContainer.extensions_system_install_path() - - if extension_pack: - install_mount = (extension_pack, extension_pack, 'ro') - else: - install_mount = (SRC_DIR, sys_install_dir / ddterm_metadata['uuid'], 'ro') + install_mount = (extension_pack, extension_pack, 'ro') basetemp = tmp_path_factory.getbasetemp() basetemp.chmod(0o777) diff --git a/test/ddterm_fixtures.py b/test/ddterm_fixtures.py index 06608d7d3..5363e9cfb 100644 --- a/test/ddterm_fixtures.py +++ b/test/ddterm_fixtures.py @@ -28,9 +28,7 @@ def configure_session(self, container, request): super().configure_session(container, request) extension_pack = request.getfixturevalue('extension_pack') - - if extension_pack: - container.install_extension(extension_pack, timeout=self.START_STOP_TIMEOUT_SEC) + container.install_extension(extension_pack, timeout=self.START_STOP_TIMEOUT_SEC) @pytest.fixture(scope='class') def enable_ddterm_extension(self, shell_dbus_api, ddterm_metadata): diff --git a/test/tox.ini b/test/tox.ini index 3ac3dc946..a818e26fc 100644 --- a/test/tox.ini +++ b/test/tox.ini @@ -8,6 +8,7 @@ passenv = FORCE_COLOR GITHUB_ACTIONS PIP_DISABLE_PIP_VERSION_CHECK + DDTERM_BUILT_PACK deps = -r requirements.txt 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()