mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-10-28 22:15:38 +00:00
Update AppImage deps and fix packaging
This commit is contained in:
10 files changed
+459
-141
No files matched your search
Executable
+134
@@ -0,0 +1,134 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Exercise an extracted AppImage without borrowing the build interpreter."""
|
||||
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
|
||||
PROBE = r'''
|
||||
import bz2, ctypes, curses, dbm.gnu, json, lzma, pathlib, readline, sqlite3, ssl, sys, tkinter, zlib
|
||||
import cffi, _cffi_backend, pycparser
|
||||
root = pathlib.Path(sys.argv[1]).resolve()
|
||||
assert pathlib.Path(sys.base_prefix).resolve() == root / 'usr', sys.base_prefix
|
||||
for module in (cffi, _cffi_backend, pycparser, ssl, sqlite3):
|
||||
assert pathlib.Path(module.__file__).resolve().is_relative_to(root), module.__file__
|
||||
assert cffi.FFI().sizeof('int') > 0
|
||||
assert tkinter.Tcl().eval('info patchlevel').startswith('8.6.')
|
||||
assert ssl.create_default_context().get_ca_certs(), 'No trusted CA certificates'
|
||||
gio = ctypes.CDLL('libgio-2.0.so.0')
|
||||
gio.g_tls_backend_get_default.restype = ctypes.c_void_p
|
||||
gio.g_tls_backend_supports_tls.argtypes = [ctypes.c_void_p]
|
||||
assert gio.g_tls_backend_supports_tls(gio.g_tls_backend_get_default()), 'GIO TLS backend unavailable'
|
||||
print(json.dumps({'python': sys.version, 'openssl': ssl.OPENSSL_VERSION,
|
||||
'cffi': cffi.__version__, 'pycparser': pycparser.__version__}))
|
||||
'''
|
||||
|
||||
PYTHON_PLUGIN = r'''
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import zoitechat, hexchat, xchat
|
||||
__module_name__ = 'AppImage Python check'
|
||||
__module_version__ = '1'
|
||||
root = Path(os.environ['ZOITECHAT_SMOKE'])
|
||||
(root / 'python.ok').write_text(sys.version)
|
||||
def finish(userdata):
|
||||
if all((root / (name + '.ok')).is_file() for name in ('python', 'perl', 'lua')):
|
||||
# Return from Python before shutdown unloads the native plugin.
|
||||
zoitechat.command('TIMER 0.1 KILLALL')
|
||||
return False
|
||||
return True
|
||||
zoitechat.hook_timer(100, finish)
|
||||
'''
|
||||
|
||||
PERL_PLUGIN = r'''
|
||||
use strict;
|
||||
use warnings;
|
||||
use File::Spec;
|
||||
use Encode;
|
||||
ZoiteChat::register('AppImage Perl check', '1', 'Runtime check');
|
||||
open my $marker, '>', File::Spec->catfile($ENV{ZOITECHAT_SMOKE}, 'perl.ok') or die $!;
|
||||
print {$marker} $^V;
|
||||
close $marker or die $!;
|
||||
'''
|
||||
|
||||
LUA_PLUGIN = r'''
|
||||
zoitechat.register('AppImage Lua check', '1', 'Runtime check')
|
||||
local marker = assert(io.open(os.getenv('ZOITECHAT_SMOKE') .. '/lua.ok', 'w'))
|
||||
marker:write(_VERSION)
|
||||
marker:close()
|
||||
'''
|
||||
|
||||
|
||||
def run(command, env):
|
||||
try:
|
||||
result = subprocess.run(command, env=env, text=True, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE, timeout=90)
|
||||
except subprocess.TimeoutExpired as error:
|
||||
raise RuntimeError(f"{command[0]} timed out:\n{error.stdout}\n{error.stderr}") from error
|
||||
if result.returncode:
|
||||
raise RuntimeError(f"{command[0]} failed:\n{result.stdout}\n{result.stderr}")
|
||||
return result.stdout.strip()
|
||||
|
||||
|
||||
def main():
|
||||
appdir = Path(sys.argv[1]).resolve()
|
||||
env = os.environ.copy()
|
||||
for key in ("PYTHONHOME", "PYTHONPATH", "PERL5LIB", "LD_LIBRARY_PATH",
|
||||
"GIO_MODULE_DIR", "GIO_EXTRA_MODULES"):
|
||||
env.pop(key, None)
|
||||
env.update({
|
||||
"APPDIR": str(appdir),
|
||||
"PYTHONHOME": str(appdir / "usr"),
|
||||
"PYTHONNOUSERSITE": "1",
|
||||
"LD_LIBRARY_PATH": f"{appdir}/usr/lib:{appdir}/usr/lib/x86_64-linux-gnu",
|
||||
"SSL_CERT_FILE": str(appdir / "etc/ssl/certs/ca-certificates.crt"),
|
||||
"SSL_CERT_DIR": str(appdir / "etc/ssl/certs"),
|
||||
"GDK_BACKEND": "x11",
|
||||
"TCL_LIBRARY": str(appdir / "usr/share/tcltk/tcl8.6"),
|
||||
"TK_LIBRARY": str(appdir / "usr/share/tcltk/tk8.6"),
|
||||
})
|
||||
for relative in ("usr/lib/x86_64-linux-gnu/gio/modules", "usr/lib/gio/modules"):
|
||||
if (appdir / relative).is_dir():
|
||||
env["GIO_MODULE_DIR"] = str(appdir / relative)
|
||||
env["GIO_EXTRA_MODULES"] = str(appdir / relative)
|
||||
break
|
||||
perl_dirs = [appdir / "usr/lib/x86_64-linux-gnu/perl-base"]
|
||||
for relative in ("usr/lib/x86_64-linux-gnu/perl", "usr/lib/x86_64-linux-gnu/perl5", "usr/share/perl"):
|
||||
perl_dirs.extend(sorted((appdir / relative).glob("*")))
|
||||
perl_dirs.append(appdir / "usr/share/perl5")
|
||||
env["PERL5LIB"] = ":".join(str(path) for path in perl_dirs if path.is_dir())
|
||||
runtime = json.loads(run([str(appdir / "usr/bin/python3"), "-s", "-c", PROBE, str(appdir)], env))
|
||||
expected = dict(line.split("=", 1) for line in
|
||||
Path(__file__).with_name("python.env").read_text().splitlines()
|
||||
if line and not line.startswith("#"))["PYTHON_VERSION"]
|
||||
assert runtime["python"].split()[0] == expected, runtime
|
||||
runtime["perl"] = run([str(appdir / "usr/bin/perl"), "-MFile::Spec", "-MEncode", "-MPOSIX",
|
||||
"-MJSON::PP", "-e", "print $^V"], env)
|
||||
|
||||
with tempfile.TemporaryDirectory(prefix="zoitechat-smoke-") as temporary:
|
||||
config = Path(temporary)
|
||||
(config / "zoitechat.conf").write_text("gui_slist_skip = 1\n")
|
||||
autoload = config / "addons"
|
||||
autoload.mkdir()
|
||||
for filename, content in (("smoke.py", PYTHON_PLUGIN), ("smoke.pl", PERL_PLUGIN), ("smoke.lua", LUA_PLUGIN)):
|
||||
(autoload / filename).write_text(content)
|
||||
env["HOME"] = temporary
|
||||
env["XDG_CONFIG_HOME"] = temporary
|
||||
env["ZOITECHAT_SMOKE"] = temporary
|
||||
output = run(["xvfb-run", "-a", "dbus-run-session", "--", str(appdir / "AppRun"),
|
||||
"--run-as-root", "--no-auto", "--cfgdir", temporary], env)
|
||||
for name in ("python", "perl", "lua"):
|
||||
assert (config / f"{name}.ok").is_file(), f"{name} plugin failed:\n{output}"
|
||||
runtime["lua"] = (config / "lua.ok").read_text()
|
||||
|
||||
(appdir.parent / "runtime.json").write_text(json.dumps(runtime, indent=2) + "\n")
|
||||
print(json.dumps(runtime, indent=2))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user