Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1from argparse import ArgumentParser 

2import logging 

3from typing import Dict, Any 

4import flashflow.cmd.coord 

5import flashflow.cmd.ctrl 

6import flashflow.cmd.measurer 

7from . import __version__ 

8from .config import get_config, config_logging 

9 

10 

11log = logging.getLogger(__name__) 

12 

13 

14def create_parser(): 

15 p = ArgumentParser() 

16 p.add_argument('--version', action='version', version=__version__) 

17 p.add_argument('-c', '--config', help='Path to flashflow config file') 

18 # p.add_argument('--log-level', 

19 # choices=['debug', 'info', 'warning', 'error', 'critical'], 

20 # help='Override the configured flashflow log level') 

21 sub = p.add_subparsers(dest='cmd') 

22 flashflow.cmd.coord.gen_parser(sub) 

23 flashflow.cmd.ctrl.gen_parser(sub) 

24 flashflow.cmd.measurer.gen_parser(sub) 

25 return p 

26 

27 

28# This function needs **some sort** of type annotation so that mypy will check 

29# the things it does. Adding the return value (e.g. '-> None') is enough 

30def call_real_main(args, conf) -> None: 

31 ''' Figure out what FlashFlow command the user gave and call into that 

32 command's main function where the real work begins to happen. The only 

33 logic here should be figuring out what command's main to call. ''' 

34 # Most (actually, all as of right now) command's main functions take these 

35 # arguments 

36 def_args = [args, conf] 

37 def_kwargs: Dict[str, Any] = {} 

38 # How to call in to each command's main 

39 cmds = { 

40 'coord': { 

41 'f': flashflow.cmd.coord.main, 

42 'a': def_args, 'kw': def_kwargs, 

43 }, 

44 'ctrl': { 

45 'f': flashflow.cmd.ctrl.main, 

46 'a': def_args, 'kw': def_kwargs, 

47 }, 

48 'measurer': { 

49 'f': flashflow.cmd.measurer.main, 

50 'a': def_args, 'kw': def_kwargs, 

51 }, 

52 } 

53 # The keys in the `cmds` dict must be the same as each command specified in 

54 # its gen_parser(...) function, thus it will be in `cmds`. args.cmd will 

55 # also be non-None because our caller must have checked that already. 

56 assert args.cmd in cmds 

57 # Here we go! 

58 cmd = cmds[args.cmd] 

59 return cmd['f'](*cmd['a'], *cmd['kw']) # type: ignore 

60 

61 

62def main() -> None: 

63 ''' Entry point when called on the command line as `flashflow ...`. 

64 

65 Do boring boilerplate stuff to get started initially. Parse the command 

66 line arguments and configuration file, then hand off control. This is where 

67 the bulk of the startup boring crap should happen. ''' 

68 p = create_parser() 

69 args = p.parse_args() 

70 if args.cmd is None: 

71 p.print_help() 

72 return 

73 try: 

74 conf = get_config(args.config) 

75 except FileNotFoundError as e: 

76 log.critical('Unable to open a config file: %s', e) 

77 return 

78 assert conf 

79 config_logging(conf) 

80 call_real_main(args, conf)