Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
uv tool install git+https://github.com/databricks/ucode
```

Check your version with `ucode --version`. Between releases this looks like
`0.1.0+14.g93986a8` — the trailing `g<hash>` is the exact commit the build came
from, so include it when reporting a bug.

---

## Usage
Expand Down
28 changes: 23 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
[build-system]
requires = ["uv_build>=0.11.0"]
build-backend = "uv_build"
requires = ["hatchling", "uv-dynamic-versioning>=0.7.0"]
build-backend = "hatchling.build"

[project]
name = "ucode"
version = "0.1.0"
# Version is derived from git tags at build time (see [tool.uv-dynamic-versioning]).
# On a tag it is the plain tag (e.g. `0.1.0`); between tags it carries the commit
# count and short hash (e.g. `0.1.0+14.g93986a8`) so a reported version maps back
# to an exact commit.
dynamic = ["version"]
description = "Bootstrap Codex against a Databricks workspace with minimal setup."
readme = "README.md"
requires-python = ">=3.12"
Expand All @@ -29,8 +33,22 @@ tracing = ["mlflow[databricks]>=3.4"]
[project.scripts]
ucode = "ucode.cli:main"

[tool.uv.build-backend]
module-name = "ucode"
[tool.hatch.build.targets.wheel]
packages = ["src/ucode"]

[tool.hatch.version]
source = "uv-dynamic-versioning"

[tool.uv-dynamic-versioning]
vcs = "git"
# On a tagged commit: plain tag (e.g. `0.1.0`). Between tags: append the commit
# count and short hash as a local segment (e.g. `0.1.0+14.g93986a8`) so a
# reported version points back to an exact commit for bug reports.
format-jinja = "{% if distance == 0 %}{{ base }}{% else %}{{ base }}+{{ distance }}.g{{ commit }}{% endif %}"
# Used only when git metadata is unavailable at build time (e.g. building from a
# source archive with no `.git`). The normal install paths clone the repo, so
# this is a last-resort so builds degrade instead of hard-failing.
fallback-version = "0.0.0"

[dependency-groups]
dev = [
Expand Down
24 changes: 24 additions & 0 deletions src/ucode/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -875,6 +875,30 @@ def revert() -> int:
app.add_typer(mcp_app, name="mcp", help="MCP servers exposed by ucode.")


def _version_callback(value: bool) -> None:
if value:
from ucode.telemetry import ucode_version

print(ucode_version())
raise typer.Exit()


@app.callback()
def _main(
version: Annotated[
bool,
typer.Option(
"--version",
"-V",
help="Show the ucode version and exit.",
callback=_version_callback,
is_eager=True,
),
] = False,
) -> None:
"""Configure and launch coding agents through Databricks AI Gateway."""


@mcp_app.command("web-search")
def mcp_web_search_cmd() -> None:
"""Run the web_search MCP server over stdio. Invoked as a subprocess by Claude Code."""
Expand Down
17 changes: 17 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,23 @@ def test_configure_help_lists_agents_flag(self):
assert "--workspaces" in output


class TestVersion:
@pytest.mark.parametrize("flag", ["--version", "-V"])
def test_prints_version_and_exits(self, flag):
result = runner.invoke(app, [flag])
assert result.exit_code == 0
# Matches the derived version reported by importlib.metadata — either a
# real string like "0.1.0" / "0.1.0+2.g93986a8" or the "unknown" fallback.
assert _strip_ansi(result.output).strip() != ""

def test_matches_telemetry_version(self):
from ucode.telemetry import ucode_version

result = runner.invoke(app, ["--version"])
assert result.exit_code == 0
assert ucode_version() in _strip_ansi(result.output)


def _patch_launch(tool: str):
"""Return a context-manager stack that makes _launch_tool a no-op.

Expand Down
Loading