Skip to content

Commit

Permalink
Fix return code when subprocess fails (#33)
Browse files Browse the repository at this point in the history
* fix: return 1 when a subprocess fails
* chore: add type hints and docstrings in scripts.py; some linter fixes

---------

Co-authored-by: Martin <[email protected]>
  • Loading branch information
git-developer and C0rn3j authored Sep 28, 2024
1 parent af8a442 commit 926b053
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 57 deletions.
9 changes: 5 additions & 4 deletions AppImageBuilder.test.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@ RUN <<EOR
chmod +x "${file}"
rm -rf squashfs-root/
"${file}" --appimage-extract >/dev/null
cd squashfs-root/runtime/compat
../../AppRun dependency-check
output=$(../../AppRun daemon --help 2>&1 | tee -a /dev/stderr)
if echo "${output}" | grep -q Error; then return 1; fi
(
cd squashfs-root/runtime/compat
../../AppRun dependency-check
../../AppRun daemon --help
)
rm -f "${file}"
done
}
Expand Down
116 changes: 63 additions & 53 deletions scc/scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,51 @@
Contains code for most of what can be done using 'scc' script.
Created so scc-* stuff doesn't polute /usr/bin.
"""
from scc.tools import init_logging, set_logging_level, find_binary
import os, sys, subprocess
from __future__ import annotations

import os
import subprocess
import sys
from typing import TYPE_CHECKING

class InvalidArguments(Exception): pass
if TYPE_CHECKING:
from io import TextIOWrapper


def cmd_daemon(argv0, argv):
""" Controls scc-daemon """
# Actually just passes parameters to scc-daemon
scc_daemon = find_binary("scc-daemon")
subprocess.Popen([scc_daemon] + argv).communicate()
from scc.tools import find_binary, init_logging, set_logging_level


def help_daemon():
scc_daemon = find_binary("scc-daemon")
subprocess.Popen([scc_daemon, "--help"]).communicate()
class InvalidArguments(Exception):
pass

def run_binary(binary_name: str, argv: list[str]) -> int:
"""Run scc-daemon with passed parameters."""
binary = find_binary(binary_name)
child = subprocess.Popen([binary] + argv)
child.communicate()
return child.returncode

def cmd_gui(argv0, argv):
""" Starts GUI """
# Passes parameters to sc-controller
scc_daemon = find_binary("sc-controller")
subprocess.Popen([scc_daemon] + argv).communicate()
def cmd_daemon(argv0: str, argv: list[str]) -> int:
"""Run scc-daemon with passed parameters."""
return run_binary("scc-daemon", argv)


def help_gui():
scc_daemon = find_binary("sc-controller")
subprocess.Popen([scc_daemon, "--help"]).communicate()
def help_daemon() -> int:
"""Run scc-daemon --help."""
return run_binary("scc-daemon", ["--help"])


def cmd_test_evdev(argv0, argv):
def cmd_gui(argv0: str, argv: list[str]) -> int:
"""Run sc-controller(GUI) with passed parameters."""
return run_binary("sc-controller", argv)


def help_gui() -> int:
"""Run sc-controller --help."""
return run_binary("sc-controller", ["--help"])


def cmd_test_evdev(argv0: str, argv: list[str]) -> int:
"""
Evdev driver test. Displays gamepad inputs using evdev driver.
Expand All @@ -48,7 +61,7 @@ def cmd_test_evdev(argv0, argv):
return evdevdrv_test(argv)


def cmd_test_hid(argv0, argv):
def cmd_test_hid(argv0: str, argv: list[str]) -> int:
"""
HID driver test. Displays gamepad inputs using hid driver.
Expand All @@ -64,27 +77,26 @@ def cmd_test_hid(argv0, argv):
return hiddrv_test(HIDController, argv)


def help_osd_keyboard():
def help_osd_keyboard() -> None:
import_osd()
from scc.osd.keyboard import Keyboard
return run_osd_tool(Keyboard(), "osd-keyboard", ["--help"])


def cmd_osd_keyboard(argv0, argv):
""" Displays on-screen keyboard """
def cmd_osd_keyboard(argv0: str, argv: list[str]) -> None:
"""Display on-screen keyboard."""
import_osd()
from scc.osd.keyboard import Keyboard
return run_osd_tool(Keyboard(), argv0, argv)


def cmd_list_profiles(argv0, argv):
"""
Lists available profiles
def cmd_list_profiles(argv0: str, argv: list[str]) -> int:
"""List available profiles.
Usage: scc list-profiles [-a]
Arguments:
-a Include names begining with dot
-a Include names begining with dot
"""
from scc.paths import get_profiles_path, get_default_profiles_path
paths = [ get_default_profiles_path(), get_profiles_path() ]
Expand All @@ -104,9 +116,8 @@ def cmd_list_profiles(argv0, argv):
return 0


def cmd_set_profile(argv0, argv):
"""
Sets controller profile
def cmd_set_profile(argv0: str, argv: list[str]) -> int:
"""Set controller profile.
Usage: scc set-profile [controller_id] "profile name"
"""
Expand Down Expand Up @@ -136,8 +147,8 @@ def cmd_set_profile(argv0, argv):
return 0


def cmd_info(argv0, argv):
""" Displays basic information about running driver """
def cmd_info(argv0: str, argv: list[str]) -> int:
"""Display basic information about running driver."""
s = connect_to_daemon()
if s is None: return -1
# Daemon already sends situable info, so this is mostly reading
Expand All @@ -151,12 +162,12 @@ def cmd_info(argv0, argv):
line = line.strip("\r\n\t ")
if line == "Ready.":
break
elif line.startswith("Current profile:"):
if line.startswith("Current profile:"):
global_profile = line
continue
elif line.startswith("Controller:"):
if line.startswith("Controller:"):
continue
elif line.startswith("Controller profile:"):
if line.startswith("Controller profile:"):
any_controller = True
elif line.startswith("Error:"):
print(line)
Expand All @@ -168,8 +179,8 @@ def cmd_info(argv0, argv):
return 0


def cmd_dependency_check(argv0, argv):
""" Checks if all required libraries are installed on this system """
def cmd_dependency_check(argv0: str, argv: list[str]) -> int:
"""Check if all required libraries are installed on this system."""
try:
import gi
gi.require_version('Gtk', '3.0')
Expand Down Expand Up @@ -201,9 +212,8 @@ def cmd_dependency_check(argv0, argv):
return 0


def cmd_lock_inputs(argv0, argv, lock="Lock: "):
"""
Locks and prints pressed buttons, pads and sticks
def cmd_lock_inputs(argv0: str, argv: list[str], lock: str = "Lock: ") -> int:
"""Lock and print pressed buttons, pads and sticks.
Locks controller inputs and prints buttons, pads and stick as they are
pressed or moved on controller.
Expand Down Expand Up @@ -247,9 +257,8 @@ def cmd_lock_inputs(argv0, argv, lock="Lock: "):
s.close()


def cmd_print_inputs(argv0, argv, lock="Lock: "):
"""
Prints pressed buttons, pads and sticks
def cmd_print_inputs(argv0: str, argv: list[str], lock: str = "Lock: ") -> int:
"""Print pressed buttons, pads and sticks.
Prints controller inputs and prints buttons, pads and stick as they are
pressed or moved on controller, without locking them exclusivelly.
Expand All @@ -268,12 +277,13 @@ def cmd_print_inputs(argv0, argv, lock="Lock: "):
return cmd_lock_inputs(argv0, argv, lock="Observe: ")


def connect_to_daemon():
"""
Returns socket connected to daemon or None if connection failed.
def connect_to_daemon() -> TextIOWrapper | None:
"""Return socket connected to daemon or None if connection failed.
Outputs error message in later case.
"""
import socket

from scc.paths import get_daemon_socket
try:
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
Expand All @@ -284,7 +294,7 @@ def connect_to_daemon():
return s.makefile(mode="rw")


def check_error(s):
def check_error(s) -> bool:
"""
Reads line(s) from socket until "OK." or "Fail:" is read.
Then return True if message is "OK." or prints message to stderr
Expand All @@ -306,19 +316,19 @@ def check_error(s):
return False


def sigint(*a):
def sigint(*a) -> None:
print("\n*break*")
sys.exit(0)


def import_osd():
def import_osd() -> None:
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('Rsvg', '2.0')
gi.require_version('GdkX11', '3.0')


def run_osd_tool(tool, argv0, argv):
def run_osd_tool(tool, argv0: str, argv: list[str]) -> None:
import signal, argparse
signal.signal(signal.SIGINT, sigint)

Expand All @@ -333,7 +343,7 @@ def run_osd_tool(tool, argv0, argv):
sys.exit(tool.get_exit_code())


def show_help(command = None, out=sys.stdout):
def show_help(command = None, out=sys.stdout) -> int:
names = [ x[4:] for x in globals() if x.startswith("cmd_") ]
max_len = max([ len(x) for x in names ])
if command in names:
Expand Down Expand Up @@ -361,7 +371,7 @@ def show_help(command = None, out=sys.stdout):
return 0


def main():
def main() -> None:
init_logging()
if len(sys.argv) < 2:
sys.exit(show_help())
Expand Down

0 comments on commit 926b053

Please sign in to comment.