Skip to content

Commit 926b053

Browse files
Fix return code when subprocess fails (kozec#33)
* 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]>
1 parent af8a442 commit 926b053

File tree

2 files changed

+68
-57
lines changed

2 files changed

+68
-57
lines changed

AppImageBuilder.test.Dockerfile

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,11 @@ RUN <<EOR
4141
chmod +x "${file}"
4242
rm -rf squashfs-root/
4343
"${file}" --appimage-extract >/dev/null
44-
cd squashfs-root/runtime/compat
45-
../../AppRun dependency-check
46-
output=$(../../AppRun daemon --help 2>&1 | tee -a /dev/stderr)
47-
if echo "${output}" | grep -q Error; then return 1; fi
44+
(
45+
cd squashfs-root/runtime/compat
46+
../../AppRun dependency-check
47+
../../AppRun daemon --help
48+
)
4849
rm -f "${file}"
4950
done
5051
}

scc/scripts.py

Lines changed: 63 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,51 @@
33
Contains code for most of what can be done using 'scc' script.
44
Created so scc-* stuff doesn't polute /usr/bin.
55
"""
6-
from scc.tools import init_logging, set_logging_level, find_binary
7-
import os, sys, subprocess
6+
from __future__ import annotations
87

8+
import os
9+
import subprocess
10+
import sys
11+
from typing import TYPE_CHECKING
912

10-
class InvalidArguments(Exception): pass
13+
if TYPE_CHECKING:
14+
from io import TextIOWrapper
1115

1216

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

1919

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

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

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

3134

32-
def help_gui():
33-
scc_daemon = find_binary("sc-controller")
34-
subprocess.Popen([scc_daemon, "--help"]).communicate()
35+
def help_daemon() -> int:
36+
"""Run scc-daemon --help."""
37+
return run_binary("scc-daemon", ["--help"])
3538

3639

37-
def cmd_test_evdev(argv0, argv):
40+
def cmd_gui(argv0: str, argv: list[str]) -> int:
41+
"""Run sc-controller(GUI) with passed parameters."""
42+
return run_binary("sc-controller", argv)
43+
44+
45+
def help_gui() -> int:
46+
"""Run sc-controller --help."""
47+
return run_binary("sc-controller", ["--help"])
48+
49+
50+
def cmd_test_evdev(argv0: str, argv: list[str]) -> int:
3851
"""
3952
Evdev driver test. Displays gamepad inputs using evdev driver.
4053
@@ -48,7 +61,7 @@ def cmd_test_evdev(argv0, argv):
4861
return evdevdrv_test(argv)
4962

5063

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

6679

67-
def help_osd_keyboard():
80+
def help_osd_keyboard() -> None:
6881
import_osd()
6982
from scc.osd.keyboard import Keyboard
7083
return run_osd_tool(Keyboard(), "osd-keyboard", ["--help"])
7184

7285

73-
def cmd_osd_keyboard(argv0, argv):
74-
""" Displays on-screen keyboard """
86+
def cmd_osd_keyboard(argv0: str, argv: list[str]) -> None:
87+
"""Display on-screen keyboard."""
7588
import_osd()
7689
from scc.osd.keyboard import Keyboard
7790
return run_osd_tool(Keyboard(), argv0, argv)
7891

7992

80-
def cmd_list_profiles(argv0, argv):
81-
"""
82-
Lists available profiles
93+
def cmd_list_profiles(argv0: str, argv: list[str]) -> int:
94+
"""List available profiles.
8395
8496
Usage: scc list-profiles [-a]
8597
8698
Arguments:
87-
-a Include names begining with dot
99+
-a Include names begining with dot
88100
"""
89101
from scc.paths import get_profiles_path, get_default_profiles_path
90102
paths = [ get_default_profiles_path(), get_profiles_path() ]
@@ -104,9 +116,8 @@ def cmd_list_profiles(argv0, argv):
104116
return 0
105117

106118

107-
def cmd_set_profile(argv0, argv):
108-
"""
109-
Sets controller profile
119+
def cmd_set_profile(argv0: str, argv: list[str]) -> int:
120+
"""Set controller profile.
110121
111122
Usage: scc set-profile [controller_id] "profile name"
112123
"""
@@ -136,8 +147,8 @@ def cmd_set_profile(argv0, argv):
136147
return 0
137148

138149

139-
def cmd_info(argv0, argv):
140-
""" Displays basic information about running driver """
150+
def cmd_info(argv0: str, argv: list[str]) -> int:
151+
"""Display basic information about running driver."""
141152
s = connect_to_daemon()
142153
if s is None: return -1
143154
# Daemon already sends situable info, so this is mostly reading
@@ -151,12 +162,12 @@ def cmd_info(argv0, argv):
151162
line = line.strip("\r\n\t ")
152163
if line == "Ready.":
153164
break
154-
elif line.startswith("Current profile:"):
165+
if line.startswith("Current profile:"):
155166
global_profile = line
156167
continue
157-
elif line.startswith("Controller:"):
168+
if line.startswith("Controller:"):
158169
continue
159-
elif line.startswith("Controller profile:"):
170+
if line.startswith("Controller profile:"):
160171
any_controller = True
161172
elif line.startswith("Error:"):
162173
print(line)
@@ -168,8 +179,8 @@ def cmd_info(argv0, argv):
168179
return 0
169180

170181

171-
def cmd_dependency_check(argv0, argv):
172-
""" Checks if all required libraries are installed on this system """
182+
def cmd_dependency_check(argv0: str, argv: list[str]) -> int:
183+
"""Check if all required libraries are installed on this system."""
173184
try:
174185
import gi
175186
gi.require_version('Gtk', '3.0')
@@ -201,9 +212,8 @@ def cmd_dependency_check(argv0, argv):
201212
return 0
202213

203214

204-
def cmd_lock_inputs(argv0, argv, lock="Lock: "):
205-
"""
206-
Locks and prints pressed buttons, pads and sticks
215+
def cmd_lock_inputs(argv0: str, argv: list[str], lock: str = "Lock: ") -> int:
216+
"""Lock and print pressed buttons, pads and sticks.
207217
208218
Locks controller inputs and prints buttons, pads and stick as they are
209219
pressed or moved on controller.
@@ -247,9 +257,8 @@ def cmd_lock_inputs(argv0, argv, lock="Lock: "):
247257
s.close()
248258

249259

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

270279

271-
def connect_to_daemon():
272-
"""
273-
Returns socket connected to daemon or None if connection failed.
280+
def connect_to_daemon() -> TextIOWrapper | None:
281+
"""Return socket connected to daemon or None if connection failed.
282+
274283
Outputs error message in later case.
275284
"""
276285
import socket
286+
277287
from scc.paths import get_daemon_socket
278288
try:
279289
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
@@ -284,7 +294,7 @@ def connect_to_daemon():
284294
return s.makefile(mode="rw")
285295

286296

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

308318

309-
def sigint(*a):
319+
def sigint(*a) -> None:
310320
print("\n*break*")
311321
sys.exit(0)
312322

313323

314-
def import_osd():
324+
def import_osd() -> None:
315325
import gi
316326
gi.require_version('Gtk', '3.0')
317327
gi.require_version('Rsvg', '2.0')
318328
gi.require_version('GdkX11', '3.0')
319329

320330

321-
def run_osd_tool(tool, argv0, argv):
331+
def run_osd_tool(tool, argv0: str, argv: list[str]) -> None:
322332
import signal, argparse
323333
signal.signal(signal.SIGINT, sigint)
324334

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

335345

336-
def show_help(command = None, out=sys.stdout):
346+
def show_help(command = None, out=sys.stdout) -> int:
337347
names = [ x[4:] for x in globals() if x.startswith("cmd_") ]
338348
max_len = max([ len(x) for x in names ])
339349
if command in names:
@@ -361,7 +371,7 @@ def show_help(command = None, out=sys.stdout):
361371
return 0
362372

363373

364-
def main():
374+
def main() -> None:
365375
init_logging()
366376
if len(sys.argv) < 2:
367377
sys.exit(show_help())

0 commit comments

Comments
 (0)