From 3907fe3863c273669f647fab54db1f9f8aa390b1 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Fri, 16 Dec 2022 12:52:22 +0700 Subject: [PATCH 01/19] chore(common/resources): Add Docker readme --- docs/websites/README.md | 113 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 docs/websites/README.md diff --git a/docs/websites/README.md b/docs/websites/README.md new file mode 100644 index 0000000000..caa3397286 --- /dev/null +++ b/docs/websites/README.md @@ -0,0 +1,113 @@ +# How to Set Up a Local Web Server for the Keyman Web Pages + +Currently, most of the Keyman websites are running via IIS. Refer to the Keyman [wiki](https://github.com/keymanapp/keyman/wiki/How-to-set-up-a-local-web-server-for-the-Keyman-web-pages) for setting that up on Windows 10. + +To make IIS redirects compatible with the Docker sites below, see +https://github.com/keymanapp/keyman.com/issues/337#issuecomment-1336339387 + +As the websites get migrated to Apache via Docker, follow the installation steps below: + +## Pre-requisite Installs +* [Docker Desktop](https://www.docker.com/products/docker-desktop/) + +On Windows, Docker will need either: +* Hyper-V or +* WSL 2.0 - Install with this guide: +https://learn.microsoft.com/en-us/windows/wsl/tutorials/wsl-containers + * WSL will then need a Linux image (e.g. Ubuntu app) from the Microsoft Store + +#### Other Docker Notes +Docker tends to throttle Docker image downloads, so some developer offices may want to set up a proxy server. If the proxy server is set up, carefully edit the JSON file per in Docker Settings -> Docker Engine https://docs.docker.com/registry/recipes/mirror/#configure-the-docker-daemon and click 'Apply & Restart'. Note the example (lingnet) is for running inside the Linguistics Institute (Chiang Mai) + +``` + "registry-mirrors": ["https://docker.io.registry.lingnet/"], + "insecure-registries" : [ + "docker.io.registry.lingnet", + "registry.lingnet" + ] +``` + + +### These pre-reqs are still needed but will be removed in keymanapp/help.keyman.com#674 +* PHP 7.4 +* Composer + +## Builder BASH Script Actions + +#### Configure +Installs PHP dependencies in vendor/ folder. This step will be removed in keymanapp/help.keyman.com#674 +1. Run `./build.sh configure`. + +#### Stop the Docker container +1. Run `./build.sh stop` + +#### Build the Docker image +1. Run `./build.sh build`. + +#### Start the Docker container +1. Run `./build.sh start`. + +After this, you can access the website at the following ports: + +| Website | URL | +|------------|-----| +|help.keyman | http://localhost:8055 | + + +#### Remove the Docker container and image +1. Run `./build.sh clean`. + +#### Running tests +Checks for broken links +1. Run `./build.sh test` + +--------- + +## Kubernetes Deployment +For production, the websites are deployed with Kubernetes. + + +### How to run help.keyman.com locally with Docker Desktop's Kubernetes singlenode cluster + +For testing Kubernetes deployment, there are yaml files under the corresponding website's repo: `/resources/kubectl`, that cover local developer testing. + +### Pre-requisites +On the host machine, install [Docker](https://docs.docker.com/get-docker/), then enable Kubernetes in the settings. Ensure you have built a help-keyman-app Docker image, and either tag it `docker.dallas.languagetechnology.org/keyman/help-keyman-app` or modify the `app-php` containers `image:` value to match you local copy's name. + +### Deploying to a desktop cluster +To deploy the dev version to the cluster do the following: +1. Ensure your `kubectl` context is set to `docker-desktop`, though the Docker Desktop systray icon or by running: +```bash +$> kubectl config use-context docker-desktop +``` +2. Create a keyman namespace if it does not already exist: +```bash +$> kubectl create ns keyman +``` +3. Apply the configs for the resources and start the pod: +```bash +$> kubectl --namespace keyman apply \ + -f resources/kubectl/help-kubectl-dev.yaml \ + -f resources/kubectl/help-kubectl.yaml +``` +### Testing the site and `/api/deploy` webhook endpoint +The site can be reached on http://localhost:30080/ via web browser, and the deploy api is on http://localhost:30900/api/deploy, and can be activated like so: +```bash +$> curl -v --request POST \ + -H "Content-Type: application/json" \ + -H "X-Hub-Signature-256: sha256=49af8531106a369bfee369f91dadec597e8ea3992ec2802bbe655be0ece17f15" \ + --data '{"action":"push","ref":"refs/heads/staging"}' \ + http://localhost:30900/api/deploy +``` +This simulates enough of a GitHub webhook push event to pass validation on the responder. + +### Clean up after testing + +To remove the k8s pod and resources, and delete everything do: +```bash +$> kubectl --namespace=keyman delete {pod,cm,svc,secret,pvc}/help-keyman-com +``` +Or just delete the pod and keep the resources for further testing: +```bash +$> kubectl --namespace=keyman delete pod/help-keyman-com +``` From 16067a36fdbf0c7c20ce705a876cbbf52e931efe Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Fri, 6 Jan 2023 18:49:55 +0100 Subject: [PATCH 02/19] chore(linux): Remove unnecessary variable We can directly use `logging.error` instead of `logging.log`. Then we don't need the `severity` variable. --- linux/keyman-config/keyman_config/handle_install.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/linux/keyman-config/keyman_config/handle_install.py b/linux/keyman-config/keyman_config/handle_install.py index a6fccc0179..4938f23d41 100644 --- a/linux/keyman-config/keyman_config/handle_install.py +++ b/linux/keyman-config/keyman_config/handle_install.py @@ -20,7 +20,6 @@ def download_and_install_package(url): """ parsedUrl = urlparse(url) bcp47 = _extract_bcp47(parsedUrl.query) - severity = logging.ERROR if parsedUrl.scheme == 'keyman': logging.info("downloading " + url) @@ -49,7 +48,7 @@ def download_and_install_package(url): return if packageFile and not _install_package(packageFile, bcp47): - logging.log(severity, "Can't find file " + url) + logging.error("Can't find file " + url) def _extract_bcp47(query): From eb5d6bc37b388740d6a61c1bfa3f4e67d1b406f8 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Fri, 6 Jan 2023 13:19:43 -0500 Subject: [PATCH 03/19] auto: increment master version to 17.0.25 --- HISTORY.md | 4 ++++ VERSION.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index eec093d169..38de14bd1f 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,9 @@ # Keyman Version History +## 17.0.24 alpha 2023-01-06 + +* chore(common/resources): Add Docker readme (#7980) + ## 17.0.23 alpha 2023-01-03 * fix(linux): add IBUS_HAS_PREFILTER ifdef to linux/ibus-keyman/tests (#7958) diff --git a/VERSION.md b/VERSION.md index 0269c93878..12d2fb91a0 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -17.0.24 \ No newline at end of file +17.0.25 \ No newline at end of file From fb58ddd04a46c3f98a743f99973c456bf46b1a81 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Mon, 9 Jan 2023 14:46:17 +0100 Subject: [PATCH 04/19] feat(linux): Add Back button to "Download Keyman Keyboards" dialog Fixes #4828 --- .../keyman_config/downloadkeyboard.py | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/linux/keyman-config/keyman_config/downloadkeyboard.py b/linux/keyman-config/keyman_config/downloadkeyboard.py index d79b1e3d44..50edc34de1 100755 --- a/linux/keyman-config/keyman_config/downloadkeyboard.py +++ b/linux/keyman-config/keyman_config/downloadkeyboard.py @@ -30,13 +30,26 @@ class DownloadKmpWindow(Gtk.Dialog): s = Gtk.ScrolledWindow() self.webview = WebKit2.WebView() self.webview.connect("decide-policy", self._keyman_policy) + self.webview.connect("load-changed", self._update_back_button) url = KeymanComUrl + "/go/linux/" + __releaseversion__ + "/download-keyboards" self.webview.load_uri(url) s.add(self.webview) self.get_content_area().pack_start(s, True, True, 0) - self.add_button(_("_Close"), Gtk.ResponseType.CLOSE) + hbox = Gtk.Box(spacing=6) + self.get_content_area().pack_start(hbox, False, False, 0) + + self.back_button = Gtk.Button.new_with_mnemonic(_("_Back")) + self.back_button.set_tooltip_text(_("Back to search")) + self.back_button.connect("clicked", self._on_back_clicked) + self.back_button.set_sensitive(False) + hbox.pack_start(self.back_button, False, False, 0) + + close_button = Gtk.Button.new_with_mnemonic(_("_Close")) + close_button.set_tooltip_text(_("Close dialog")) + close_button.connect("clicked", self._on_close_clicked) + hbox.pack_end(close_button, False, False, 0) if self.parentWindow is not None: self.getinfo = GetInfo(self.parentWindow.incomplete_kmp) @@ -44,6 +57,15 @@ class DownloadKmpWindow(Gtk.Dialog): self.resize(800, 450) self.show_all() + def _update_back_button(self, webview, load_event): + self.back_button.set_sensitive(webview.can_go_back()) + + def _on_back_clicked(self, button): + self.webview.go_back() + + def _on_close_clicked(self, button): + self.response(Gtk.ResponseType.CLOSE) + def _process_kmp(self, url, downloadfile: str): logging.info("Downloading kmp file to %s", downloadfile) if download_kmp_file(url, downloadfile): From d54beee0ab792e71441de36471c8195c6e1f6ac3 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Mon, 9 Jan 2023 15:52:15 +0100 Subject: [PATCH 05/19] feat(linux): List fonts in the uninstall confirmation dialog Fixes #3501 --- .../keyman_config/kmpmetadata.py | 1 - .../keyman_config/view_installed.py | 30 +++++++++++++++---- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/linux/keyman-config/keyman_config/kmpmetadata.py b/linux/keyman-config/keyman_config/kmpmetadata.py index 83351d5172..4632531e75 100755 --- a/linux/keyman-config/keyman_config/kmpmetadata.py +++ b/linux/keyman-config/keyman_config/kmpmetadata.py @@ -506,7 +506,6 @@ def get_metadata(tmpdirname): If it does not exist then will return get_and_convert_infdata Args: - inputfile (str): path to kmp file tmpdirname(str): temp directory to extract kmp Returns: diff --git a/linux/keyman-config/keyman_config/view_installed.py b/linux/keyman-config/keyman_config/view_installed.py index 959c0196d9..f1aabe5dbb 100755 --- a/linux/keyman-config/keyman_config/view_installed.py +++ b/linux/keyman-config/keyman_config/view_installed.py @@ -22,6 +22,7 @@ from keyman_config.get_kmp import (InstallLocation, get_keyboard_dir, get_keyman_dir) from keyman_config.install_window import InstallKmpWindow, find_keyman_image from keyman_config.keyboard_details import KeyboardDetailsView +from keyman_config.kmpmetadata import get_fonts, parsemetadata from keyman_config.list_installed_kmp import get_installed_kmp from keyman_config.options import OptionsView from keyman_config.uninstall_kmp import uninstall_kmp @@ -351,12 +352,29 @@ class ViewInstalledWindow(ViewInstalledWindowBase): model, treeiter = self.tree.get_selection().get_selected() if treeiter is not None: logging.info("Uninstall keyboard " + model[treeiter][3] + "?") - dialog = Gtk.MessageDialog( - self, 0, Gtk.MessageType.QUESTION, - Gtk.ButtonsType.YES_NO, _("Uninstall keyboard package?")) - dialog.format_secondary_text( - _("Are you sure that you want to uninstall the {keyboard} keyboard and its fonts?") - .format(keyboard=model[treeiter][1])) + dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, + _("Uninstall keyboard package?")) + msg = _("Are you sure that you want to uninstall the {keyboard} keyboard?").format( + keyboard=model[treeiter][1]) + kbdir = get_keyboard_dir(InstallLocation.User, model[treeiter][3]) + kmpjson = os.path.join(kbdir, "kmp.json") + if os.path.isfile(kmpjson): + info, system, options, keyboards, files = parsemetadata(kmpjson, False) + fonts = get_fonts(files) + if fonts: + # Fonts are optional + fontlist = "" + for font in fonts: + if 'description' in font: + if fontlist != "": + fontlist = fontlist + "\n" + if font['description'][:5] == "Font ": + fontdesc = font['description'][5:] + else: + fontdesc = font['description'] + fontlist = fontlist + fontdesc + msg += "\n\n" + _("The following fonts will also be uninstalled:\n") + fontlist + dialog.format_secondary_text(msg) response = dialog.run() dialog.destroy() if response == Gtk.ResponseType.YES: From 702a96aec0ddab31132d72ca6318fce68c4a8b18 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Mon, 9 Jan 2023 13:01:52 -0500 Subject: [PATCH 06/19] auto: increment master version to 17.0.26 --- HISTORY.md | 4 ++++ VERSION.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 38de14bd1f..8c6eaf6acf 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,9 @@ # Keyman Version History +## 17.0.25 alpha 2023-01-09 + +* chore(linux): Remove unnecessary variable (#7988) + ## 17.0.24 alpha 2023-01-06 * chore(common/resources): Add Docker readme (#7980) diff --git a/VERSION.md b/VERSION.md index 12d2fb91a0..9663c46b83 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -17.0.25 \ No newline at end of file +17.0.26 \ No newline at end of file From 7df84301b0e5121f196c54446b5f1501075a0b86 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Tue, 10 Jan 2023 10:46:37 +0100 Subject: [PATCH 07/19] chore(linux): Refactor completion script --- linux/keyman-config/km-package-get.bash-completion | 7 ++++--- linux/keyman-config/km-package-install.bash-completion | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/linux/keyman-config/km-package-get.bash-completion b/linux/keyman-config/km-package-get.bash-completion index 9a1d5ac3aa..5faec47e0f 100644 --- a/linux/keyman-config/km-package-get.bash-completion +++ b/linux/keyman-config/km-package-get.bash-completion @@ -2,7 +2,7 @@ _km-package-get_completions() { - local cur prev opts cache + local cur prev opts cache pkg_install_path COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" @@ -21,10 +21,11 @@ _km-package-get_completions() # Unfortunately with bash completion scripts it's not possible to factor out # common code. if [[ -e ./km-package-install ]]; then - python3 -c "from importlib.machinery import SourceFileLoader;from importlib.util import module_from_spec, spec_from_loader;loader = SourceFileLoader('km_package_install', './km-package-install');spec = spec_from_loader(loader.name, loader);mod = module_from_spec(spec);loader.exec_module(mod);mod.list_keyboards()" + pkg_install_path='./km-package-install' else - python3 -c "from importlib.machinery import SourceFileLoader;from importlib.util import module_from_spec, spec_from_loader;loader = SourceFileLoader('km_package_install', '/usr/bin/km-package-install');spec = spec_from_loader(loader.name, loader);mod = module_from_spec(spec);loader.exec_module(mod);mod.list_keyboards()" + pkg_install_path='/usr/bin/km-package-install' fi + python3 -c "from importlib.machinery import SourceFileLoader;from importlib.util import module_from_spec, spec_from_loader;loader = SourceFileLoader('km_package_install', pkg_install_path);spec = spec_from_loader(loader.name, loader);mod = module_from_spec(spec);loader.exec_module(mod);mod.list_keyboards()" fi if [[ -r $cache ]] ; then diff --git a/linux/keyman-config/km-package-install.bash-completion b/linux/keyman-config/km-package-install.bash-completion index 768ea26bb2..5fbd340934 100644 --- a/linux/keyman-config/km-package-install.bash-completion +++ b/linux/keyman-config/km-package-install.bash-completion @@ -2,7 +2,7 @@ _km-package-install_completions() { - local cur prev opts cache + local cur prev opts cache pkg_install_path COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" @@ -23,10 +23,11 @@ _km-package-install_completions() # Unfortunately with bash completion scripts it's not possible to factor out # common code. if [[ -e ./km-package-install ]]; then - python3 -c "from importlib.machinery import SourceFileLoader;from importlib.util import module_from_spec, spec_from_loader;loader = SourceFileLoader('km_package_install', './km-package-install');spec = spec_from_loader(loader.name, loader);mod = module_from_spec(spec);loader.exec_module(mod);mod.list_keyboards()" + pkg_install_path='./km-package-install' else - python3 -c "from importlib.machinery import SourceFileLoader;from importlib.util import module_from_spec, spec_from_loader;loader = SourceFileLoader('km_package_install', '/usr/bin/km-package-install');spec = spec_from_loader(loader.name, loader);mod = module_from_spec(spec);loader.exec_module(mod);mod.list_keyboards()" + pkg_install_path='/usr/bin/km-package-install' fi + python3 -c "from importlib.machinery import SourceFileLoader;from importlib.util import module_from_spec, spec_from_loader;loader = SourceFileLoader('km_package_install', pkg_install_path);spec = spec_from_loader(loader.name, loader);mod = module_from_spec(spec);loader.exec_module(mod);mod.list_keyboards()" fi if [[ -r $cache ]] ; then From c9fad367f8bdbd89e3b389bb8b48d7cb22bdb50b Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Tue, 10 Jan 2023 11:40:12 +0100 Subject: [PATCH 08/19] chore(linux): Fix shellcheck warnings --- .../keyman-config/km-package-get.bash-completion | 15 ++++++++------- .../km-package-install.bash-completion | 15 +++++++++------ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/linux/keyman-config/km-package-get.bash-completion b/linux/keyman-config/km-package-get.bash-completion index 5faec47e0f..9bacb1b8fe 100644 --- a/linux/keyman-config/km-package-get.bash-completion +++ b/linux/keyman-config/km-package-get.bash-completion @@ -1,17 +1,17 @@ -#/usr/bin/env bash +#!/usr/bin/env bash _km-package-get_completions() { - local cur prev opts cache pkg_install_path + local cur opts cache pkg_install_path COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" - prev="${COMP_WORDS[COMP_CWORD-1]}" opts="-h --help -v --verbose -vv --veryverbose --version" cache=${XDG_CACHE_HOME:-~/.cache}/keyman/kmpdirlist if [[ ${cur} == -* ]] ; then - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + # shellcheck disable=SC2207 + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 fi @@ -25,12 +25,13 @@ _km-package-get_completions() else pkg_install_path='/usr/bin/km-package-install' fi - python3 -c "from importlib.machinery import SourceFileLoader;from importlib.util import module_from_spec, spec_from_loader;loader = SourceFileLoader('km_package_install', pkg_install_path);spec = spec_from_loader(loader.name, loader);mod = module_from_spec(spec);loader.exec_module(mod);mod.list_keyboards()" + python3 -c "from importlib.machinery import SourceFileLoader;from importlib.util import module_from_spec, spec_from_loader;loader = SourceFileLoader('km_package_install', $pkg_install_path);spec = spec_from_loader(loader.name, loader);mod = module_from_spec(spec);loader.exec_module(mod);mod.list_keyboards()" fi if [[ -r $cache ]] ; then - for file in `cat $cache`; do words="${words} ${file}"; done - COMPREPLY=($(compgen -W "${words}" -- ${cur})) + while read -r file; do words="${words} ${file}"; done < "$cache" + # shellcheck disable=SC2207 + COMPREPLY=($(compgen -W "${words}" -- "${cur}")) return 0 fi } diff --git a/linux/keyman-config/km-package-install.bash-completion b/linux/keyman-config/km-package-install.bash-completion index 5fbd340934..091e4f64ec 100644 --- a/linux/keyman-config/km-package-install.bash-completion +++ b/linux/keyman-config/km-package-install.bash-completion @@ -1,4 +1,4 @@ -#/usr/bin/env bash +#!/usr/bin/env bash _km-package-install_completions() { @@ -11,7 +11,8 @@ _km-package-install_completions() cache=${XDG_CACHE_HOME:-~/.cache}/keyman/kmpdirlist if [[ ${cur} == -* ]] ; then - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + # shellcheck disable=SC2207 + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 fi @@ -27,19 +28,21 @@ _km-package-install_completions() else pkg_install_path='/usr/bin/km-package-install' fi - python3 -c "from importlib.machinery import SourceFileLoader;from importlib.util import module_from_spec, spec_from_loader;loader = SourceFileLoader('km_package_install', pkg_install_path);spec = spec_from_loader(loader.name, loader);mod = module_from_spec(spec);loader.exec_module(mod);mod.list_keyboards()" + python3 -c "from importlib.machinery import SourceFileLoader;from importlib.util import module_from_spec, spec_from_loader;loader = SourceFileLoader('km_package_install', $pkg_install_path);spec = spec_from_loader(loader.name, loader);mod = module_from_spec(spec);loader.exec_module(mod);mod.list_keyboards()" fi if [[ -r $cache ]] ; then - for file in `cat $cache`; do words="${words} ${file}"; done - COMPREPLY=($(compgen -W "${words}" -- ${cur})) + while read -r file; do words="${words} ${file}"; done < "$cache" + # shellcheck disable=SC2207 + COMPREPLY=($(compgen -W "${words}" -- "${cur}")) return 0 fi ;; "-f"|"--file") local IFS=$'\n' compopt -o filenames - COMPREPLY=( $(compgen -f -X "!"*.kmp -- $cur) $(compgen -d -- $cur) ) + # shellcheck disable=SC2207 + COMPREPLY=( $(compgen -f -X "!"*.kmp -- "$cur") $(compgen -d -- "$cur") ) return 0 ;; *) From c5938fab8ec4ba8a3df308211db858d6c23ff648 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Tue, 10 Jan 2023 12:29:45 +0100 Subject: [PATCH 09/19] chore(linux): Fix more warnings --- linux/keyman-config/km-config.bash-completion | 12 +++++++----- linux/keyman-config/km-kvk2ldml.bash-completion | 11 +++++++---- .../km-package-list-installed.bash-completion | 6 +++--- .../km-package-uninstall.bash-completion | 16 ++++++++++------ 4 files changed, 27 insertions(+), 18 deletions(-) diff --git a/linux/keyman-config/km-config.bash-completion b/linux/keyman-config/km-config.bash-completion index bc28b19212..b1f46c0076 100644 --- a/linux/keyman-config/km-config.bash-completion +++ b/linux/keyman-config/km-config.bash-completion @@ -1,4 +1,4 @@ -#/usr/bin/env bash +#!/usr/bin/env bash _km-config_completions() { @@ -9,14 +9,15 @@ _km-config_completions() opts="-h --help -v --verbose -vv --veryverbose --version -i --install" if [[ ${cur} == -* ]] ; then - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + # shellcheck disable=SC2207 + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 fi # default IFS splits 'file://' into 'file', ':' and '//' - if [ "${prev}" == ":" -a "${COMP_WORDS[COMP_CWORD-2]}" == "file" ]; then + if [ "${prev}" == ":" ] && [ "${COMP_WORDS[COMP_CWORD-2]}" == "file" ]; then local flag=${COMP_WORDS[COMP_CWORD-3]} - if [ $flag == "-i" -o $flag == "--install" ]; then + if [ "$flag" == "-i" ] || [ "$flag" == "--install" ]; then prev=$flag fi fi @@ -25,7 +26,8 @@ _km-config_completions() "-i"|"--install") local IFS=$'\n' compopt -o filenames - COMPREPLY=( $(compgen -f -X "!"*.kmp -- $cur) $(compgen -d -- $cur) ) + # shellcheck disable=SC2207 + COMPREPLY=( $(compgen -f -X "!"*.kmp -- "$cur") $(compgen -d -- "$cur") ) return 0 ;; *) diff --git a/linux/keyman-config/km-kvk2ldml.bash-completion b/linux/keyman-config/km-kvk2ldml.bash-completion index c89967666f..3eb2950c39 100644 --- a/linux/keyman-config/km-kvk2ldml.bash-completion +++ b/linux/keyman-config/km-kvk2ldml.bash-completion @@ -1,4 +1,4 @@ -#/usr/bin/env bash +#!/usr/bin/env bash _km-kvk2ldml_completions() { @@ -9,7 +9,8 @@ _km-kvk2ldml_completions() opts="-h --help -p --print -k --keys -o --output -v --verbose -vv --veryverbose --version" if [[ ${cur} == -* ]] ; then - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + # shellcheck disable=SC2207 + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 fi @@ -17,7 +18,8 @@ _km-kvk2ldml_completions() "-o"|"--output") local IFS=$'\n' compopt -o filenames - COMPREPLY=( $(compgen -f -- $cur) ) + # shellcheck disable=SC2207 + COMPREPLY=( $(compgen -f -- "$cur") ) return 0 ;; *) @@ -26,7 +28,8 @@ _km-kvk2ldml_completions() local IFS=$'\n' compopt -o filenames - COMPREPLY=( $(compgen -f -X "!"*.kvk -- $cur) $(compgen -d -- $cur) ) + # shellcheck disable=SC2207 + COMPREPLY=( $(compgen -f -X "!"*.kvk -- "$cur") $(compgen -d -- "$cur") ) } complete -F _km-kvk2ldml_completions km-kvk2ldml diff --git a/linux/keyman-config/km-package-list-installed.bash-completion b/linux/keyman-config/km-package-list-installed.bash-completion index e90bd29699..c3752fe733 100644 --- a/linux/keyman-config/km-package-list-installed.bash-completion +++ b/linux/keyman-config/km-package-list-installed.bash-completion @@ -1,14 +1,14 @@ -#/usr/bin/env bash +#!/usr/bin/env bash _km-package-list-installed_completions() { - local cur prev opts + local cur opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" - prev="${COMP_WORDS[COMP_CWORD-1]}" opts="-h --help -l --long -v --verbose -vv --veryverbose --version -u --user -o --os -s --shared" if [[ ${cur} == -* ]] ; then + # shellcheck disable=SC2207 COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) return 0 fi diff --git a/linux/keyman-config/km-package-uninstall.bash-completion b/linux/keyman-config/km-package-uninstall.bash-completion index 451a2e3e80..191e709eab 100644 --- a/linux/keyman-config/km-package-uninstall.bash-completion +++ b/linux/keyman-config/km-package-uninstall.bash-completion @@ -1,4 +1,4 @@ -#/usr/bin/env bash +#!/usr/bin/env bash _km-package-uninstall_completions() { @@ -9,7 +9,8 @@ _km-package-uninstall_completions() opts="-h --help -s --shared -v --verbose -vv --veryverbose --version" if [[ ${cur} == -* ]] ; then - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + # shellcheck disable=SC2207 + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 fi @@ -23,12 +24,15 @@ _km-package-uninstall_completions() shared="" case "${prev}" in "-s"|"--shared") - for file in $(ls -1 /usr/local/share/keyman); do kbid="`basename ${file}`"; shared="${shared} ${kbid}"; done - COMPREPLY=($(compgen -W "${shared}" -- ${cur})) + for file in /usr/local/share/keyman/*; do kbid="$(basename "${file}")"; shared="${shared} ${kbid}"; done + # shellcheck disable=SC2207 + COMPREPLY=($(compgen -W "${shared}" -- "${cur}")) ;; *) - for file in $(ls -1 ${XDG_DATA_HOME:-~/.local/share}/keyman); do kbid="`basename ${file}`"; words="${words} ${kbid}"; done - COMPREPLY=($(compgen -W "${words}" -- ${cur})) + # shellcheck disable=SC2231 # doesn't work with quotes + for file in ${XDG_DATA_HOME:-~/.local/share}/keyman/*; do kbid="$(basename "${file}")"; words="${words} ${kbid}"; done + # shellcheck disable=SC2207 + COMPREPLY=($(compgen -W "${words}" -- "${cur}")) ;; esac } From 0e4a00e6c0f6a9d5982754d6b212146fe314fe4d Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Tue, 10 Jan 2023 13:01:29 -0500 Subject: [PATCH 10/19] auto: increment master version to 17.0.27 --- HISTORY.md | 5 +++++ VERSION.md | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 8c6eaf6acf..2328313bc6 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,10 @@ # Keyman Version History +## 17.0.26 alpha 2023-01-10 + +* feat(linux): Add Back button to "Download Keyman Keyboards" dialog (#7994) +* feat(linux): List fonts in the uninstall confirmation dialog (#7995) + ## 17.0.25 alpha 2023-01-09 * chore(linux): Remove unnecessary variable (#7988) diff --git a/VERSION.md b/VERSION.md index 9663c46b83..bbae1f65b8 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -17.0.26 \ No newline at end of file +17.0.27 \ No newline at end of file From 89a253b1cac8db4185f003c93cb5b294744d894a Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Wed, 11 Jan 2023 11:48:58 +0100 Subject: [PATCH 11/19] feat(linux): Enhance tab completion in km-package-install This change adds tab completion for the bcp-47 parameter in km-package-install. Fixes #5361 --- linux/keyman-config/km-package-install | 29 +++++++++ .../km-package-install.bash-completion | 54 ++++++++++++++--- .../km-package-list-installed.bash-completion | 2 +- .../tests/test_package_install_completion.py | 60 +++++++++++++++++++ 4 files changed, 137 insertions(+), 8 deletions(-) create mode 100644 linux/keyman-config/tests/test_package_install_completion.py diff --git a/linux/keyman-config/km-package-install b/linux/keyman-config/km-package-install index dc2c3a355d..205a82b186 100755 --- a/linux/keyman-config/km-package-install +++ b/linux/keyman-config/km-package-install @@ -10,6 +10,8 @@ from pkg_resources import parse_version from zipfile import is_zipfile from keyman_config import KeymanApiUrl, __version__, secure_lookup +from keyman_config.install_kmp import extract_kmp +from keyman_config.kmpmetadata import get_metadata from keyman_config.uninstall_kmp import uninstall_kmp @@ -84,6 +86,33 @@ def list_keyboards(): write_kmpdirlist(kmpdirfile) +def _list_languages_for_keyboard_impl(packageId, packageDir): + from keyman_config.get_kmp import keyman_cache_dir + kmpfile = os.path.join(keyman_cache_dir(), packageId) + if not os.path.exists(kmpfile): + kmpfile = kmpfile + '.kmp' + if not os.path.exists(kmpfile): + return '' + extract_kmp(kmpfile, packageDir) + info, system, options, keyboards, files = get_metadata(packageDir) + if not keyboards: + return '' + firstKeyboard = keyboards[0] + if not secure_lookup(firstKeyboard, 'languages') or len(firstKeyboard['languages']) <= 0: + return '' + result = '' + for lang in firstKeyboard['languages']: + if result: + result += '\n' + result += lang['id'] + return result + + +def list_languages_for_keyboard(packageId, packageDir): + result = _list_languages_for_keyboard_impl(packageId, packageDir) + print(result) + + def main(): parser = argparse.ArgumentParser( description='Install a Keyman keyboard package, either a local .kmp file or specify a ' + diff --git a/linux/keyman-config/km-package-install.bash-completion b/linux/keyman-config/km-package-install.bash-completion index 091e4f64ec..1a424e8ea6 100644 --- a/linux/keyman-config/km-package-install.bash-completion +++ b/linux/keyman-config/km-package-install.bash-completion @@ -6,7 +6,7 @@ _km-package-install_completions() COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" - opts="-h --help -v --verbose -vv --veryverbose --version -p --package -f --file -s --shared" + opts="-h --help -v --verbose -vv --veryverbose --version -p --package -f --file -s --shared -l --bcp47" cache=${XDG_CACHE_HOME:-~/.cache}/keyman/kmpdirlist @@ -16,6 +16,14 @@ _km-package-install_completions() return 0 fi + if [[ -e ./km-package-install ]]; then + pkg_install_path='./km-package-install' + get_kmp_path='keyman_config/get_kmp.py' + else + pkg_install_path='/usr/bin/km-package-install' + get_kmp_path='/usr/lib/python3/dist-packages/keyman_config/get_kmp.py' + fi + case "${prev}" in "-p"|"--package") words="" @@ -23,12 +31,8 @@ _km-package-install_completions() # NOTE: identical code in `km-package-get.bash-completion`. # Unfortunately with bash completion scripts it's not possible to factor out # common code. - if [[ -e ./km-package-install ]]; then - pkg_install_path='./km-package-install' - else - pkg_install_path='/usr/bin/km-package-install' - fi - python3 -c "from importlib.machinery import SourceFileLoader;from importlib.util import module_from_spec, spec_from_loader;loader = SourceFileLoader('km_package_install', $pkg_install_path);spec = spec_from_loader(loader.name, loader);mod = module_from_spec(spec);loader.exec_module(mod);mod.list_keyboards()" + + python3 -c "from importlib.machinery import SourceFileLoader;from importlib.util import module_from_spec, spec_from_loader;loader = SourceFileLoader('km_package_install', '$pkg_install_path');spec = spec_from_loader(loader.name, loader);mod = module_from_spec(spec);loader.exec_module(mod);mod.list_keyboards()" fi if [[ -r $cache ]] ; then @@ -45,6 +49,42 @@ _km-package-install_completions() COMPREPLY=( $(compgen -f -X "!"*.kmp -- "$cur") $(compgen -d -- "$cur") ) return 0 ;; + "-l"|"--bcp47") + local packageId="" + local packageDir + packageDir=$(mktemp -d) + for ((i=0;i<$COMP_CWORD;i++)); do + case ${COMP_WORDS[$i]} in + "-p"|"--package") + packageId="${COMP_WORDS[$i+1]}" + # shellcheck disable=SC2086 # doesn't work with quotes + if [ ! -f ${XDG_CACHE_HOME:-~/.cache}/keyman/$packageId ] && [ ! -f ${XDG_CACHE_HOME:-~/.cache}/keyman/${packageId}.kmp ]; then + python3 -c "from importlib.machinery import SourceFileLoader;from importlib.util import module_from_spec, spec_from_loader;loader = SourceFileLoader('get_kmp', '$get_kmp_path');spec = spec_from_loader(loader.name, loader);mod = module_from_spec(spec);loader.exec_module(mod);mod.get_kmp('$packageId')" + fi + break + ;; + "-f"|"--file") + package="${COMP_WORDS[$i+1]}" + packageId=$(basename "$package") + # shellcheck disable=SC2086 # doesn't work with quotes + cp "$package" ${XDG_CACHE_HOME:-~/.cache}/keyman/${packageId} + break + ;; + *) + ;; + esac + done + if [ -z "$packageId" ]; then + return 0 + fi + words="" + while read -r lang; do + words="$words $lang" + done < <(python3 -c "from importlib.machinery import SourceFileLoader;from importlib.util import module_from_spec, spec_from_loader;loader = SourceFileLoader('km_package_install', '$pkg_install_path');spec = spec_from_loader(loader.name, loader);mod = module_from_spec(spec);loader.exec_module(mod);mod.list_languages_for_keyboard('$packageId', '$packageDir')") + # shellcheck disable=SC2207 + COMPREPLY=($(compgen -W "${words}" -- "${cur}")) + return 0 + ;; *) ;; esac diff --git a/linux/keyman-config/km-package-list-installed.bash-completion b/linux/keyman-config/km-package-list-installed.bash-completion index c3752fe733..a3758b467e 100644 --- a/linux/keyman-config/km-package-list-installed.bash-completion +++ b/linux/keyman-config/km-package-list-installed.bash-completion @@ -9,7 +9,7 @@ _km-package-list-installed_completions() if [[ ${cur} == -* ]] ; then # shellcheck disable=SC2207 - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 fi } diff --git a/linux/keyman-config/tests/test_package_install_completion.py b/linux/keyman-config/tests/test_package_install_completion.py new file mode 100644 index 0000000000..97238e3dc2 --- /dev/null +++ b/linux/keyman-config/tests/test_package_install_completion.py @@ -0,0 +1,60 @@ +#!/usr/bin/python3 +import os +import tempfile +import unittest +from unittest.mock import patch, ANY +from importlib.machinery import SourceFileLoader +from importlib.util import module_from_spec, spec_from_loader + + +class PackageInstallCompletionTests(unittest.TestCase): + + def setUp(self): + patcher1 = patch('keyman_config.install_kmp.extract_kmp') + self.mockExtractKmp = patcher1.start() + self.addCleanup(patcher1.stop) + patcher2 = patch('keyman_config.kmpmetadata.get_metadata') + self.mockGetMetadata = patcher2.start() + self.addCleanup(patcher2.stop) + + loader = SourceFileLoader('km_package_install', os.path.join(os.path.dirname( + os.path.abspath(__file__)), '../km-package-install')) + spec = spec_from_loader(loader.name, loader) + if spec: + self.mod = module_from_spec(spec) + loader.exec_module(self.mod) + + self.tempDir = tempfile.TemporaryDirectory() + os.environ["XDG_CACHE_HOME"] = self.tempDir.name + self.cacheDir = os.path.join(self.tempDir.name, 'keyman') + os.makedirs(self.cacheDir) + + def _list_languages_for_keyboard_impl(self, packageId): + return self.mod._list_languages_for_keyboard_impl(packageId, 'someDir') + + def test_PackageCompletionNoLanguage(self): + open(os.path.join(self.cacheDir, 'foo'), 'w') + self.mockGetMetadata.return_value = (None, None, None, [{}], None) + result = self._list_languages_for_keyboard_impl('foo') + self.assertEqual(result, "") + + def test_PackageCompletionOneLanguage(self): + open(os.path.join(self.cacheDir, 'khmer_angkor'), 'w') + self.mockGetMetadata.return_value = ( + None, None, None, + [{'languages': [{'name': 'Central Khmer (Khmer, Cambodia)', 'id': 'km'}]}], + None) + result = self._list_languages_for_keyboard_impl('khmer_angkor') + self.assertEqual(result, "km") + + def test_PackageCompletionMultipleLanguages(self): + open(os.path.join(self.cacheDir, 'sil_euro_latin'), 'w') + self.mockGetMetadata.return_value = ( + None, None, None, + [{'languages': [ + {'name': 'English', 'id': 'en'}, + {'name': 'French', 'id': 'fr'}, + {'name': 'German', 'id': 'de'}]}], + None) + result = self._list_languages_for_keyboard_impl('sil_euro_latin') + self.assertEqual(result, 'en\nfr\nde') From 6bc87991e0740cb9e9bf120e7d0d8d19b40c9f91 Mon Sep 17 00:00:00 2001 From: Kevin Schluensen Date: Wed, 11 Jan 2023 13:58:46 +0100 Subject: [PATCH 12/19] feat(linux): Display error messages in the UI Fixes #6288 --- .../keyman_config/downloadkeyboard.py | 6 ++++ .../keyman_config/uninstall_kmp.py | 35 +++++++++++-------- .../keyman_config/view_installed.py | 7 +++- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/linux/keyman-config/keyman_config/downloadkeyboard.py b/linux/keyman-config/keyman_config/downloadkeyboard.py index d79b1e3d44..1b9e3bbfdc 100755 --- a/linux/keyman-config/keyman_config/downloadkeyboard.py +++ b/linux/keyman-config/keyman_config/downloadkeyboard.py @@ -52,6 +52,12 @@ class DownloadKmpWindow(Gtk.Dialog): self.response(Gtk.ResponseType.OK) self.close() return True + logging.error(_("Downloading kmp file failed")) + dialog = Gtk.MessageDialog( + self, 0, Gtk.MessageType.ERROR, + Gtk.ButtonsType.OK, _("Downloading keyboard file failed")) + dialog.run() + dialog.destroy() return False def _keyman_policy(self, web_view, decision, decision_type): diff --git a/linux/keyman-config/keyman_config/uninstall_kmp.py b/linux/keyman-config/keyman_config/uninstall_kmp.py index fe8931dbe3..84c083694d 100755 --- a/linux/keyman-config/keyman_config/uninstall_kmp.py +++ b/linux/keyman-config/keyman_config/uninstall_kmp.py @@ -37,31 +37,32 @@ def uninstall_kmp_shared(packageID): """ kbdir = get_keyboard_dir(InstallLocation.Shared, packageID) if not os.path.isdir(kbdir): - logging.error("Keyboard directory for %s does not exist. Aborting", packageID) - exit(3) + msg = _("Keyboard directory for %s does not exist." % packageID) + logging.error(msg) + return msg kbdocdir = get_keyman_doc_dir(InstallLocation.Shared, packageID) kbfontdir = get_keyman_font_dir(InstallLocation.Shared, packageID) logging.info("Uninstalling shared keyboard: %s", packageID) if not os.access(kbdir, os.X_OK | os.W_OK): # Check for write access of keyman dir - logging.error( - "You do not have permissions to uninstall the keyboard files. You need to run this with `sudo`") - exit(3) + msg = _("You do not have permissions to uninstall the keyboard files. You need to run this with `sudo`") + logging.error(msg) + return msg if os.path.isdir(kbdocdir): if not os.access(kbdocdir, os.X_OK | os.W_OK): # Check for write access of keyman doc dir - logging.error( - "You do not have permissions to uninstall the documentation. You need to run this with `sudo`") - exit(3) + msg = _("You do not have permissions to uninstall the documentation. You need to run this with `sudo`") + logging.error(msg) + return msg delete_dir(kbdocdir) logging.info("Removed documentation directory: %s", kbdocdir) else: logging.info("No documentation directory") if os.path.isdir(kbfontdir): if not os.access(kbfontdir, os.X_OK | os.W_OK): # Check for write access of keyman fonts - logging.error( - "You do not have permissions to uninstall the font files. You need to run this with `sudo`") - exit(3) + msg = _("You do not have permissions to uninstall the font files. You need to run this with `sudo`") + logging.error(msg) + return msg delete_dir(kbfontdir) logging.info("Removed font directory: %s", kbfontdir) else: @@ -80,6 +81,7 @@ def uninstall_kmp_shared(packageID): delete_dir(kbdir) logging.info("Removed keyman directory: %s", kbdir) logging.info("Finished uninstalling shared keyboard: %s", packageID) + return '' def uninstall_keyboards_from_ibus(keyboards, packageDir): @@ -130,8 +132,9 @@ def uninstall_kmp_user(packageID): """ kbdir = get_keyboard_dir(InstallLocation.User, packageID) if not os.path.isdir(kbdir): - logging.error("Keyboard directory for %s does not exist. Aborting", packageID) - exit(3) + msg = _("Keyboard directory for %s does not exist." % packageID) + logging.error(msg) + return msg logging.info("Uninstalling local keyboard: %s", packageID) info, system, options, keyboards, files = get_metadata(kbdir) if keyboards: @@ -150,6 +153,7 @@ def uninstall_kmp_user(packageID): delete_dir(fontdir) logging.info("Removed user keyman font directory: %s", fontdir) logging.info("Finished uninstalling local keyboard: %s", packageID) + return '' def uninstall_kmp(packageID, sharedarea=False): @@ -161,8 +165,9 @@ def uninstall_kmp(packageID, sharedarea=False): sharedarea (str): whether to uninstall from shared /usr/local or ~/.local """ if sharedarea: - uninstall_kmp_shared(packageID) + msg = uninstall_kmp_shared(packageID) else: - uninstall_kmp_user(packageID) + msg = uninstall_kmp_user(packageID) get_keyman_config_service().keyboard_list_changed() + return msg diff --git a/linux/keyman-config/keyman_config/view_installed.py b/linux/keyman-config/keyman_config/view_installed.py index 959c0196d9..921d86c5f8 100755 --- a/linux/keyman-config/keyman_config/view_installed.py +++ b/linux/keyman-config/keyman_config/view_installed.py @@ -362,7 +362,12 @@ class ViewInstalledWindow(ViewInstalledWindowBase): if response == Gtk.ResponseType.YES: logging.info("Uninstalling keyboard" + model[treeiter][1]) # can only uninstall with the gui from user area - uninstall_kmp(model[treeiter][3]) + msg = uninstall_kmp(model[treeiter][3]) + if not msg == '': + md = Gtk.MessageDialog(self, 0, Gtk.MessageType.ERROR, + Gtk.ButtonsType.OK, _("Uninstalling keyboard failed.\n\nError message: ") + msg) + md.run() + md.destroy() logging.info("need to restart window after uninstalling a keyboard") self.restart() elif response == Gtk.ResponseType.NO: From a3e57bf3f0589b7852c27bb3d69eb204ab87511b Mon Sep 17 00:00:00 2001 From: Kevin Schluensen Date: Wed, 11 Jan 2023 15:12:55 +0100 Subject: [PATCH 13/19] bug(linux): Empty keyboard after failed installation Fixes #8004 --- linux/keyman-config/keyman_config/install_kmp.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/linux/keyman-config/keyman_config/install_kmp.py b/linux/keyman-config/keyman_config/install_kmp.py index bed23e3f41..eb2069c319 100755 --- a/linux/keyman-config/keyman_config/install_kmp.py +++ b/linux/keyman-config/keyman_config/install_kmp.py @@ -106,14 +106,14 @@ class InstallKmp(): self.kmpdocdir = get_keyman_doc_dir(area, self.packageID) self.kmpfontdir = get_keyman_font_dir(area, self.packageID) - if not self._safeMakeDirs(self.packageDir): - return - if not os.path.isfile(inputfile): message = _("File {kmpfile} doesn't exist").format(kmpfile=inputfile) logging.error("install_kmp.py: %s", message) raise InstallError(InstallStatus.Abort, message) + if not self._safeMakeDirs(self.packageDir): + return + extract_kmp(inputfile, self.packageDir) if is_fcitx_running(): From 099b22b1745ce6cdcfc22f171be6f575ade18568 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Wed, 11 Jan 2023 13:01:49 -0500 Subject: [PATCH 14/19] auto: increment master version to 17.0.28 --- HISTORY.md | 4 ++++ VERSION.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 2328313bc6..32622155b1 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,9 @@ # Keyman Version History +## 17.0.27 alpha 2023-01-11 + +* chore(linux): Refactor completion script (#8002) + ## 17.0.26 alpha 2023-01-10 * feat(linux): Add Back button to "Download Keyman Keyboards" dialog (#7994) diff --git a/VERSION.md b/VERSION.md index bbae1f65b8..4cc50c0215 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -17.0.27 \ No newline at end of file +17.0.28 \ No newline at end of file From 9ab2019003792cfde1514663bc42f6e0864cb7a7 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Thu, 12 Jan 2023 13:01:37 -0500 Subject: [PATCH 15/19] auto: increment master version to 17.0.29 --- HISTORY.md | 5 +++++ VERSION.md | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 32622155b1..e244698d63 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,10 @@ # Keyman Version History +## 17.0.28 alpha 2023-01-12 + +* feat(linux): Display error messages in the UI (#8006) +* bug(linux): Empty keyboard after failed installation (#8008) + ## 17.0.27 alpha 2023-01-11 * chore(linux): Refactor completion script (#8002) diff --git a/VERSION.md b/VERSION.md index 4cc50c0215..6c64547582 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -17.0.28 \ No newline at end of file +17.0.29 \ No newline at end of file From c5c238d2703e1aff61a126f4202356115f17b969 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Fri, 13 Jan 2023 16:34:52 +0100 Subject: [PATCH 16/19] chore(linux): Update sample settings --- docs/settings/linux/extensions.json | 3 ++- docs/settings/linux/launch.json | 9 ++++++--- docs/settings/linux/tasks.json | 6 +++--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/docs/settings/linux/extensions.json b/docs/settings/linux/extensions.json index bd7f528324..81603ea639 100644 --- a/docs/settings/linux/extensions.json +++ b/docs/settings/linux/extensions.json @@ -7,6 +7,7 @@ "ms-python.python", "mads-hartmann.bash-ide-vscode", "timonwong.shellcheck", - "maelvalais.autoconf" + "maelvalais.autoconf", + "webfreak.debug", ] } diff --git a/docs/settings/linux/launch.json b/docs/settings/linux/launch.json index cbf10cb216..b407dacdb7 100644 --- a/docs/settings/linux/launch.json +++ b/docs/settings/linux/launch.json @@ -24,14 +24,17 @@ "valuesFormatting": "parseText" }, { + // Mount the Keyman root directory as a Shared Folder in the VM. // kill ibus-engine-keyman, if running // start: gdbserver 10.3.0.53:2345 /media/sf_Develop/keyman/keyman/linux/ibus-keyman/src/ibus-engine-keyman // then attach debugger in vscode + // Replace the IP address after `gdbserver` with the IP address of the host machine. + // Replace the IP address below with the address of the VM running gdbserver. "type": "gdb", "request": "attach", - "name": "Attach to gdbserver", - "executable": "./linux/ibus-keyman/src/ibus-engine-keyman", - "target": "10.3.0.53:2345", + "name": "Attach to gdbserver (ibus-keyman)", + "executable": "${workspaceFolder}/linux/ibus-keyman/src/ibus-engine-keyman", + "target": "10.3.0.52:2345", "remote": true, "cwd": "${workspaceFolder}/linux/ibus-keyman", "valuesFormatting": "parseText" diff --git a/docs/settings/linux/tasks.json b/docs/settings/linux/tasks.json index f274656555..b2a7f161e5 100644 --- a/docs/settings/linux/tasks.json +++ b/docs/settings/linux/tasks.json @@ -143,9 +143,9 @@ "CPPFLAGS=\"-DG_MESSAGES_DEBUG -I${workspaceFolder}/core/build/arch/debug/include/ -I${workspaceFolder}/common/include/ -I${workspaceFolder}/core/include/\"", "CFLAGS=\"-g -O0\"", "CXXFLAGS=\"-g -O0\"", - "KEYMAN_PROC_LIBS=\"-L${workspaceFolder}/common/core/desktop/build/arch/debug/src -lkmnkbp0\"", - "KEYMAN_PROC_CFLAGS=\"-I${workspaceFolder}/common/core/desktop/build/arch/debug/include -I${workspaceFolder}/common/core/desktop/include\"", - "PKG_CONFIG_PATH=${workspaceFolder}/common/core/desktop/build/arch/debug/meson-private" + "KEYMAN_PROC_LIBS=\"-L${workspaceFolder}/core/build/arch/debug/src -lkmnkbp0\"", + "KEYMAN_PROC_CFLAGS=\"-I${workspaceFolder}/core/build/arch/debug/include -I${workspaceFolder}/core/include -I${workspaceFolder}/common/include\"", + "PKG_CONFIG_PATH=${workspaceFolder}/core/build/arch/debug/meson-private" ], "options": { "cwd": "${workspaceFolder}/linux/ibus-keyman" From 90d8feabe19d3ab987bbf6b953b26b815dd8cbdd Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Fri, 13 Jan 2023 18:03:12 +0100 Subject: [PATCH 17/19] fix(linux): Fix crash (un-)installing shared keyboard The reason for the crash is the missing file `dbus-launch` which gets called when running with `sudo`. This change adds a dependency to `dbus-x11` which provides `dbus-launch`. Fixes #8012. (cherry picked from commit 0584db39c3d5b7996fdb1ee78076a5ff3ac95e58) --- linux/debian/control | 1 + 1 file changed, 1 insertion(+) diff --git a/linux/debian/control b/linux/debian/control index b42e7bc5c9..0a0446cb1a 100644 --- a/linux/debian/control +++ b/linux/debian/control @@ -86,6 +86,7 @@ Depends: python3-bs4, python3-gi, python3-sentry-sdk (>= 1.1) | python3-raven, + dbus-x11, ${misc:Depends}, ${python3:Depends}, Description: Keyman for Linux configuration From 5ee9c2ead1f271df0c7e1d73e4428d3f2bb2b9ed Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Fri, 13 Jan 2023 18:27:25 +0100 Subject: [PATCH 18/19] chore(linux): Don't report KeyboardInterrupt to Sentry When the user presses Ctrl-C we don't want to create a Sentry issue. This change ignores that exception. --- linux/keyman-config/keyman_config/__init__.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/linux/keyman-config/keyman_config/__init__.py b/linux/keyman-config/keyman_config/__init__.py index ee2326a86f..1b0b283900 100644 --- a/linux/keyman-config/keyman_config/__init__.py +++ b/linux/keyman-config/keyman_config/__init__.py @@ -37,6 +37,15 @@ def secure_lookup(data, key1, key2 = None): return None +def before_send(event, hint): + if 'exc_info' in hint: + exc_type, exc_value, tb = hint['exc_info'] + if isinstance(exc_value, KeyboardInterrupt): + # Ignore KeyboardInterrupt exception + return None + return event + + gettext.bindtextdomain('keyman-config', '/usr/share/locale') gettext.textdomain('keyman-config') @@ -77,6 +86,7 @@ else: environment=__environment__, release='release-' + __versionwithtag__, integrations=[sentry_logging], + before_send=before_send ) set_user({'id': hash(getpass.getuser())}) with configure_scope() as scope: From 0988c7f31aedcff6c89a41127155d2e4e7526470 Mon Sep 17 00:00:00 2001 From: Keyman Build Agent Date: Mon, 16 Jan 2023 13:02:22 -0500 Subject: [PATCH 19/19] auto: increment master version to 17.0.30 --- HISTORY.md | 7 +++++++ VERSION.md | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index e244698d63..b937f09aa6 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,12 @@ # Keyman Version History +## 17.0.29 alpha 2023-01-16 + +* fix(linux): Fix crash (un-)installing shared keyboard (#8020) +* chore(linux): Don't report KeyboardInterrupt to Sentry (#8021) +* chore(linux): Update sample settings (#8018) +* feat(linux): Enhance tab completion in km-package-install (#8005) + ## 17.0.28 alpha 2023-01-12 * feat(linux): Display error messages in the UI (#8006) diff --git a/VERSION.md b/VERSION.md index 6c64547582..bc08fbd7ed 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -17.0.29 \ No newline at end of file +17.0.30 \ No newline at end of file