Merge pull request #8011 from keymanapp/feat/linux/uninstall-if-error

feat(linux): Improve uninstallation
This commit is contained in:
Eberhard Beilharz 2023-01-25 16:46:56 +01:00 committed by GitHub
commit 2fea609714
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 55 additions and 93 deletions

View file

@ -17,7 +17,10 @@ from keyman_config.ibus_util import (get_ibus_bus, restart_ibus,
from keyman_config.kmpmetadata import get_metadata
def delete_dir(dir: str) -> bool:
error_dirs = set()
def _delete_dir(dir: str) -> bool:
if not os.path.isdir(dir):
logging.error("%s is not a directory", dir)
return False
@ -28,63 +31,55 @@ def delete_dir(dir: str) -> bool:
return True
def uninstall_kmp_shared(packageID):
"""
Uninstall a kmp from /usr/local/share/keyman
def _uninstall_dir(what, dir):
if os.path.isdir(dir):
if not os.access(dir, os.X_OK | os.W_OK):
error_dirs.add(dir)
return
Args:
packageID (str): Keyboard package ID
"""
kbdir = get_keyboard_dir(InstallLocation.Shared, packageID)
if not os.path.isdir(kbdir):
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
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
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)
_delete_dir(dir)
logging.info('Removed %s directory %s', what, dir)
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
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:
logging.info("No font directory")
logging.info('No %s directory %s', what, dir)
# need to uninstall from ibus for all lang and all kmx in kmp
def _uninstall_kmp_common(location, packageID):
kbdir = get_keyboard_dir(location, packageID)
kbdocdir = get_keyman_doc_dir(location, packageID)
kbfontdir = get_keyman_font_dir(location, packageID)
where = 'local'
if location == InstallLocation.Shared:
where = 'shared'
logging.info("Uninstalling %s keyboard: %s", where, packageID)
info, system, options, keyboards, files = get_metadata(kbdir)
if keyboards:
if is_gnome_shell():
uninstall_keyboards_from_gnome(keyboards, kbdir)
if is_fcitx_running():
_uninstall_keyboards_from_fcitx5()
elif is_gnome_shell():
_uninstall_keyboards_from_gnome(keyboards, kbdir)
else:
uninstall_keyboards_from_ibus(keyboards, kbdir)
_uninstall_keyboards_from_ibus(keyboards, kbdir)
else:
logging.warning("could not uninstall keyboards")
delete_dir(kbdir)
logging.info("Removed keyman directory: %s", kbdir)
logging.info("Finished uninstalling shared keyboard: %s", packageID)
if not os.path.isdir(kbdir):
logging.error('Keyboard directory %s for %s does not exist.', kbdir, packageID)
_uninstall_dir('Keyman keyboards', kbdir)
_uninstall_dir('documentation', kbdocdir)
_uninstall_dir('font', kbfontdir)
if error_dirs:
msg = _('You do not have permission to uninstall the files in %s. You need to run this with `sudo`.') % ', '.join(error_dirs)
logging.error(msg)
return msg
logging.info("Finished uninstalling %s keyboard: %s", where, packageID)
return ''
def uninstall_keyboards_from_ibus(keyboards, packageDir):
def _uninstall_keyboards_from_ibus(keyboards, packageDir):
bus = get_ibus_bus()
if bus or os.environ.get('SUDO_USER'):
# install all kmx for first lang not just packageID
@ -96,7 +91,7 @@ def uninstall_keyboards_from_ibus(keyboards, packageDir):
logging.warning("could not uninstall keyboards from IBus")
def uninstall_keyboards_from_gnome(keyboards, packageDir):
def _uninstall_keyboards_from_gnome(keyboards, packageDir):
gnomeKeyboardsUtil = GnomeKeyboardsUtil()
sources = gnomeKeyboardsUtil.read_input_sources()
@ -123,39 +118,6 @@ def _uninstall_keyboards_from_fcitx5():
return _('Please use fcitx5-configtool to remove the keyboard from the group')
def uninstall_kmp_user(packageID):
"""
Uninstall a kmp from ~/.local/share/keyman
Args:
packageID (str): Keyboard package ID
"""
kbdir = get_keyboard_dir(InstallLocation.User, packageID)
if not os.path.isdir(kbdir):
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:
if is_fcitx_running():
_uninstall_keyboards_from_fcitx5()
elif is_gnome_shell():
uninstall_keyboards_from_gnome(keyboards, kbdir)
else:
uninstall_keyboards_from_ibus(keyboards, kbdir)
else:
logging.warning("could not uninstall keyboards")
delete_dir(kbdir)
logging.info("Removed user keyman directory: %s", kbdir)
fontdir = get_keyman_font_dir(InstallLocation.User, packageID)
if os.path.isdir(fontdir):
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):
"""
Uninstall a kmp
@ -165,9 +127,9 @@ def uninstall_kmp(packageID, sharedarea=False):
sharedarea (str): whether to uninstall from shared /usr/local or ~/.local
"""
if sharedarea:
msg = uninstall_kmp_shared(packageID)
msg = _uninstall_kmp_common(InstallLocation.Shared, packageID)
else:
msg = uninstall_kmp_user(packageID)
msg = _uninstall_kmp_common(InstallLocation.User, packageID)
get_keyman_config_service().keyboard_list_changed()
return msg

View file

@ -2,7 +2,7 @@
import unittest
from unittest.mock import patch
from keyman_config.uninstall_kmp import uninstall_keyboards_from_gnome
from keyman_config.uninstall_kmp import _uninstall_keyboards_from_gnome
class UninstallKmpTests(unittest.TestCase):
@ -17,7 +17,7 @@ class UninstallKmpTests(unittest.TestCase):
mockGnomeKeyboardsUtilInstance = self.mockGnomeKeyboardsUtilClass.return_value
mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = []
# Execute
uninstall_keyboards_from_gnome([{'id': 'foo1'}], 'fooDir')
_uninstall_keyboards_from_gnome([{'id': 'foo1'}], 'fooDir')
# Verify
mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with([])
@ -27,7 +27,7 @@ class UninstallKmpTests(unittest.TestCase):
mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [
('ibus', 'fooDir/foo2.kmx')]
# Execute
uninstall_keyboards_from_gnome([{'id': 'foo1'}], 'fooDir')
_uninstall_keyboards_from_gnome([{'id': 'foo1'}], 'fooDir')
# Verify
mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with([
('ibus', 'fooDir/foo2.kmx')])
@ -38,7 +38,7 @@ class UninstallKmpTests(unittest.TestCase):
mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [
('xkb', 'en'), ('ibus', 'fooDir/foo1.kmx')]
# Execute
uninstall_keyboards_from_gnome([{'id': 'foo1'}], 'fooDir')
_uninstall_keyboards_from_gnome([{'id': 'foo1'}], 'fooDir')
# Verify
mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with(
[('xkb', 'en')])
@ -49,7 +49,7 @@ class UninstallKmpTests(unittest.TestCase):
mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [
('xkb', 'en'), ('ibus', 'fooDir/foo1.kmx'), ('ibus', 'fooDir/foo2.kmx')]
# Execute
uninstall_keyboards_from_gnome([{'id': 'foo1'}, {'id': 'foo2'}], 'fooDir')
_uninstall_keyboards_from_gnome([{'id': 'foo1'}, {'id': 'foo2'}], 'fooDir')
# Verify
mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with(
[('xkb', 'en')])
@ -60,7 +60,7 @@ class UninstallKmpTests(unittest.TestCase):
mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [
('ibus', 'fooDir/foo1.kmx'), ('ibus', 'fooDir/foo2.kmx')]
# Execute
uninstall_keyboards_from_gnome([{'id': 'foo1'}, {'id': 'foo2'}], 'fooDir')
_uninstall_keyboards_from_gnome([{'id': 'foo1'}, {'id': 'foo2'}], 'fooDir')
# Verify
mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with([])
@ -70,7 +70,7 @@ class UninstallKmpTests(unittest.TestCase):
mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [
('xkb', 'en'), ('ibus', 'en:fooDir/foo1.kmx')]
# Execute
uninstall_keyboards_from_gnome([{'id': 'foo1', 'languages': [{'id': 'en'}]}], 'fooDir')
_uninstall_keyboards_from_gnome([{'id': 'foo1', 'languages': [{'id': 'en'}]}], 'fooDir')
# Verify
mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with(
[('xkb', 'en')])
@ -81,7 +81,7 @@ class UninstallKmpTests(unittest.TestCase):
mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [
('xkb', 'en'), ('ibus', 'fr:fooDir/foo1.kmx')]
# Execute
uninstall_keyboards_from_gnome(
_uninstall_keyboards_from_gnome(
[{'id': 'foo1', 'languages': [{'id': 'en'}, {'id': 'fr'}]}], 'fooDir')
# Verify
mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with(
@ -93,7 +93,7 @@ class UninstallKmpTests(unittest.TestCase):
mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [
('xkb', 'en'), ('ibus', 'en:fooDir/foo1.kmx')]
# Execute
uninstall_keyboards_from_gnome(
_uninstall_keyboards_from_gnome(
[{'id': 'foo1', 'languages': [{'id': 'fr'}]}], 'fooDir')
# Verify
mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with(
@ -105,7 +105,7 @@ class UninstallKmpTests(unittest.TestCase):
mockGnomeKeyboardsUtilInstance.read_input_sources.return_value = [
('xkb', 'en'), ('ibus', 'en:fooDir/foo1.kmx'), ('ibus', 'fr:fooDir/foo1.kmx')]
# Execute
uninstall_keyboards_from_gnome(
_uninstall_keyboards_from_gnome(
[{'id': 'foo1', 'languages': [{'id': 'fr'}]}], 'fooDir')
# Verify
mockGnomeKeyboardsUtilInstance.write_input_sources.assert_called_once_with(