small script to help launch things in flatpak wine

#!/usr/bin/env python3
import os
import shlex
from pathlib import Path
class ConfigError(Exception):
pass
ENV_KEEP_VARS = frozenset(["HOME", "PWD", "XAUTHORITY", "DISPLAY", "WAYLAND_DISPLAY"])
ENV_KEEP_PREFIX = frozenset(["XDG_"])
def should_keep_var(key: str) -> bool:
if key in ENV_KEEP_VARS:
return True
for prefix in ENV_KEEP_PREFIX:
if key.startswith(prefix):
return True
return False
def build_command(
wine_command: str,
wine_flatpak_app: str,
root_dir_override: str | None = None,
wineprefix_override: str | None = None,
extra_flatpak_arguments: list[str] | None = None,
allow_network: bool = True,
allow_default_filesystem: bool = False,
clean_env: bool = False,
):
if root_dir_override:
root_dir_raw = root_dir_override
else:
root_dir_raw = os.environ.get("WINE_RUNNER_ROOT")
if not root_dir_raw:
raise ConfigError(
"no root directory defined, use the WINE_RUNNER_ROOT env var or the --root-dir argument"
)
orig_root = Path(root_dir_raw)
root_dir = orig_root.absolute()
if not root_dir.is_dir():
raise ConfigError(f"root {root_dir} is not a directory")
if wineprefix_override:
wineprefix_str = wineprefix_override
else:
wineprefix_str = os.environ.get("WINEPREFIX")
if wineprefix_str:
wineprefix = Path(wineprefix_str).absolute()
else:
wineprefix = root_dir / ".wine-prefix"
print(f"using root {root_dir} with prefix {wineprefix}")
if not wineprefix.is_relative_to(root_dir):
print("wineprefix is not under root directory, might not be passed through!")
cwd = Path(".").absolute()
common_args = [
"run",
f"--cwd={cwd}",
]
command_prefix: list[str] = []
if clean_env:
env_cmd = ["env", "-i", "-"]
for k, v in os.environ.items():
if should_keep_var(k):
env_cmd.append(f"{k}={shlex.quote(v)}")
command_prefix = command_prefix + env_cmd
if not allow_default_filesystem:
common_args += [
"--nofilesystem=host:reset",
]
common_args += [
f"--filesystem={root_dir}",
f"--env=WINEPREFIX={wineprefix}",
]
if not allow_network:
common_args += [
"--unshare=network",
]
if extra_flatpak_arguments:
common_args += extra_flatpak_arguments
argv = command_prefix + ["flatpak"]
argv += common_args
if wine_command == "wine":
pass
elif wine_command == "winetricks":
argv.append("--command=winetricks")
else:
raise ConfigError(f"unknown launcher command {wine_command}")
argv.append(wine_flatpak_app)
return argv
def main():
import argparse
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter
)
parser.add_argument(
"--wine-flatpak", default="org.winehq.Wine", help="Wine flatpak to use"
)
parser.add_argument(
"--flatpak-run-arg",
action="append",
help="extra argument to pass to flatpak run",
)
parser.add_argument(
"--root-dir",
type=str,
help="root path to pass over, overrides the env var WINE_RUNNER_ROOT",
)
parser.add_argument(
"--allow-default-filesystem",
action="store_true",
help="do not reset filesystem access settings",
)
parser.add_argument(
"--clean-env",
action="store_true",
help="do not pass environment variables",
)
parser.add_argument(
"--no-network", action="store_true", help="disable network access"
)
parser.add_argument(
"--wineprefix",
type=str,
help="wineprefix path, overrides the env var WINEPREFIX",
)
parser.add_argument(
"-n", "--dry-run", action="store_true", help="do not execute anything"
)
parser.add_argument(
"command", choices=["wine", "winetricks"], help="command to run"
)
parser.add_argument("args", nargs="*")
args = parser.parse_args()
try:
argv = build_command(
wine_command=args.command,
wine_flatpak_app=args.wine_flatpak,
root_dir_override=args.root_dir,
wineprefix_override=args.wineprefix,
extra_flatpak_arguments=args.flatpak_run_arg,
allow_default_filesystem=args.allow_default_filesystem,
allow_network=not args.no_network,
clean_env=args.clean_env,
)
except ConfigError as e:
print(str(e))
return 1
argv += args.args
cmd_str = shlex.join(argv)
print(f"running:\n {cmd_str}")
if args.dry_run:
print("dry run: not executing command")
else:
os.execvp(argv[0], argv)
return 0
if __name__ == "__main__":
import sys
sys.exit(main())
添加评论
点赞收藏
点踩分享查看原文
评论
?
参与讨论