feat(identity): rename user-visible identity to voculinux with one-time legacy import

The fork takes its own name everywhere a user can see it: binaries
(voculinux, voculinux-gui), desktop entry, autostart, tray, D-Bus
namespace (com.voculinux.Voculinux, no alias for the old name),
config/data/cache dirs, single-instance lock, IBus engine identity,
tray icons, resource prefixes, VOCULINUX_* environment names, and the
update-checker user agent. The internal Python module stays vocalinux
and the distribution metadata keeps the upstream URLs as provenance.

On first run a previous Vocalinux install's config.json, custom
dictionary, and portal restore token are copied once into the new
locations (new config always wins, no merge, no write-back); models
re-resolve through the pinned-checksum download path. An offline
naming-sweep test proves no old-name strings remain on user-visible
surfaces outside the allowlist.

Refs #18
This commit is contained in:
soubarnak
2026-11-06 01:29:39 +05:30
parent c565e6d946
commit ea7be5f111
251 changed files with 2449 additions and 1991 deletions
+20 -20
View File
@@ -94,7 +94,7 @@ class TestIBusTextInjectorSetupFailures(unittest.TestCase):
with self.assertRaises(IBusSetupError) as context:
IBusTextInjector(auto_activate=True)
self.assertIn("Failed to activate Vocalinux IBus engine", str(context.exception))
self.assertIn("Failed to activate Voculinux IBus engine", str(context.exception))
@patch("vocalinux.text_injection.ibus_engine.IBUS_AVAILABLE", True)
@patch("vocalinux.text_injection.ibus_engine.ensure_ibus_dir")
@@ -137,7 +137,7 @@ class TestIBusEngineHelpers(unittest.TestCase):
def test_ensure_ibus_dir_creates_directory(self):
"""Test that ensure_ibus_dir creates the directory."""
with patch("vocalinux.text_injection.ibus_engine.VOCALINUX_IBUS_DIR") as mock_dir:
with patch("vocalinux.text_injection.ibus_engine.VOCULINUX_IBUS_DIR") as mock_dir:
mock_dir.mkdir = MagicMock()
from vocalinux.text_injection.ibus_engine import ensure_ibus_dir
@@ -157,7 +157,7 @@ class TestIsEngineActive(unittest.TestCase):
@patch("subprocess.run")
def test_engine_active(self, mock_run):
"""Test detection when engine is active."""
mock_run.return_value = MagicMock(stdout="vocalinux", returncode=0)
mock_run.return_value = MagicMock(stdout="voculinux", returncode=0)
from vocalinux.text_injection.ibus_engine import is_engine_active
@@ -589,12 +589,12 @@ class TestSwitchEngine(unittest.TestCase):
# First call: ibus engine <name> (switch)
# Second call: ibus engine (get current) - for verification
switch_result = MagicMock(returncode=0)
verify_result = MagicMock(returncode=0, stdout="vocalinux\n")
verify_result = MagicMock(returncode=0, stdout="voculinux\n")
mock_run.side_effect = [switch_result, verify_result]
from vocalinux.text_injection.ibus_engine import switch_engine
result = switch_engine("vocalinux")
result = switch_engine("voculinux")
self.assertTrue(result)
self.assertEqual(mock_run.call_count, 2)
@@ -621,7 +621,7 @@ class TestSwitchEngine(unittest.TestCase):
from vocalinux.text_injection.ibus_engine import switch_engine
result = switch_engine("vocalinux")
result = switch_engine("voculinux")
self.assertFalse(result)
@@ -674,8 +674,8 @@ class TestIBusTextInjector(unittest.TestCase):
self.assertGreaterEqual(mock_ensure_dir.call_count, 1)
# Engine should be started
mock_start_engine.assert_called_once()
# Should switch to vocalinux engine
mock_switch.assert_called_once_with("vocalinux")
# Should switch to voculinux engine
mock_switch.assert_called_once_with("voculinux")
mock_wait_ready.assert_called_once_with()
self.assertEqual(injector._previous_engine, "xkb:us::eng")
@@ -1003,20 +1003,20 @@ class TestIBusTextInjector(unittest.TestCase):
@patch(
"vocalinux.text_injection.ibus_engine._query_active_engine",
return_value="vocalinux",
return_value="voculinux",
)
@patch("vocalinux.text_injection.ibus_engine.stop_engine_process")
@patch(
"vocalinux.text_injection.ibus_engine.get_current_engine",
return_value="vocalinux",
return_value="voculinux",
)
@patch("vocalinux.text_injection.ibus_engine.switch_engine", return_value=True)
@patch("vocalinux.text_injection.ibus_engine.IBUS_AVAILABLE", True)
@patch("vocalinux.text_injection.ibus_engine.ensure_ibus_dir")
def test_stop_uses_cached_engine_when_stuck_on_vocalinux(
def test_stop_uses_cached_engine_when_stuck_on_voculinux(
self, mock_ensure_dir, mock_switch, mock_get_current, mock_stop_proc, mock_live
):
"""If quit finds vocalinux selected, fall back to the warmup-captured engine (#558)."""
"""If quit finds voculinux selected, fall back to the warmup-captured engine (#558)."""
from vocalinux.text_injection.ibus_engine import IBusTextInjector
injector = IBusTextInjector(auto_activate=False)
@@ -1031,15 +1031,15 @@ class TestIBusTextInjector(unittest.TestCase):
@patch("vocalinux.text_injection.ibus_engine.stop_engine_process")
@patch(
"vocalinux.text_injection.ibus_engine.get_current_engine",
return_value="vocalinux",
return_value="voculinux",
)
@patch("vocalinux.text_injection.ibus_engine.switch_engine")
@patch("vocalinux.text_injection.ibus_engine.IBUS_AVAILABLE", True)
@patch("vocalinux.text_injection.ibus_engine.ensure_ibus_dir")
def test_stop_skips_restore_when_only_vocalinux_active(
def test_stop_skips_restore_when_only_voculinux_active(
self, mock_ensure_dir, mock_switch, mock_get_current, mock_stop_proc
):
"""Do not try to reselect vocalinux after its process has been torn down."""
"""Do not try to reselect voculinux after its process has been torn down."""
from vocalinux.text_injection.ibus_engine import IBusTextInjector
injector = IBusTextInjector(auto_activate=False)
@@ -1091,7 +1091,7 @@ class TestIBusTextInjector(unittest.TestCase):
@patch("vocalinux.text_injection.ibus_engine.start_engine_process", return_value=True)
@patch("vocalinux.text_injection.ibus_engine.IBusTextInjector._wait_for_engine_ready")
@patch("vocalinux.text_injection.ibus_engine.switch_engine")
def test_prepare_engine_does_not_activate_vocalinux_engine(
def test_prepare_engine_does_not_activate_voculinux_engine(
self,
mock_switch,
mock_wait_ready,
@@ -1124,7 +1124,7 @@ class TestIBusTextInjector(unittest.TestCase):
mock_is_active,
mock_get_current,
):
"""Warmup caches the live engine so quit can restore after a stuck vocalinux (#558)."""
"""Warmup caches the live engine so quit can restore after a stuck voculinux (#558)."""
from vocalinux.text_injection.ibus_engine import IBusTextInjector
injector = IBusTextInjector(auto_activate=False)
@@ -1194,7 +1194,7 @@ class TestIBusTextInjector(unittest.TestCase):
mock_get_xkb,
mock_restore_xkb,
):
"""Scoped injection must restore XKB after the Vocalinux engine switch (#664)."""
"""Scoped injection must restore XKB after the Voculinux engine switch (#664)."""
from vocalinux.text_injection.ibus_engine import ENGINE_NAME, IBusTextInjector
mock_socket_path.exists.return_value = True
@@ -1615,14 +1615,14 @@ class TestIBusTextInjector(unittest.TestCase):
mock_is_active,
mock_get_current,
):
"""Test inject_text returns False when switch to Vocalinux engine fails."""
"""Test inject_text returns False when switch to Voculinux engine fails."""
from vocalinux.text_injection.ibus_engine import IBusTextInjector
injector = IBusTextInjector(auto_activate=False)
result = injector.inject_text("Hello")
self.assertFalse(result)
mock_switch.assert_called_once_with("vocalinux")
mock_switch.assert_called_once_with("voculinux")
@patch("vocalinux.text_injection.ibus_engine.get_current_engine", return_value=None)
@patch("vocalinux.text_injection.ibus_engine.is_engine_active", return_value=False)