1010
1111from munch import DefaultMunch
1212import yaml
13+ from yamllint import linter
14+ from yamllint .config import YamlLintConfig
1315
1416from decoder import decoder
1517
1820# Where can we expect to find Job definitions?
1921_DEFINITION_DIRECTORY : str = 'data-manager'
2022
23+ # The yamllint configuration file of the repository under test.
24+ # Expected to be in the repo we're running from.
25+ _YAMLLINT_FILE : str = '.yamllint'
26+
2127
2228def _print_test_banner (collection : str ,
2329 job_name : str ,
@@ -27,15 +33,41 @@ def _print_test_banner(collection: str,
2733 print (f'+ collection={ collection } job={ job_name } test={ job_test_name } ' )
2834
2935
30- def _load () -> Tuple [List [DefaultMunch ], int ]:
36+ def _lint (definition_file : str ) -> bool :
37+ """Lints the provided job definition file.
38+ """
39+
40+ if not os .path .isfile (_YAMLLINT_FILE ):
41+ print (f'! The yamllint file ({ _YAMLLINT_FILE } ) is missing' )
42+ return False
43+
44+ errors = linter .run (definition_file , YamlLintConfig (file = _YAMLLINT_FILE ))
45+ if errors :
46+ print (f'! Job definition "{ definition_file } " fails yamllint: -' )
47+ for error in errors :
48+ print (error )
49+ return False
50+
51+ return True
52+
53+
54+ def _load (skip_lint : bool = False ) -> Tuple [List [DefaultMunch ], int ]:
3155 """Loads definition files (all the YAML files in a given directory)
3256 and extracts the definitions that contain at least one test.
57+
58+ If there was a problem loading the files an empty list and
59+ -ve count is returned.
3360 """
3461 job_definitions : List [DefaultMunch ] = []
3562 num_tests : int = 0
3663
3764 jd_filenames : List [str ] = glob .glob (f'{ _DEFINITION_DIRECTORY } /*.yaml' )
3865 for jd_filename in jd_filenames :
66+
67+ if not skip_lint :
68+ if not _lint (jd_filename ):
69+ return [], - 1
70+
3971 with open (jd_filename , 'r' ) as jd_file :
4072 jd : Dict [str , Any ] = yaml .load (jd_file , Loader = yaml .FullLoader )
4173 if jd :
@@ -311,9 +343,15 @@ def main() -> None:
311343 arg_parser .add_argument ('-x' , '--exit-on-failure' , action = 'store_true' ,
312344 help = 'Normally jote reports test failures but'
313345 ' continues with the next test.'
314- ' Setting this flag will force jote to '
346+ ' Setting this flag will force jote to'
315347 ' stop when it encounters the first failure' )
316348
349+ arg_parser .add_argument ('-s' , '--skip-lint' , action = 'store_true' ,
350+ help = 'Normally jote runs the job definition'
351+ ' files against the prevailing lint'
352+ ' configuration of the repository under test.'
353+ ' Using this flag skips that step' )
354+
317355 args : argparse .Namespace = arg_parser .parse_args ()
318356
319357 if args .test and args .job is None :
@@ -326,7 +364,11 @@ def main() -> None:
326364 test_fail_count : int = 0
327365
328366 # Load all the files we can and then run the tests.
329- job_definitions , num_tests = _load ()
367+ job_definitions , num_tests = _load (args .skip_lint )
368+ if num_tests < 0 :
369+ print ('! FAILURE' )
370+ print ('! Definition file has filed yamllint' )
371+ arg_parser .error ('Done (FAILURE)' )
330372
331373 msg : str = 'test' if num_tests == 1 else 'tests'
332374 print (f'# Found { num_tests } { msg } ' )
0 commit comments