Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initial logging functionality #39

Merged
merged 1 commit into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions ulwgl_consts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from enum import Enum
from logging import INFO, WARNING, DEBUG, ERROR

SIMPLE_FORMAT = "%(levelname)s: %(message)s"

DEBUG_FORMAT = "%(levelname)s [%(module)s.%(funcName)s:%(lineno)s]:%(message)s"


class Level(Enum):
"""Represent the Log level values for the logger module."""

INFO = INFO
WARNING = WARNING
DEBUG = DEBUG
ERROR = ERROR


class Color(Enum):
"""Represent the color to be applied to a string."""

RESET = "\u001b[0m"
INFO = "\u001b[34m"
WARNING = "\033[33m"
ERROR = "\033[31m"
BOLD = "\033[1m"
DEBUG = "\u001b[35m"
13 changes: 13 additions & 0 deletions ulwgl_log.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import logging
from sys import stderr
from ulwgl_consts import SIMPLE_FORMAT, DEBUG_FORMAT

simple_formatter = logging.Formatter(SIMPLE_FORMAT)
debug_formatter = logging.Formatter(DEBUG_FORMAT)

log = logging.getLogger(__name__)

console_handler = logging.StreamHandler(stream=stderr)
console_handler.setFormatter(simple_formatter)
log.addHandler(console_handler)
log.setLevel(logging.CRITICAL + 1)
36 changes: 34 additions & 2 deletions ulwgl_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
from re import match
import subprocess
from ulwgl_dl_util import get_ulwgl_proton
from ulwgl_consts import Level
from ulwgl_util import msg
from ulwgl_log import log, console_handler, debug_formatter

verbs: Set[str] = {
"waitforexitandrun",
Expand All @@ -34,6 +37,7 @@ def parse_args() -> Union[Namespace, Tuple[str, List[str]]]: # noqa: D103
WINEPREFIX= GAMEID= PROTONPATH= {exe} ""
WINEPREFIX= GAMEID= PROTONPATH= PROTON_VERB= {exe} /home/foo/example.exe
WINEPREFIX= GAMEID= PROTONPATH= STORE= {exe} /home/foo/example.exe
ULWGL_LOG= GAMEID= {exe} /home/foo/example.exe
{exe} --config /home/foo/example.toml
"""
parser: ArgumentParser = argparse.ArgumentParser(
Expand All @@ -59,6 +63,27 @@ def parse_args() -> Union[Namespace, Tuple[str, List[str]]]: # noqa: D103
return sys.argv[1], sys.argv[2:]


def set_log() -> None:
"""Adjust the log level for the logger."""
levels: Set[str] = {"1", "warn", "debug"}

if os.environ["ULWGL_LOG"] not in levels:
return

if os.environ["ULWGL_LOG"] == "1":
# Show the envvars and command at this level
log.setLevel(level=Level.INFO.value)
elif os.environ["ULWGL_LOG"] == "warn":
log.setLevel(level=Level.WARNING.value)
elif os.environ["ULWGL_LOG"] == "debug":
# Show all logs
console_handler.setFormatter(debug_formatter)
log.addHandler(console_handler)
log.setLevel(level=Level.DEBUG.value)

os.environ.pop("ULWGL_LOG")


def setup_pfx(path: str) -> None:
"""Create a symlink to the WINE prefix and tracked_files file."""
pfx: Path = Path(path).joinpath("pfx").expanduser()
Expand Down Expand Up @@ -115,8 +140,6 @@ def check_env(
else:
env["PROTONPATH"] = os.environ["PROTONPATH"]

print(env["PROTONPATH"], file=sys.stderr)

# If download fails/doesn't exist in the system, raise an error
if not os.environ["PROTONPATH"]:
err: str = "Download failed.\nProton could not be found in cache or compatibilitytools.d\nPlease set $PROTONPATH or visit https://github.com/Open-Wine-Components/ULWGL-Proton/releases"
Expand Down Expand Up @@ -250,6 +273,9 @@ def main() -> int: # noqa: D103
args: Union[Namespace, Tuple[str, List[str]]] = parse_args()
opts: List[str] = None

if "ULWGL_LOG" in os.environ:
set_log()

if isinstance(args, Namespace) and getattr(args, "config", None):
set_env_toml(env, args)
else:
Expand All @@ -266,15 +292,21 @@ def main() -> int: # noqa: D103
# Set all environment variables
# NOTE: `env` after this block should be read only
for key, val in env.items():
log.info(msg(f"{key}={val}", Level.INFO))
os.environ[key] = val

build_command(env, command, opts)
log.debug(msg(command, Level.DEBUG))
return subprocess.run(command).returncode


if __name__ == "__main__":
try:
sys.exit(main())
except KeyboardInterrupt:
# Until Reaper is part of the command sequence, spawned process may still be alive afterwards
log.warning(msg("Keyboard Interrupt", Level.WARNING))
sys.exit(1)
except Exception as e: # noqa: BLE001
print_exception(e)
sys.exit(1)
20 changes: 20 additions & 0 deletions ulwgl_util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from ulwgl_consts import Color, Level
from typing import Any


def msg(msg: Any, level: Level):
"""Return a log message depending on the log level.

The message will bolden the typeface and apply a color.
Expects the first parameter to be a string or implement __str__
"""
log: str = ""

if level == Level.INFO:
log = f"{Color.BOLD.value}{Color.INFO.value}{msg}{Color.RESET.value}"
elif level == Level.WARNING:
log = f"{Color.BOLD.value}{Color.WARNING.value}{msg}{Color.RESET.value}"
elif level == Level.DEBUG:
log = f"{Color.BOLD.value}{Color.DEBUG.value}{msg}{Color.RESET.value}"

return log