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:
+19
-19
@@ -116,10 +116,10 @@ def test_record_audits_payload_and_preserves_export_digests(tmp_path: Path) -> N
|
||||
(source / "src/vocalinux/version.py").write_text('__version__ = "0.18.5"\n')
|
||||
root = tmp_path / "install"
|
||||
distribution(root, "demo", "1.0")
|
||||
distribution(root, "vocalinux", "0.18.5")
|
||||
distribution(root, "voculinux", "0.18.5")
|
||||
CHECK.record(root, source)
|
||||
manifest = json.loads((root / CHECK.MANIFEST).read_text())
|
||||
assert manifest["packages"] == {"demo": "1.0", "vocalinux": "0.18.5"}
|
||||
assert manifest["packages"] == {"demo": "1.0", "voculinux": "0.18.5"}
|
||||
assert manifest["python"] == list(sys.version_info[:2])
|
||||
for name, digest in manifest["exports"].items():
|
||||
assert digest == hashlib.sha256((source / "requirements" / name).read_bytes()).hexdigest()
|
||||
@@ -154,12 +154,12 @@ def test_launchers_are_relocatable_and_keep_locked_packages_first(
|
||||
header = (
|
||||
f"#!/bin/sh\n'''exec' {python} \"$0\" \"$@\"\n' '''\n" if long_shebang else f"#!{python}\n"
|
||||
)
|
||||
for name in ("vocalinux", "vocalinux-gui", "pwcpp"):
|
||||
for name in ("voculinux", "voculinux-gui", "pwcpp"):
|
||||
path = binary / name
|
||||
path.write_text(header + "print('entry point')\n")
|
||||
path.chmod(0o755)
|
||||
(binary / "python3").symlink_to(sys.executable)
|
||||
site = distribution(install, "vocalinux", "0.18.5")
|
||||
site = distribution(install, "voculinux", "0.18.5")
|
||||
package = site / "vocalinux"
|
||||
package.mkdir()
|
||||
(package / "__init__.py").write_text("")
|
||||
@@ -169,13 +169,13 @@ def test_launchers_are_relocatable_and_keep_locked_packages_first(
|
||||
platform.mkdir(parents=True)
|
||||
(platform / "__init__.py").write_text("raise RuntimeError('wrong runtime')\n")
|
||||
BUILD.relocate_scripts(install, tooling)
|
||||
for name in ("vocalinux", "vocalinux-gui", "pwcpp"):
|
||||
for name in ("voculinux", "voculinux-gui", "pwcpp"):
|
||||
text = (binary / name).read_text()
|
||||
assert text.startswith("#!/usr/bin/env python3\n")
|
||||
assert str(tooling) not in text
|
||||
assert os.access(binary / name, os.X_OK)
|
||||
result = subprocess.run(
|
||||
[str(binary / "vocalinux")],
|
||||
[str(binary / "voculinux")],
|
||||
env={
|
||||
**os.environ,
|
||||
"PATH": f"{binary}{os.pathsep}{os.environ['PATH']}",
|
||||
@@ -211,7 +211,7 @@ def test_build_orchestration_uses_hashes_and_separates_tooling(
|
||||
def run(argv: list[str], cwd: Path, env: dict[str, str]) -> None:
|
||||
calls.append((argv, cwd, env.copy()))
|
||||
if str(source) == argv[-1]:
|
||||
for name in ("vocalinux", "vocalinux-gui"):
|
||||
for name in ("voculinux", "voculinux-gui"):
|
||||
(install / "bin" / name).write_text(f"#!{argv[0]}\n")
|
||||
|
||||
monkeypatch.setattr(BUILD.venv.EnvBuilder, "create", create)
|
||||
@@ -309,7 +309,7 @@ def test_runtime_pip_flags_reject_corrupt_artifact_offline(tmp_path: Path) -> No
|
||||
environment = tmp_path / "tooling"
|
||||
venv.EnvBuilder(with_pip=True).create(environment)
|
||||
wheel = tmp_path / "demo-1.0-py3-none-any.whl"
|
||||
real_zipfile = getattr(sys, "_vocalinux_real_zipfile", zipfile)
|
||||
real_zipfile = getattr(sys, "_voculinux_real_zipfile", zipfile)
|
||||
with real_zipfile.ZipFile(wheel, "w") as archive:
|
||||
archive.writestr("demo.py", "VALUE = 1\n")
|
||||
archive.writestr(
|
||||
@@ -369,7 +369,7 @@ def test_full_python_payload_build_is_offline_and_keeps_project_metadata(tmp_pat
|
||||
(source / "src/vocalinux/version.py").write_text('__version__ = "0.18.5"\n')
|
||||
wheelhouse = tmp_path / "wheels"
|
||||
wheelhouse.mkdir()
|
||||
real_zipfile = getattr(sys, "_vocalinux_real_zipfile", zipfile)
|
||||
real_zipfile = getattr(sys, "_voculinux_real_zipfile", zipfile)
|
||||
|
||||
def wheel(name: str, version: str, files: dict[str, str]) -> Path:
|
||||
path = wheelhouse / f"{name}-{version}-py3-none-any.whl"
|
||||
@@ -399,13 +399,13 @@ def test_full_python_payload_build_is_offline_and_keeps_project_metadata(tmp_pat
|
||||
)
|
||||
runtime = wheel("demo", "1.0", {"demo.py": "VALUE = 1\n"})
|
||||
app = wheel(
|
||||
"vocalinux",
|
||||
"voculinux",
|
||||
"0.18.5",
|
||||
{
|
||||
"vocalinux/__init__.py": "",
|
||||
"vocalinux/main.py": "def main():\n print('fixture app')\n",
|
||||
"vocalinux-0.18.5.dist-info/entry_points.txt": "[console_scripts]\nvocalinux = vocalinux.main:main\n"
|
||||
"[gui_scripts]\nvocalinux-gui = vocalinux.main:main\n",
|
||||
"voculinux-0.18.5.dist-info/entry_points.txt": "[console_scripts]\nvoculinux = vocalinux.main:main\n"
|
||||
"[gui_scripts]\nvoculinux-gui = vocalinux.main:main\n",
|
||||
},
|
||||
)
|
||||
for filename, name, version, artifact in (
|
||||
@@ -421,7 +421,7 @@ def test_full_python_payload_build_is_offline_and_keeps_project_metadata(tmp_pat
|
||||
metadata = source / "pyproject.toml"
|
||||
metadata.write_text(
|
||||
'[build-system]\nrequires = []\nbuild-backend = "backend"\nbackend-path = ["."]\n'
|
||||
'[project]\nname = "vocalinux"\nversion = "0.18.5"\ndependencies = ["PyGObject"]\n'
|
||||
'[project]\nname = "voculinux"\nversion = "0.18.5"\ndependencies = ["PyGObject"]\n'
|
||||
)
|
||||
(source / "backend.py").write_text(
|
||||
"import shutil\nfrom pathlib import Path\n"
|
||||
@@ -434,11 +434,11 @@ def test_full_python_payload_build_is_offline_and_keeps_project_metadata(tmp_pat
|
||||
install = tmp_path / "install"
|
||||
BUILD.build(source, install, tmp_path / "work")
|
||||
assert metadata.read_bytes() == before
|
||||
CHECK.audit(install, {"demo": "1.0", "vocalinux": "0.18.5"})
|
||||
CHECK.audit(install, {"demo": "1.0", "voculinux": "0.18.5"})
|
||||
assert not list((tmp_path / "work").iterdir())
|
||||
assert not (install / "bin/pip").exists()
|
||||
result = subprocess.run(
|
||||
[str(install / "bin/python3"), str(install / "bin/vocalinux")],
|
||||
[str(install / "bin/python3"), str(install / "bin/voculinux")],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=5,
|
||||
@@ -464,7 +464,7 @@ def test_artifact_smoke_refuses_user_install_and_checks_the_supplied_file(
|
||||
"with open(os.environ['SNAP_TEST_LOG'], 'a') as stream:\n"
|
||||
" stream.write(json.dumps([Path(sys.argv[0]).name, sys.argv[1:], "
|
||||
"os.environ.get('PYNPUT_BACKEND')]) + '\\n')\n"
|
||||
"if sys.argv[1:3] == ['list', 'vocalinux']:\n"
|
||||
"if sys.argv[1:3] == ['list', 'voculinux']:\n"
|
||||
" sys.exit(0 if os.environ['SNAP_TEST_EXISTING'] == '1' else 1)\n"
|
||||
)
|
||||
path.chmod(0o755)
|
||||
@@ -490,8 +490,8 @@ def test_artifact_smoke_refuses_user_install_and_checks_the_supplied_file(
|
||||
else:
|
||||
assert result.returncode == 0, result.stderr
|
||||
assert calls[1][:2] == ["sudo", ["snap", "install", "--dangerous", str(artifact)]]
|
||||
assert calls[2][:2] == ["snap", ["run", "vocalinux", "--version"]]
|
||||
assert calls[3][1][:4] == ["run", "--shell", "vocalinux", "-c"]
|
||||
assert calls[2][:2] == ["snap", ["run", "voculinux", "--version"]]
|
||||
assert calls[3][1][:4] == ["run", "--shell", "voculinux", "-c"]
|
||||
assert '"$SNAP/snap/command-chain/desktop-launch"' in calls[3][1][4]
|
||||
assert '"$SNAP/usr/lib/vocalinux/check_runtime.py"' in calls[3][1][4]
|
||||
assert '"$SNAP/usr/lib/voculinux/check_runtime.py"' in calls[3][1][4]
|
||||
assert calls[3][2] == "dummy"
|
||||
|
||||
Reference in New Issue
Block a user