Coverage for .tox/coverage/lib/python3.11/site-packages/wuttjamaican/cli/base.py: 100%

21 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2024-12-05 21:27 -0600

1# -*- coding: utf-8; -*- 

2################################################################################ 

3# 

4# WuttJamaican -- Base package for Wutta Framework 

5# Copyright © 2023-2024 Lance Edgar 

6# 

7# This file is part of Wutta Framework. 

8# 

9# Wutta Framework is free software: you can redistribute it and/or modify it 

10# under the terms of the GNU General Public License as published by the Free 

11# Software Foundation, either version 3 of the License, or (at your option) any 

12# later version. 

13# 

14# Wutta Framework is distributed in the hope that it will be useful, but 

15# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 

16# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 

17# more details. 

18# 

19# You should have received a copy of the GNU General Public License along with 

20# Wutta Framework. If not, see <http://www.gnu.org/licenses/>. 

21# 

22################################################################################ 

23""" 

24WuttJamaican - core command logic 

25 

26See also :doc:`/narr/cli/index`. 

27 

28.. data:: wutta_typer 

29 

30 This is the top-level ``wutta`` :term:`command`, using the Typer 

31 framework. 

32 

33 See also :func:`make_typer()`. 

34""" 

35 

36import logging 

37from pathlib import Path 

38from typing import List, Optional 

39 

40import typer 

41from typing_extensions import Annotated 

42 

43from wuttjamaican.conf import make_config 

44from wuttjamaican.util import load_entry_points 

45 

46 

47def make_cli_config(ctx: typer.Context): 

48 """ 

49 Make a :term:`config object` according to the command-line context 

50 (params). 

51 

52 This function is normally called by :func:`typer_callback()`. 

53 

54 This function calls :func:`~wuttjamaican.conf.make_config()` using 

55 config files specified via command line (if any). 

56 

57 :param ctx: ``typer.Context`` instance 

58 

59 :returns: :class:`~wuttjamaican.conf.WuttaConfig` instance 

60 """ 

61 logging.basicConfig() 

62 return make_config(files=ctx.params.get('config_paths') or None) 

63 

64 

65def typer_callback( 

66 ctx: typer.Context, 

67 

68 config_paths: Annotated[ 

69 Optional[List[Path]], 

70 typer.Option('--config', '-c', 

71 exists=True, 

72 help="Config path (may be specified more than once)")] = None, 

73): 

74 """ 

75 Generic callback for use with top-level commands. This adds some 

76 top-level args: 

77 

78 * ``--config`` (and ``-c``) 

79 

80 This callback is responsible for creating the :term:`config 

81 object` for the command. (It calls :func:`make_cli_config()` for 

82 that.) It then attaches it to the context as 

83 ``ctx.wutta_config``. 

84 """ 

85 ctx.wutta_config = make_cli_config(ctx) 

86 

87 

88def typer_eager_imports( 

89 group: [typer.Typer, str]): 

90 """ 

91 Eagerly import all modules which are registered as having 

92 :term:`subcommands <subcommand>` belonging to the given group 

93 (i.e. top-level :term:`command`). 

94 

95 This is used to locate subcommands which may be defined by 

96 multiple different packages. It is mostly needed for the main 

97 ``wutta`` command, since e.g. various extension packages may 

98 define additional subcommands for it. 

99 

100 Most custom apps will define their own top-level command and some 

101 subcommands, but will have no need to "discover" additional 

102 subcommands defined elsewhere. Hence you normally would not need 

103 to call this function. 

104 

105 However if you wish to define a ``wutta`` subcommand(s), you 

106 *would* need to register the entry point for your module(s) 

107 containing the subcommand(s) like so (in ``pyproject.toml``): 

108 

109 .. code-block:: ini 

110 

111 [project.entry-points."wutta.typer_imports"] 

112 poser = "poser.commands" 

113 

114 Note that the ``wutta.typer_imports`` above indicates you are 

115 registering a module which defines ``wutta`` subcommands. The 

116 ``poser`` name is arbitrary but should match your package name. 

117 

118 :param group: Typer group command, or the name of one. 

119 """ 

120 if isinstance(group, typer.Typer): 

121 group = group.info.name 

122 load_entry_points(f'{group}.typer_imports') 

123 

124 

125def make_typer(**kwargs): 

126 """ 

127 Create a Typer command instance, per Wutta conventions. 

128 

129 This function is used to create the top-level ``wutta`` command, 

130 :data:`wutta_typer`. You can use it to create additional 

131 top-level commands for your app if needed. (And don't forget to 

132 register; see :doc:`/narr/cli/custom`.) 

133 

134 :param callback: Override for the ``Typer.callback`` param. If 

135 not specified, :func:`typer_callback` is used. 

136 

137 :returns: ``typer.Typer`` instance 

138 """ 

139 kwargs.setdefault('callback', typer_callback) 

140 return typer.Typer(**kwargs) 

141 

142 

143wutta_typer = make_typer( 

144 name='wutta', 

145 help="Wutta Software Framework" 

146)