Edit on GitHub

hexdoc.cli.utils

 1__all__ = [
 2    "DefaultTyper",
 3    "init_context",
 4    "load_common_data",
 5    "render_textures_and_export_metadata",
 6]
 7
 8from .args import (
 9    DefaultTyper,
10)
11from .load import (
12    init_context,
13    load_common_data,
14    render_textures_and_export_metadata,
15)
def DefaultTyper( *, name: Optional[str] = <typer.models.DefaultPlaceholder object>, cls: Optional[Type[typer.core.TyperGroup]] = <typer.models.DefaultPlaceholder object>, invoke_without_command: bool = <typer.models.DefaultPlaceholder object>, no_args_is_help: bool = <typer.models.DefaultPlaceholder object>, subcommand_metavar: Optional[str] = <typer.models.DefaultPlaceholder object>, chain: bool = <typer.models.DefaultPlaceholder object>, result_callback: Optional[Callable[..., Any]] = <typer.models.DefaultPlaceholder object>, context_settings: Optional[Dict[Any, Any]] = <typer.models.DefaultPlaceholder object>, callback: Optional[Callable[..., Any]] = <typer.models.DefaultPlaceholder object>, help: Optional[str] = <typer.models.DefaultPlaceholder object>, epilog: Optional[str] = <typer.models.DefaultPlaceholder object>, short_help: Optional[str] = <typer.models.DefaultPlaceholder object>, options_metavar: str = <typer.models.DefaultPlaceholder object>, add_help_option: bool = <typer.models.DefaultPlaceholder object>, hidden: bool = <typer.models.DefaultPlaceholder object>, deprecated: bool = <typer.models.DefaultPlaceholder object>, add_completion: bool = True, rich_markup_mode: Literal['markdown', 'rich', None] = <typer.models.DefaultPlaceholder object>, rich_help_panel: Optional[str] = <typer.models.DefaultPlaceholder object>, suggest_commands: bool = True, pretty_exceptions_enable: bool = True, pretty_exceptions_show_locals: bool = True, pretty_exceptions_short: bool = True):
114class Typer:
115    def __init__(
116        self,
117        *,
118        name: Optional[str] = Default(None),
119        cls: Optional[Type[TyperGroup]] = Default(None),
120        invoke_without_command: bool = Default(False),
121        no_args_is_help: bool = Default(False),
122        subcommand_metavar: Optional[str] = Default(None),
123        chain: bool = Default(False),
124        result_callback: Optional[Callable[..., Any]] = Default(None),
125        # Command
126        context_settings: Optional[Dict[Any, Any]] = Default(None),
127        callback: Optional[Callable[..., Any]] = Default(None),
128        help: Optional[str] = Default(None),
129        epilog: Optional[str] = Default(None),
130        short_help: Optional[str] = Default(None),
131        options_metavar: str = Default("[OPTIONS]"),
132        add_help_option: bool = Default(True),
133        hidden: bool = Default(False),
134        deprecated: bool = Default(False),
135        add_completion: bool = True,
136        # Rich settings
137        rich_markup_mode: MarkupMode = Default(DEFAULT_MARKUP_MODE),
138        rich_help_panel: Union[str, None] = Default(None),
139        suggest_commands: bool = True,
140        pretty_exceptions_enable: bool = True,
141        pretty_exceptions_show_locals: bool = True,
142        pretty_exceptions_short: bool = True,
143    ):
144        self._add_completion = add_completion
145        self.rich_markup_mode: MarkupMode = rich_markup_mode
146        self.rich_help_panel = rich_help_panel
147        self.suggest_commands = suggest_commands
148        self.pretty_exceptions_enable = pretty_exceptions_enable
149        self.pretty_exceptions_show_locals = pretty_exceptions_show_locals
150        self.pretty_exceptions_short = pretty_exceptions_short
151        self.info = TyperInfo(
152            name=name,
153            cls=cls,
154            invoke_without_command=invoke_without_command,
155            no_args_is_help=no_args_is_help,
156            subcommand_metavar=subcommand_metavar,
157            chain=chain,
158            result_callback=result_callback,
159            context_settings=context_settings,
160            callback=callback,
161            help=help,
162            epilog=epilog,
163            short_help=short_help,
164            options_metavar=options_metavar,
165            add_help_option=add_help_option,
166            hidden=hidden,
167            deprecated=deprecated,
168        )
169        self.registered_groups: List[TyperInfo] = []
170        self.registered_commands: List[CommandInfo] = []
171        self.registered_callback: Optional[TyperInfo] = None
172
173    def callback(
174        self,
175        *,
176        cls: Optional[Type[TyperGroup]] = Default(None),
177        invoke_without_command: bool = Default(False),
178        no_args_is_help: bool = Default(False),
179        subcommand_metavar: Optional[str] = Default(None),
180        chain: bool = Default(False),
181        result_callback: Optional[Callable[..., Any]] = Default(None),
182        # Command
183        context_settings: Optional[Dict[Any, Any]] = Default(None),
184        help: Optional[str] = Default(None),
185        epilog: Optional[str] = Default(None),
186        short_help: Optional[str] = Default(None),
187        options_metavar: str = Default("[OPTIONS]"),
188        add_help_option: bool = Default(True),
189        hidden: bool = Default(False),
190        deprecated: bool = Default(False),
191        # Rich settings
192        rich_help_panel: Union[str, None] = Default(None),
193    ) -> Callable[[CommandFunctionType], CommandFunctionType]:
194        def decorator(f: CommandFunctionType) -> CommandFunctionType:
195            self.registered_callback = TyperInfo(
196                cls=cls,
197                invoke_without_command=invoke_without_command,
198                no_args_is_help=no_args_is_help,
199                subcommand_metavar=subcommand_metavar,
200                chain=chain,
201                result_callback=result_callback,
202                context_settings=context_settings,
203                callback=f,
204                help=help,
205                epilog=epilog,
206                short_help=short_help,
207                options_metavar=options_metavar,
208                add_help_option=add_help_option,
209                hidden=hidden,
210                deprecated=deprecated,
211                rich_help_panel=rich_help_panel,
212            )
213            return f
214
215        return decorator
216
217    def command(
218        self,
219        name: Optional[str] = None,
220        *,
221        cls: Optional[Type[TyperCommand]] = None,
222        context_settings: Optional[Dict[Any, Any]] = None,
223        help: Optional[str] = None,
224        epilog: Optional[str] = None,
225        short_help: Optional[str] = None,
226        options_metavar: str = "[OPTIONS]",
227        add_help_option: bool = True,
228        no_args_is_help: bool = False,
229        hidden: bool = False,
230        deprecated: bool = False,
231        # Rich settings
232        rich_help_panel: Union[str, None] = Default(None),
233    ) -> Callable[[CommandFunctionType], CommandFunctionType]:
234        if cls is None:
235            cls = TyperCommand
236
237        def decorator(f: CommandFunctionType) -> CommandFunctionType:
238            self.registered_commands.append(
239                CommandInfo(
240                    name=name,
241                    cls=cls,
242                    context_settings=context_settings,
243                    callback=f,
244                    help=help,
245                    epilog=epilog,
246                    short_help=short_help,
247                    options_metavar=options_metavar,
248                    add_help_option=add_help_option,
249                    no_args_is_help=no_args_is_help,
250                    hidden=hidden,
251                    deprecated=deprecated,
252                    # Rich settings
253                    rich_help_panel=rich_help_panel,
254                )
255            )
256            return f
257
258        return decorator
259
260    def add_typer(
261        self,
262        typer_instance: "Typer",
263        *,
264        name: Optional[str] = Default(None),
265        cls: Optional[Type[TyperGroup]] = Default(None),
266        invoke_without_command: bool = Default(False),
267        no_args_is_help: bool = Default(False),
268        subcommand_metavar: Optional[str] = Default(None),
269        chain: bool = Default(False),
270        result_callback: Optional[Callable[..., Any]] = Default(None),
271        # Command
272        context_settings: Optional[Dict[Any, Any]] = Default(None),
273        callback: Optional[Callable[..., Any]] = Default(None),
274        help: Optional[str] = Default(None),
275        epilog: Optional[str] = Default(None),
276        short_help: Optional[str] = Default(None),
277        options_metavar: str = Default("[OPTIONS]"),
278        add_help_option: bool = Default(True),
279        hidden: bool = Default(False),
280        deprecated: bool = Default(False),
281        # Rich settings
282        rich_help_panel: Union[str, None] = Default(None),
283    ) -> None:
284        self.registered_groups.append(
285            TyperInfo(
286                typer_instance,
287                name=name,
288                cls=cls,
289                invoke_without_command=invoke_without_command,
290                no_args_is_help=no_args_is_help,
291                subcommand_metavar=subcommand_metavar,
292                chain=chain,
293                result_callback=result_callback,
294                context_settings=context_settings,
295                callback=callback,
296                help=help,
297                epilog=epilog,
298                short_help=short_help,
299                options_metavar=options_metavar,
300                add_help_option=add_help_option,
301                hidden=hidden,
302                deprecated=deprecated,
303                rich_help_panel=rich_help_panel,
304            )
305        )
306
307    def __call__(self, *args: Any, **kwargs: Any) -> Any:
308        if sys.excepthook != except_hook:
309            sys.excepthook = except_hook
310        try:
311            return get_command(self)(*args, **kwargs)
312        except Exception as e:
313            # Set a custom attribute to tell the hook to show nice exceptions for user
314            # code. An alternative/first implementation was a custom exception with
315            # raise custom_exc from e
316            # but that means the last error shown is the custom exception, not the
317            # actual error. This trick improves developer experience by showing the
318            # actual error last.
319            setattr(
320                e,
321                _typer_developer_exception_attr_name,
322                DeveloperExceptionConfig(
323                    pretty_exceptions_enable=self.pretty_exceptions_enable,
324                    pretty_exceptions_show_locals=self.pretty_exceptions_show_locals,
325                    pretty_exceptions_short=self.pretty_exceptions_short,
326                ),
327            )
328            raise e
def init_context( *, book_id: hexdoc.core.ResourceLocation, book_data: dict[str, typing.Any], pm: hexdoc.plugin.PluginManager, loader: hexdoc.core.ModResourceLoader, i18n: hexdoc.minecraft.I18n, all_metadata: dict[str, hexdoc.data.HexdocMetadata]):
117def init_context(
118    *,
119    book_id: ResourceLocation,
120    book_data: dict[str, Any],
121    pm: PluginManager,
122    loader: ModResourceLoader,
123    i18n: I18n,
124    all_metadata: dict[str, HexdocMetadata],
125):
126    props = loader.props
127
128    context = dict[str, Any]()
129
130    for item in [
131        props,
132        pm,
133        loader,
134        i18n,
135        TextureContext(
136            textures=load_metadata_textures(all_metadata),
137            allowed_missing_textures=props.textures.missing,
138        ),
139        FormattingContext(
140            book_id=book_id,
141            macros=DEFAULT_MACROS | book_data.get("macros", {}) | props.macros,
142        ),
143        BookContext(
144            modid=props.modid,
145            book_id=book_id,
146            spoilered_advancements=Tag.SPOILERED_ADVANCEMENTS.load(
147                loader
148            ).value_ids_set,
149            all_metadata=all_metadata,
150            flags=pm.load_flags(),
151        ),
152    ]:
153        item.add_to_context(context)
154
155    for item in pm.update_context(context):
156        item.add_to_context(context)
157
158    return context
def load_common_data( props_file: pathlib.Path, branch: str, *, book: bool = False) -> tuple[hexdoc.core.Properties, hexdoc.plugin.PluginManager, hexdoc.plugin.BookPlugin[typing.Any], hexdoc.plugin.ModPlugin]:
50def load_common_data(
51    props_file: Path,
52    branch: str,
53    *,
54    book: bool = False,
55) -> tuple[Properties, PluginManager, BookPlugin[Any], ModPlugin]:
56    props = Properties.load(props_file)
57    pm = PluginManager(branch, props)
58
59    book_plugin = pm.book_plugin(props.book_type)
60    mod_plugin = pm.mod_plugin(props.modid, book=book)
61
62    header = get_header(props, pm, mod_plugin)
63    logger.info(f"Loading hexdoc.\n{indent(header, '  ')}")
64
65    minecraft_version = MinecraftVersion.MINECRAFT_VERSION = pm.minecraft_version()
66    if minecraft_version is None:
67        logger.warning(
68            "No plugins implement minecraft_version. All versions may be used."
69        )
70
71    return props, pm, book_plugin, mod_plugin
def render_textures_and_export_metadata( loader: hexdoc.core.ModResourceLoader, asset_loader: hexdoc.minecraft.assets.HexdocAssetLoader):
 74def render_textures_and_export_metadata(
 75    loader: ModResourceLoader,
 76    asset_loader: HexdocAssetLoader,
 77):
 78    all_metadata = loader.load_metadata(model_type=HexdocMetadata)
 79
 80    all_lookups = load_metadata_textures(all_metadata)
 81    image_textures = {
 82        id: texture
 83        for texture_type in [PNGTexture, AnimatedTexture]
 84        for id, texture in texture_type.get_lookup(all_lookups).items()
 85    }
 86
 87    internal_lookups = TextureLookups[Texture](dict)
 88    if loader.props.textures.enabled:
 89        logger.info(f"Loading and rendering textures to {asset_loader.render_dir}.")
 90        for id, texture in asset_loader.load_and_render_internal_textures(
 91            image_textures
 92        ):
 93            texture.insert_texture(internal_lookups, id)
 94
 95    # this mod's metadata
 96    metadata = HexdocMetadata(
 97        book_url=asset_loader.site_url / loader.props.default_lang,
 98        asset_url=loader.props.env.asset_url,
 99        textures=internal_lookups,
100    )
101
102    loader.export(
103        metadata.path(loader.props.modid),
104        metadata.model_dump_json(
105            by_alias=True,
106            warnings=False,
107            exclude_defaults=True,
108            round_trip=True,
109        ),
110        cache=True,
111    )
112
113    return all_metadata | {loader.props.modid: metadata}