Coverage for arbejdstimer/cli.py: 100.00%
37 statements
« prev ^ index » next coverage.py v7.0.1, created at 2023-01-02 19:01 +0100
« prev ^ index » next coverage.py v7.0.1, created at 2023-01-02 19:01 +0100
1"""Commandline API gateway for arbejdstimer."""
2import pathlib
3import sys
5import typer
7import arbejdstimer
8import arbejdstimer.arbejdstimer as at
10APP_NAME = 'Working hours (Danish arbejdstimer) or not?'
11APP_ALIAS = 'arbejdstimer'
12app = typer.Typer(
13 add_completion=False,
14 context_settings={'help_option_names': ['-h', '--help']},
15 no_args_is_help=True,
16)
18TEMPLATE_EXAMPLE = """\
19{
20 "api": 1,
21 "application": "arbejdstimer",
22 "operator": "or",
23 "holidays": [
24 {
25 "label": "public holiday",
26 "at": [
27 "2022-12-08"
28 ]
29 },
30 {
31 "label": "some holidays 2022/2023",
32 "at": [
33 "2022-12-23",
34 "2023-01-02"
35 ]
36 }
37 ],
38 "working_hours": [8, 17]
39}
40"""
43@app.callback(invoke_without_command=True)
44def callback(
45 version: bool = typer.Option(
46 False,
47 '-V',
48 '--version',
49 help='Display the arbejdstimer version and exit',
50 is_eager=True,
51 )
52) -> None:
53 """
54 Working hours (Danish arbejdstimer) or not?
56 Given a configuration file detect if today is a work day and
57 if at the time of request is a working hour.
59 Return code of 0 indicates work time, 1 no work time, and 2 usage error.
61 Additional help available per command adding the -h/--help option
62 """
63 if version:
64 typer.echo(f'{APP_NAME} version {arbejdstimer.__version__}')
65 raise typer.Exit()
68@app.command('template')
69def app_template() -> int:
70 """
71 Write a template of a JSON configuration to standard out and exit
72 """
73 sys.stdout.write(TEMPLATE_EXAMPLE)
74 return sys.exit(0)
77@app.command('now')
78def now(
79 conf: str = typer.Option(
80 '',
81 '-c',
82 '--config',
83 help='Path to config file (default is $HOME/.arbejdstimer.json)',
84 metavar='<configpath>',
85 ),
86 strict: bool = typer.Option(
87 False,
88 '-s',
89 '--strict',
90 help='Enforce presence of farming dates in configuration (default is false if not provided)',
91 metavar='<bool>',
92 ),
93) -> int:
94 """
95 Silently answer the question if now is a working hour (per return code 0 for yes, and 1 for no).
96 """
97 command = 'now'
98 config = conf if conf else pathlib.Path.home() / at.DEFAULT_CONFIG_NAME
99 action = (command, '', str(config), bool(strict))
100 return sys.exit(at.main(action))
103def explain_enforce_defaults(conf: str = '', day: str = '', verbose: bool = False, strict: bool = False) -> int:
104 """Until the root cause of https://github.com/tiangolo/typer/issues/106 remains unfixed."""
105 command = 'explain'
106 if verbose:
107 command += '_verbatim'
108 config = conf if conf else pathlib.Path.home() / at.DEFAULT_CONFIG_NAME
109 action = (command, day, str(config), strict)
110 return sys.exit(at.main(action))
113@app.command('explain')
114def explain(
115 conf: str = typer.Option(
116 '',
117 '-c',
118 '--config',
119 help='Path to config file (default is $HOME/.arbejdstimer.json)',
120 metavar='<configpath>',
121 ),
122 day: str = typer.Option(
123 '',
124 '-d',
125 '--day',
126 help='Day sought (default is today)',
127 metavar='<date>',
128 ),
129 strict: bool = typer.Option(
130 False,
131 '-s',
132 '--strict',
133 help='Enforce presence of farming dates in configuration (default is false if not provided)',
134 metavar='<bool>',
135 ),
136 verbose: bool = typer.Option(
137 False,
138 '-v',
139 '--verbose',
140 help='Be more verbatim providing the effective config values (default is false if not provided)',
141 metavar='<bool>',
142 ),
143) -> int:
144 """
145 Explain the answer to the question if now is a working hour
146 (in addition to the return code 0 for yes, and 1 for no).
147 """
148 return explain_enforce_defaults(conf, day, verbose, strict)
151@app.command('version')
152def app_version() -> None:
153 """
154 Display the arbejdstimer version and exit
155 """
156 callback(True)