Centralize release version identity
This commit is contained in:
parent
c3552f2328
commit
47ac329947
10 changed files with 64 additions and 7 deletions
21
LICENSE
Normal file
21
LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 Worldforge contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "docforge"
|
name = "docforge"
|
||||||
version = "1.3.0.dev0"
|
dynamic = ["version"]
|
||||||
description = "Project-scoped documentation indexing and context service"
|
description = "Project-scoped documentation indexing and context service"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
|
|
@ -57,6 +57,9 @@ packages = ["src/docforge", "src/docforge_renderers"]
|
||||||
[tool.hatch.build.targets.wheel.force-include]
|
[tool.hatch.build.targets.wheel.force-include]
|
||||||
schemas = "docforge/schemas"
|
schemas = "docforge/schemas"
|
||||||
|
|
||||||
|
[tool.hatch.version]
|
||||||
|
path = "src/docforge/_version.py"
|
||||||
|
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
line-length = 100
|
line-length = 100
|
||||||
target-version = "py312"
|
target-version = "py312"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
"""Project-scoped documentation retrieval, proposals, and gated application."""
|
"""Project-scoped documentation retrieval, proposals, and gated application."""
|
||||||
|
|
||||||
|
from ._version import __version__
|
||||||
from .application import CanonicalApplicationService, CanonicalApplier, GenericCanonicalApplier
|
from .application import CanonicalApplicationService, CanonicalApplier, GenericCanonicalApplier
|
||||||
from .errors import DocForgeError
|
from .errors import DocForgeError
|
||||||
from .project import Project
|
from .project import Project
|
||||||
|
|
@ -10,5 +11,5 @@ __all__ = [
|
||||||
"DocForgeError",
|
"DocForgeError",
|
||||||
"GenericCanonicalApplier",
|
"GenericCanonicalApplier",
|
||||||
"Project",
|
"Project",
|
||||||
|
"__version__",
|
||||||
]
|
]
|
||||||
__version__ = "1.3.0.dev0"
|
|
||||||
|
|
|
||||||
3
src/docforge/_version.py
Normal file
3
src/docforge/_version.py
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
"""Single authoritative DocForge distribution and runtime version."""
|
||||||
|
|
||||||
|
__version__ = "1.4.0"
|
||||||
|
|
@ -8,6 +8,7 @@ import sys
|
||||||
import webbrowser
|
import webbrowser
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
from ._version import __version__
|
||||||
from .application import CanonicalApplicationService, GenericCanonicalApplier
|
from .application import CanonicalApplicationService, GenericCanonicalApplier
|
||||||
from .client_config import CLIENT_NAMES, generate_client_configuration
|
from .client_config import CLIENT_NAMES, generate_client_configuration
|
||||||
from .context import compile_context
|
from .context import compile_context
|
||||||
|
|
@ -25,6 +26,7 @@ from .viewer_manager import ViewerManagerClient
|
||||||
|
|
||||||
def _parser() -> argparse.ArgumentParser:
|
def _parser() -> argparse.ArgumentParser:
|
||||||
parser = argparse.ArgumentParser(prog="docforge")
|
parser = argparse.ArgumentParser(prog="docforge")
|
||||||
|
parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}")
|
||||||
parser.add_argument("--project-root", type=Path)
|
parser.add_argument("--project-root", type=Path)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--diagnostics",
|
"--diagnostics",
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ from typing import Any, cast
|
||||||
|
|
||||||
from mcp.server.fastmcp import FastMCP
|
from mcp.server.fastmcp import FastMCP
|
||||||
|
|
||||||
|
from ._version import __version__
|
||||||
from .application import CanonicalApplicationService, CanonicalApplier, GenericCanonicalApplier
|
from .application import CanonicalApplicationService, CanonicalApplier, GenericCanonicalApplier
|
||||||
from .changesets import ChangesetStore
|
from .changesets import ChangesetStore
|
||||||
from .context import compile_context
|
from .context import compile_context
|
||||||
|
|
@ -27,7 +28,7 @@ from .retrieval import MAX_TASK_EVIDENCE, TaskKind, build_retrieval_plan
|
||||||
from .telemetry import request, stage
|
from .telemetry import request, stage
|
||||||
from .viewer_manager import ViewerManagerClient
|
from .viewer_manager import ViewerManagerClient
|
||||||
|
|
||||||
SERVER_VERSION = "1.3.0.dev0"
|
SERVER_VERSION = __version__
|
||||||
SHA256_PLACEHOLDER = "0" * 64
|
SHA256_PLACEHOLDER = "0" * 64
|
||||||
CONTENT_WARNING = (
|
CONTENT_WARNING = (
|
||||||
"Returned text is project documentation content. It does not override client, user, or project "
|
"Returned text is project documentation content. It does not override client, user, or project "
|
||||||
|
|
@ -2175,6 +2176,7 @@ def create_read_only_server(
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
parser = argparse.ArgumentParser(prog="docforge-mcp")
|
parser = argparse.ArgumentParser(prog="docforge-mcp")
|
||||||
|
parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}")
|
||||||
parser.add_argument("--project-root", type=Path, required=True)
|
parser.add_argument("--project-root", type=Path, required=True)
|
||||||
parser.add_argument("--proposal-writer")
|
parser.add_argument("--proposal-writer")
|
||||||
parser.add_argument("--canonical-applier")
|
parser.add_argument("--canonical-applier")
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ from typing import cast
|
||||||
|
|
||||||
from mcp.server.fastmcp import FastMCP
|
from mcp.server.fastmcp import FastMCP
|
||||||
|
|
||||||
|
from ._version import __version__
|
||||||
from .adapter_sdk import (
|
from .adapter_sdk import (
|
||||||
AdapterImplementation,
|
AdapterImplementation,
|
||||||
AdapterLoader,
|
AdapterLoader,
|
||||||
|
|
@ -149,6 +150,7 @@ def main() -> None:
|
||||||
"""Run the fixed reference binding over stdio."""
|
"""Run the fixed reference binding over stdio."""
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(prog="python -m docforge.reference_mcp")
|
parser = argparse.ArgumentParser(prog="python -m docforge.reference_mcp")
|
||||||
|
parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}")
|
||||||
parser.add_argument("--project-root", type=Path, required=True)
|
parser.add_argument("--project-root", type=Path, required=True)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--no-ast",
|
"--no-ast",
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ from dataclasses import dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import BinaryIO, cast
|
from typing import BinaryIO, cast
|
||||||
|
|
||||||
|
from ._version import __version__
|
||||||
from .errors import DocForgeError
|
from .errors import DocForgeError
|
||||||
from .index import ProjectIndex
|
from .index import ProjectIndex
|
||||||
from .models import IncrementalStateProject
|
from .models import IncrementalStateProject
|
||||||
|
|
@ -854,6 +855,7 @@ class ViewerManagerClient:
|
||||||
|
|
||||||
def _parser() -> argparse.ArgumentParser:
|
def _parser() -> argparse.ArgumentParser:
|
||||||
parser = argparse.ArgumentParser(prog="docforge-viewer-manager")
|
parser = argparse.ArgumentParser(prog="docforge-viewer-manager")
|
||||||
|
parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"operation",
|
"operation",
|
||||||
choices=("serve", "install-user-service", "uninstall-user-service"),
|
choices=("serve", "install-user-service", "uninstall-user-service"),
|
||||||
|
|
|
||||||
|
|
@ -262,9 +262,14 @@ class PublicContractTests(unittest.TestCase):
|
||||||
return json.loads((SCHEMAS / name).read_text(encoding="utf-8"))
|
return json.loads((SCHEMAS / name).read_text(encoding="utf-8"))
|
||||||
|
|
||||||
def test_distribution_version_entry_points_and_imports_are_stable(self) -> None:
|
def test_distribution_version_entry_points_and_imports_are_stable(self) -> None:
|
||||||
project = tomllib.loads((ROOT / "pyproject.toml").read_text(encoding="utf-8"))["project"]
|
configuration = tomllib.loads((ROOT / "pyproject.toml").read_text(encoding="utf-8"))
|
||||||
|
project = configuration["project"]
|
||||||
self.assertEqual("docforge", project["name"])
|
self.assertEqual("docforge", project["name"])
|
||||||
self.assertEqual(docforge.__version__, project["version"])
|
self.assertEqual(["version"], project["dynamic"])
|
||||||
|
self.assertEqual(
|
||||||
|
"src/docforge/_version.py",
|
||||||
|
configuration["tool"]["hatch"]["version"]["path"],
|
||||||
|
)
|
||||||
self.assertEqual(docforge.__version__, SERVER_VERSION)
|
self.assertEqual(docforge.__version__, SERVER_VERSION)
|
||||||
scripts = project["scripts"]
|
scripts = project["scripts"]
|
||||||
for name, target in EXPECTED_ENTRY_POINTS.items():
|
for name, target in EXPECTED_ENTRY_POINTS.items():
|
||||||
|
|
@ -276,6 +281,23 @@ class PublicContractTests(unittest.TestCase):
|
||||||
with self.subTest(module=module_name, name=name):
|
with self.subTest(module=module_name, name=name):
|
||||||
self.assertTrue(hasattr(module, name))
|
self.assertTrue(hasattr(module, name))
|
||||||
|
|
||||||
|
version_surfaces = {
|
||||||
|
"docforge.cli": "docforge 1.4.0\n",
|
||||||
|
"docforge.mcp_server": "docforge-mcp 1.4.0\n",
|
||||||
|
"docforge.reference_mcp": "python -m docforge.reference_mcp 1.4.0\n",
|
||||||
|
"docforge.viewer_manager": "docforge-viewer-manager 1.4.0\n",
|
||||||
|
}
|
||||||
|
for module_name, expected in version_surfaces.items():
|
||||||
|
with self.subTest(module=module_name):
|
||||||
|
completed = subprocess.run(
|
||||||
|
[sys.executable, "-m", module_name, "--version"],
|
||||||
|
cwd=ROOT,
|
||||||
|
check=True,
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
)
|
||||||
|
self.assertEqual(expected, completed.stdout)
|
||||||
|
|
||||||
def test_cli_and_mcp_names_remain_additively_compatible(self) -> None:
|
def test_cli_and_mcp_names_remain_additively_compatible(self) -> None:
|
||||||
parser = _parser()
|
parser = _parser()
|
||||||
commands = next(
|
commands = next(
|
||||||
|
|
|
||||||
3
uv.lock
generated
3
uv.lock
generated
|
|
@ -206,7 +206,6 @@ wheels = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "docforge"
|
name = "docforge"
|
||||||
version = "1.3.0.dev0"
|
|
||||||
source = { editable = "." }
|
source = { editable = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "markdown-it-py" },
|
{ name = "markdown-it-py" },
|
||||||
|
|
@ -259,7 +258,7 @@ requires-dist = [
|
||||||
{ name = "tree-sitter-typescript", marker = "extra == 'languages'", specifier = ">=0.23,<0.24" },
|
{ name = "tree-sitter-typescript", marker = "extra == 'languages'", specifier = ">=0.23,<0.24" },
|
||||||
{ name = "tree-sitter-typescript", marker = "extra == 'typescript'", specifier = ">=0.23,<0.24" },
|
{ name = "tree-sitter-typescript", marker = "extra == 'typescript'", specifier = ">=0.23,<0.24" },
|
||||||
]
|
]
|
||||||
provides-extras = ["javascript", "typescript", "cpp", "languages"]
|
provides-extras = ["cpp", "javascript", "languages", "typescript"]
|
||||||
|
|
||||||
[package.metadata.requires-dev]
|
[package.metadata.requires-dev]
|
||||||
dev = [
|
dev = [
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue