Coverage for src / mafw / devtools / cli / documentation / server.py: 96%
47 statements
« prev ^ index » next coverage.py v7.14.0, created at 2026-06-28 13:34 +0000
« prev ^ index » next coverage.py v7.14.0, created at 2026-06-28 13:34 +0000
1# Copyright 2025–2026 European Union
2# Author: Bulgheroni Antonio (antonio.bulgheroni@ec.europa.eu)
3# SPDX-License-Identifier: EUPL-1.2
4"""CLI commands for managing a local documentation server."""
6from __future__ import annotations
8from pathlib import Path
10import click
12from mafw.devtools.documentation.server import (
13 SERVER_DEFAULT_DIRECTORY,
14 ServerStatusEnum,
15 get_server_status,
16 read_server_metadata,
17 server_default_directory,
18 server_metadata_path,
19 server_start_impl,
20 server_stop_by_metadata,
21)
22from mafw.tools.click_extensions import AbbreviateGroup
25@click.group(cls=AbbreviateGroup)
26def server() -> None:
27 """Manage a local web server for browsing documentation over HTTP."""
30@server.command(name='start')
31@click.option('-b', '--bind', 'address', default='127.0.0.1', help='IP address to bind (default: 127.0.0.1).')
32@click.option('-p', '--port', default=8000, type=int, help='Port number where to listen (default: 8000).')
33@click.option(
34 '-d',
35 '--directory',
36 default=SERVER_DEFAULT_DIRECTORY,
37 type=click.Path(file_okay=False, dir_okay=True, path_type=Path),
38 help='Folder to serve (default: docs/build).',
39)
40@click.option(
41 '-l',
42 '--log-file',
43 default=Path('doc-server.log'),
44 type=click.Path(dir_okay=False, path_type=Path),
45 help='Log file for server output (default: doc-server.log).',
46)
47@click.option('-f', '--force-restart', is_flag=True, default=False, help='Force restart if already running.')
48def server_start(address: str, port: int, directory: Path, log_file: Path, force_restart: bool) -> None:
49 """Start a local documentation server (python -m http.server)."""
50 server_start_impl(address=address, port=port, directory=directory, log_file=log_file, force_restart=force_restart)
53@server.command(name='status')
54def server_status() -> None:
55 """Show the current status of the local documentation server."""
56 directory = server_default_directory()
57 meta_path = server_metadata_path(directory)
59 try:
60 status, metadata = get_server_status(directory)
61 except click.ClickException as e:
62 raise click.ClickException(f'{e} (while reading: {meta_path})') from e
64 if status == ServerStatusEnum.unknown:
65 print('status: unknown (metadata not found)')
66 return
68 assert metadata is not None
69 url = f'http://{metadata["address"]}:{metadata["port"]}'
70 print(f'status: {status} ({url})')
73@server.command(name='stop')
74def server_stop() -> None:
75 """Stop the local documentation server."""
76 directory = server_default_directory()
77 server_stop_by_metadata(directory, require_metadata=True)
80@server.command(name='restart')
81def server_restart() -> None:
82 """Restart the local documentation server."""
83 directory = server_default_directory()
84 metadata = read_server_metadata(directory)
85 if metadata is None:
86 server_stop_by_metadata(directory, require_metadata=False)
87 server_start_impl(
88 address='127.0.0.1', port=8000, directory=directory, log_file=Path('doc-server.log'), force_restart=False
89 )
90 return
92 address = metadata.get('address', '127.0.0.1')
93 port = metadata.get('port', 8000)
94 directory_value = metadata.get('directory', str(directory))
95 log_file_value = metadata.get('log_file', str(Path('doc-server.log').resolve()))
97 server_stop_by_metadata(directory, require_metadata=False)
98 server_start_impl(
99 address=str(address),
100 port=int(port),
101 directory=Path(directory_value),
102 log_file=Path(log_file_value),
103 force_restart=False,
104 )