refactor: port all sys.exit over to kas exceptions

This patch replaces all direct invocations of sys.exit outside of the
main invocation to KasUserError based exceptions. By that, only one
method for returning is used and return codes can be handled
consistently. In addition, this makes it possible to handle specific
errors differently.

Signed-off-by: Felix Moessbauer <felix.moessbauer@siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
This commit is contained in:
Felix Moessbauer
2023-05-04 04:50:18 +02:00
committed by Jan Kiszka
parent a5750901c6
commit 222f07de69
11 changed files with 122 additions and 46 deletions

View File

@@ -40,6 +40,7 @@ from kas.config import Config
from kas.libkas import find_program, run_cmd
from kas.libcmds import Macro, Command
from kas.libkas import setup_parser_common_args
from kas.kasusererror import CommandExecError
__license__ = 'MIT'
__copyright__ = 'Copyright (c) Siemens AG, 2017-2018'
@@ -114,8 +115,7 @@ class BuildCommand(Command):
logging.info('%s$ %s', ctx.build_dir, ' '.join(cmd))
ret = subprocess.call(cmd, env=ctx.environ, cwd=ctx.build_dir)
if ret != 0:
logging.error('Command returned non-zero exit status %d', ret)
sys.exit(ret)
raise CommandExecError(cmd, ret)
else:
run_cmd(cmd, cwd=ctx.build_dir)

View File

@@ -63,7 +63,6 @@
Note, that the lockfiles should be checked-in into the VCS.
"""
import logging
import sys
import json
import yaml
@@ -71,11 +70,17 @@ from typing import TypeVar, TextIO
from collections import OrderedDict
from kas.context import get_context
from kas.plugins.checkout import Checkout
from kas.kasusererror import KasUserError, ArgsCombinationError
__license__ = 'MIT'
__copyright__ = 'Copyright (c) Siemens AG, 2022'
class OutputFormatError(KasUserError):
def __init__(self, format):
super().__init__('invalid format {}'.format(format))
class IoTarget:
StrOrTextIO = TypeVar('StrOrTextIO', str, TextIO)
@@ -184,8 +189,7 @@ class Dump(Checkout):
output = IoTarget(target=sys.stdout, managed=False)
if args.inplace and not args.lock:
logging.error('--inplace requires --lock')
sys.exit(1)
raise ArgsCombinationError('--inplace requires --lock')
if args.lock:
args.resolve_refs = True
@@ -220,8 +224,7 @@ class Dump(Checkout):
indent=args.indent,
Dumper=self.KasYamlDumper)
else:
logging.error('invalid format %s', args.format)
sys.exit(1)
raise OutputFormatError(args.format)
__KAS_PLUGINS__ = [Dump]

View File

@@ -56,13 +56,13 @@
import logging
import os
import subprocess
import sys
from kas.context import create_global_context
from kas.config import Config
from kas.libcmds import Macro, Command, SetupHome
from kas.libkas import setup_parser_common_args
from kas.libkas import setup_parser_preserve_env_arg
from kas.libkas import run_handle_preserve_env_arg
from kas.kasusererror import CommandExecError
__license__ = 'MIT'
__copyright__ = 'Copyright (c) Siemens AG, 2017-2018'
@@ -113,8 +113,7 @@ class ForAllReposCommand(Command):
retcode = subprocess.call(self.command, shell=True, cwd=repo.path,
env=env)
if retcode != 0:
logging.error('Command failed with return code %d', retcode)
sys.exit(retcode)
raise CommandExecError(self.command, retcode)
__KAS_PLUGINS__ = [ForAllRepos]

View File

@@ -69,7 +69,6 @@
import logging
import os
import pprint
import sys
import yaml
from kconfiglib import Kconfig, Symbol, Choice, expr_value, TYPE_TO_STR, \
MENU, COMMENT, STRING, BOOL, INT, HEX, UNKNOWN
@@ -78,6 +77,7 @@ from kas.context import create_global_context
from kas.config import CONFIG_YAML_FILE
from kas.includehandler import load_config as load_config_yaml
from kas.plugins.build import Build
from kas.kasusererror import KasUserError
try:
from snack import SnackScreen, EntryWindow, ButtonChoiceWindow, \
@@ -92,10 +92,18 @@ __copyright__ = \
'Copyright (c) Siemens AG, 2021'
class VariableTypeError(KasUserError):
pass
class MissingModuleError(KasUserError):
pass
def check_sym_is_string(sym):
if sym.type != STRING:
logging.error('Variable %s must be of string type', sym.name)
sys.exit(1)
raise VariableTypeError('Variable {} must be of string type'
.format(sym.name))
def str_representer(dumper, data):
@@ -175,10 +183,9 @@ class Menu:
elif sym.type == HEX:
menu_configuration[symname] = int(symvalue, 16)
else:
logging.error(
'Configuration variable %s uses unsupported type',
symname)
sys.exit(1)
raise VariableTypeError(
'Configuration variable {} uses unsupported type'
.format(symname))
if symname.startswith('KAS_INCLUDE_'):
check_sym_is_string(sym)
@@ -241,9 +248,8 @@ class Menu:
def run(self, args):
if not newt_available:
logging.error(
raise MissingModuleError(
'Menu plugin requires \'python3-newt\' distribution package.')
sys.exit(1)
ctx = create_global_context(args)

View File

@@ -40,13 +40,13 @@
import logging
import os
import subprocess
import sys
from kas.context import create_global_context
from kas.config import Config
from kas.libcmds import Macro, Command, SetupHome
from kas.libkas import setup_parser_common_args
from kas.libkas import setup_parser_preserve_env_arg
from kas.libkas import run_handle_preserve_env_arg
from kas.kasusererror import CommandExecError
__license__ = 'MIT'
__copyright__ = 'Copyright (c) Siemens AG, 2017-2018'
@@ -124,8 +124,8 @@ class ShellCommand(Command):
cmd.append(self.cmd)
ret = subprocess.call(cmd, env=ctx.environ, cwd=ctx.build_dir)
if ret != 0:
logging.error('Shell returned non-zero exit status %d', ret)
sys.exit(ret)
logging.error('Shell returned non-zero exit status')
raise CommandExecError(cmd, ret, True)
__KAS_PLUGINS__ = [Shell]