Skip to content

Commit 2e0c8a7

Browse files
Coding-Dev-ToolsDevForge Engineercowork-bot
authored
chore: declare revenueholdings_license as optional 'license' extra (#33)
* build, test: fix packaging config and add edge-case tests - Adds include-package-data + [tool.setuptools.package-data] deploydiff = ['py.typed'] - Fixes known-first-party from ['*'] to ['deploydiff'] - Adds test_edge_cases.py with 11 tests (render cost decrease/increase, load_plan no-input, load_pricing nonexistent/custom, pulumi rollback, cloudformation rollback with/without raw_data, packaging parity) - Fixes ruff import sorting (I001) across 1 source + nested imports in tests * style: fix ruff I001 import ordering in test_edge_cases.py * fix: remove unused imports in edge case tests (ruff F401) * cowork-bot: fix click_to_mcp eager import breaks all tests when not installed cli.py imported run_for_app from mcp_server at module level; mcp_server.py imported click_to_mcp at module level. click_to_mcp is an optional dep, so any environment without it (CI, pip install deploydiff without [mcp]) raised ModuleNotFoundError on import of cli — making the entire test suite fail at collection time. Fix: lazy imports in both files — click_to_mcp is now imported only inside the functions that need it (run_mcp / run_for_app / mcp()), with a clear error message + exit 1 when missing. All 97 existing tests pass; ruff clean. * cowork-bot: seed cowork-auto-pr workflow for PR automation * chore: declare revenueholdings_license as optional 'license' extra --------- Co-authored-by: DevForge Engineer <engineer@devforge.dev> Co-authored-by: cowork-bot <cowork@revenueholdings.dev>
1 parent 488380f commit 2e0c8a7

4 files changed

Lines changed: 65 additions & 3 deletions

File tree

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Seeded by the repo-improver-rotation Cowork job into cowork/improve-* branches.
2+
# Opens a PR automatically when such a branch is pushed (sandbox cannot reach
3+
# the GitHub API directly; this runs server-side with the repo's GITHUB_TOKEN).
4+
name: cowork-auto-pr
5+
on:
6+
push:
7+
branches: ['cowork/improve-**']
8+
permissions:
9+
contents: read
10+
pull-requests: write
11+
jobs:
12+
ensure-pr:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Open PR for this branch if none exists
16+
env:
17+
GH_TOKEN: ${{ github.token }}
18+
run: |
19+
set -eu
20+
existing=$(gh pr list --repo "$GITHUB_REPOSITORY" --head "$GITHUB_REF_NAME" --state open --json number --jq 'length')
21+
if [ "$existing" = "0" ]; then
22+
gh pr create --repo "$GITHUB_REPOSITORY" \
23+
--head "$GITHUB_REF_NAME" \
24+
--title "cowork-bot: automated improvements ($GITHUB_REF_NAME)" \
25+
--body "Automated improvement PR from the Cowork repo-improver rotation (one coherent senior-dev improvement per run; see individual commit messages). Subsequent runs push additional commits to this PR rather than opening new ones."
26+
else
27+
echo "Open PR already exists for $GITHUB_REF_NAME — nothing to do."
28+
fi

pyproject.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ classifiers = [
2828
]
2929

3030
[project.optional-dependencies]
31+
# Optional paywall gating (Model-B license). The tool runs without it
32+
# (require_license no-ops on ImportError); install to enable Free/Pro
33+
# tiers: pip install deploydiff[license]
34+
license = [
35+
"revenueholdings_license @ git+https://github.com/Coding-Dev-Tools/revenueholdings_license.git",
36+
]
3137
dev = [
3238
"pytest>=7.0",
3339
"pytest-cov>=4.0",

src/deploydiff/cli.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from .cloudformation_parser import parse_cloudformation_changeset
99
from .cost_estimator import estimate_costs
1010
from .diff_renderer import render_plan
11-
from .mcp_server import run_for_app
1211
from .models import CostEstimate, DeployPlan
1312
from .pulumi_parser import parse_pulumi_preview
1413
from .rollback import generate_rollback_commands
@@ -185,4 +184,13 @@ def mcp() -> None:
185184
Uses stdio transport compatible with Claude Code, Cursor, Codex, and
186185
any MCP-compatible agent. Run this from your MCP client configuration.
187186
"""
187+
try:
188+
from .mcp_server import run_for_app
189+
except ImportError as exc:
190+
console.print(
191+
"[red]Error: click-to-mcp is not installed.[/red]\n"
192+
"Install it with: [bold]pip install click-to-mcp[/bold]"
193+
)
194+
raise SystemExit(1) from exc
195+
188196
run_for_app(main)

src/deploydiff/mcp_server.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,36 @@
1010

1111
from __future__ import annotations
1212

13-
import click_to_mcp
14-
1513

1614
def run_mcp() -> None:
1715
"""Start the MCP stdio server (entry point for console_scripts)."""
16+
try:
17+
import click_to_mcp
18+
except ImportError:
19+
import sys
20+
print(
21+
"Error: click-to-mcp is not installed. "
22+
"Install it with: pip install click-to-mcp",
23+
file=sys.stderr,
24+
)
25+
sys.exit(1)
26+
1827
from deploydiff.cli import main
1928

2029
click_to_mcp.run(main, prefix="dd")
2130

2231

2332
def run_for_app(app: object) -> None:
2433
"""Start the MCP server for a given Click app (injected by cli.py)."""
34+
try:
35+
import click_to_mcp
36+
except ImportError:
37+
import sys
38+
print(
39+
"Error: click-to-mcp is not installed. "
40+
"Install it with: pip install click-to-mcp",
41+
file=sys.stderr,
42+
)
43+
sys.exit(1)
44+
2545
click_to_mcp.run(app, prefix="dd")

0 commit comments

Comments
 (0)