Skip to content

Commit

Permalink
Adding inputs (i.e. options incl. value)
Browse files Browse the repository at this point in the history
- adding command line option -I/--input
- adding inputs to CheckSuite, ComplianceChecker and BaseCheck
  • Loading branch information
sol1105 committed Jun 12, 2024
1 parent 8d29c8e commit 059d73d
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 4 deletions.
47 changes: 47 additions & 0 deletions cchecker.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,30 @@ def parse_options(opts):
return options_dict


def parse_inputs(inputs):
"""
Helper function to parse possible inputs. Splits input after the first
and second colon to split into checker/key/value triplets.
:param inputs: Iterable of strings with inputs
:rtype: dict
:return: Dictionary of dictionaries, with first level keys as checker
type (i.e. "cf", "acdd") and second level keys as options.
"""
inputs_dict = {}
for input_str in inputs:
try:
checker_type, checker_opt, checker_val = input_str.split(":", 2)
except ValueError:
warnings.warn(f"Could not split input {input_str}, ignoring", stacklevel=2)
else:
try:
inputs_dict[checker_type].update({checker_opt: checker_val})
except KeyError:
inputs_dict[checker_type] = {checker_opt: checker_val}
return inputs_dict


def main():
# Load all available checker classes
check_suite = CheckSuite()
Expand Down Expand Up @@ -185,6 +209,26 @@ def main():
),
)

parser.add_argument(
"-I",
"--input",
default=[],
action="append",
help=dedent(
"""
Additional input options to be passed to the
checkers. Multiple input options can be specified
via multiple invocations of this switch.
Input options should be prefixed with a the
checker name followed by the input name and the value , e.g.
'<checker>:<input_name>:<input_value>'
For now this switch exists to support more complex command line options
for plugins.
""",
),
)

parser.add_argument(
"-V",
"--version",
Expand Down Expand Up @@ -236,6 +280,7 @@ def main():
sys.exit(0)

options_dict = parse_options(args.option) if args.option else defaultdict(set)
inputs_dict = parse_inputs(args.input) if args.input else {}

if args.describe_checks:
error_stat = 0
Expand Down Expand Up @@ -306,6 +351,7 @@ def main():
args.output[0],
args.format or ["text"],
options=options_dict,
inputs=inputs_dict,
)
return_values.append(return_value)
had_errors.append(errors)
Expand All @@ -326,6 +372,7 @@ def main():
output,
args.format or ["text"],
options=options_dict,
inputs=inputs_dict,
)
return_values.append(return_value)
had_errors.append(errors)
Expand Down
6 changes: 5 additions & 1 deletion compliance_checker/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,16 @@ def setup(self, ds):
Automatically run when running a CheckSuite. Define this method in your Checker class.
"""

def __init__(self, options=None):
def __init__(self, options=None, inputs=None):
self._defined_results = defaultdict(lambda: defaultdict(dict))
if options is None:
self.options = set()
else:
self.options = options
if inputs is None:
self.inputs = {}
else:
self.inputs = inputs

def get_test_ctx(self, severity, name, variable=None):
"""
Expand Down
3 changes: 2 additions & 1 deletion compliance_checker/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ def run_checker(
output_filename="-",
output_format="text",
options=None,
inputs=None,
):
"""
Static check runner.
Expand All @@ -58,7 +59,7 @@ def run_checker(
@returns If the tests failed (based on the criteria)
"""
all_groups = []
cs = CheckSuite(options=options or {})
cs = CheckSuite(options=options or {}, inputs=inputs or {})
# using OrderedDict is important here to preserve the order
# of multiple datasets which may be passed in
score_dict = OrderedDict()
Expand Down
6 changes: 4 additions & 2 deletions compliance_checker/suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,10 @@ class CheckSuite:
) # Base dict of checker names to BaseCheck derived types, override this in your CheckSuite implementation
templates_root = "compliance_checker" # modify to load alternative Jinja2 templates

def __init__(self, options=None):
def __init__(self, options=None, inputs=None):
self.col_width = 40
self.options = options or {}
self.inputs = inputs or {}

@classmethod
def _get_generator_plugins(cls):
Expand Down Expand Up @@ -402,10 +403,11 @@ def run_all(self, ds, checker_names, include_checks=None, skip_checks=None):
# version baked in
checker_type_name = checker_name.split(":")[0]
checker_opts = self.options.get(checker_type_name, set())
checker_inpts = self.inputs.get(checker_type_name, {})

# instantiate a Checker object
try:
checker = checker_class(options=checker_opts)
checker = checker_class(options=checker_opts, inputs=checker_inpts)
# hacky fix for no options in constructor
except TypeError:
checker = checker_class()
Expand Down

0 comments on commit 059d73d

Please sign in to comment.