feat(admin-config-tool): task 1.1 - xceadmin package skeleton
Editable-installable xceadmin package with a real click-group entry point (zero subcommands yet) and xcecommon as an independently importable standalone package. Requirements: 5.4
This commit is contained in:
parent
4ad31d774d
commit
b30a856a2d
6 changed files with 248 additions and 0 deletions
29
src/xceadmin/pyproject.toml
Normal file
29
src/xceadmin/pyproject.toml
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
[build-system]
|
||||
requires = ["setuptools>=68"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "xceadmin"
|
||||
version = "0.1.0"
|
||||
description = "XCE cluster configuration admin CLI (config build / config push)"
|
||||
requires-python = ">=3.10"
|
||||
dependencies = [
|
||||
"click>=8.0",
|
||||
]
|
||||
|
||||
# NOT wired into meson (src/meson.build / src/meson.options) — xceadmin is
|
||||
# dispatched by src/tools/xce-build.sh's case-statement pattern instead.
|
||||
# See .kiro/specs/admin-config-tool/design.md, File Structure Plan.
|
||||
|
||||
[project.optional-dependencies]
|
||||
test = ["pytest"]
|
||||
|
||||
[project.scripts]
|
||||
xceadmin = "xceadmin.cli:main"
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
where = ["src"]
|
||||
include = ["xceadmin*", "xcecommon*"]
|
||||
|
||||
[tool.setuptools.package-dir]
|
||||
"" = "src"
|
||||
1
src/xceadmin/src/xceadmin/__init__.py
Normal file
1
src/xceadmin/src/xceadmin/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
"""xceadmin: CLI for building and deploying XCE cluster configuration."""
|
||||
23
src/xceadmin/src/xceadmin/cli.py
Normal file
23
src/xceadmin/src/xceadmin/cli.py
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
"""xceadmin command-line entry point.
|
||||
|
||||
This module wires the ``xceadmin`` console-script entry point to a click
|
||||
command group. It intentionally has zero subcommands for now — ``config
|
||||
build`` and ``config push`` are added by a later task (see
|
||||
.kiro/specs/admin-config-tool/tasks.md, task 4.1).
|
||||
"""
|
||||
|
||||
import click
|
||||
|
||||
|
||||
@click.group()
|
||||
def cli() -> None:
|
||||
"""xceadmin: build and deploy XCE cluster configuration."""
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""Console-script entry point (see pyproject.toml [project.scripts])."""
|
||||
cli()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
9
src/xceadmin/src/xcecommon/__init__.py
Normal file
9
src/xceadmin/src/xcecommon/__init__.py
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
"""xcecommon: shared library for XCE Python tooling.
|
||||
|
||||
Provides capnp schema loading, YAML->capnp mapping, JSON Schema validation,
|
||||
and the TLS wire protocol client shared by ``xceadmin`` and any future
|
||||
Python client of the XCE controller wire protocol.
|
||||
|
||||
This package has no dependency on ``click`` or any CLI-specific concern —
|
||||
it must remain importable on its own, independent of ``xceadmin``.
|
||||
"""
|
||||
44
src/xceadmin/tests/test_cli.py
Normal file
44
src/xceadmin/tests/test_cli.py
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
"""Tests for the xceadmin package skeleton (task 1.1).
|
||||
|
||||
Covers Requirement 5.4: xcecommon is importable as a standalone package
|
||||
independent of xceadmin's CLI, and the xceadmin console-script entry point
|
||||
is backed by a genuinely working (if currently empty) click group.
|
||||
"""
|
||||
|
||||
from click.testing import CliRunner
|
||||
|
||||
from xceadmin.cli import cli
|
||||
|
||||
|
||||
def test_cli_help_exits_zero() -> None:
|
||||
"""`xceadmin --help` must run cleanly and print usage text."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(cli, ["--help"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "Usage:" in result.output
|
||||
|
||||
|
||||
def test_cli_help_shows_zero_commands() -> None:
|
||||
"""The click group has no subcommands yet (config build/push land later)."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(cli, ["--help"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "Commands:" not in result.output
|
||||
|
||||
|
||||
def test_cli_group_invoked_with_no_args_does_not_traceback() -> None:
|
||||
"""Invoking the bare group with no subcommand exits cleanly via click's
|
||||
own SystemExit (no subcommand registered yet), not an unhandled
|
||||
traceback from application code."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(cli, [])
|
||||
|
||||
assert isinstance(result.exception, SystemExit)
|
||||
assert "Usage:" in result.output
|
||||
|
||||
|
||||
def test_xcecommon_is_importable_independent_of_xceadmin() -> None:
|
||||
"""xcecommon must be importable on its own, with no xceadmin import."""
|
||||
import xcecommon # noqa: F401 - import success is the assertion
|
||||
Loading…
Add table
Add a link
Reference in a new issue