Coverage for src/pystencilssfg/cli.py: 89%

53 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-04 07:16 +0000

1import sys 

2import os 

3from os import path 

4from typing import NoReturn 

5 

6from argparse import ArgumentParser, BooleanOptionalAction 

7 

8from .config import CommandLineParameters, SfgConfigException 

9 

10 

11def add_newline_arg(parser): 

12 parser.add_argument( 

13 "--newline", 

14 action=BooleanOptionalAction, 

15 default=True, 

16 help="Whether to add a terminating newline to the output.", 

17 ) 

18 

19 

20def cli_main(program="sfg-cli") -> NoReturn: 

21 parser = ArgumentParser( 

22 program, 

23 description="pystencilssfg command-line utility for build system integration", 

24 ) 

25 

26 subparsers = parser.add_subparsers(required=True, title="Subcommands") 

27 

28 version_parser = subparsers.add_parser("version", help="Print version and exit.") 

29 add_newline_arg(version_parser) 

30 version_parser.set_defaults(func=version) 

31 

32 outfiles_parser = subparsers.add_parser( 

33 "list-files", help="List files produced by given codegen script." 

34 ) 

35 

36 outfiles_parser.set_defaults(func=list_files) 

37 CommandLineParameters.add_args_to_parser(outfiles_parser) 

38 add_newline_arg(outfiles_parser) 

39 outfiles_parser.add_argument( 

40 "--sep", type=str, default=" ", dest="sep", help="Separator for list items" 

41 ) 

42 outfiles_parser.add_argument("codegen_script", type=str) 

43 

44 cmake_parser = subparsers.add_parser( 

45 "cmake", help="Operations for CMake integation" 

46 ) 

47 cmake_subparsers = cmake_parser.add_subparsers(required=True) 

48 

49 modpath = cmake_subparsers.add_parser( 

50 "modulepath", help="Print the include path for the pystencils-sfg cmake module" 

51 ) 

52 add_newline_arg(modpath) 

53 modpath.set_defaults(func=print_cmake_modulepath) 

54 

55 findmod = cmake_subparsers.add_parser( 

56 "make-find-module", 

57 help="Creates the pystencils-sfg CMake find module as" 

58 + "'FindPystencilsSfg.cmake' in the current directory.", 

59 ) 

60 findmod.set_defaults(func=make_cmake_find_module) 

61 

62 args = parser.parse_args() 

63 args.func(args) 

64 

65 exit(-1) # should never happen 

66 

67 

68def version(args) -> NoReturn: 

69 from . import __version__ 

70 

71 print(__version__, end=os.linesep if args.newline else "") 

72 

73 exit(0) 

74 

75 

76def list_files(args) -> NoReturn: 

77 cli_params = CommandLineParameters(args) 

78 config = cli_params.get_config() 

79 

80 _, scriptname = path.split(args.codegen_script) 

81 basename = path.splitext(scriptname)[0] 

82 

83 output_files = config._get_output_files(basename) 

84 

85 print( 

86 args.sep.join(str(of) for of in output_files), 

87 end=os.linesep if args.newline else "", 

88 ) 

89 

90 exit(0) 

91 

92 

93def print_cmake_modulepath(args) -> NoReturn: 

94 from .cmake import get_sfg_cmake_modulepath 

95 

96 print(get_sfg_cmake_modulepath(), end=os.linesep if args.newline else "") 

97 exit(0) 

98 

99 

100def make_cmake_find_module(args) -> NoReturn: 

101 from .cmake import make_find_module 

102 

103 make_find_module() 

104 exit(0) 

105 

106 

107def abort_with_config_exception(exception: SfgConfigException, source: str) -> NoReturn: 

108 print(f"Invalid {source} configuration: {exception.args[0]}.", file=sys.stderr) 

109 exit(1)