Skip to content

fix: Harden fresh installs against undeclared dependencies - #19

Open
kw-datamasque wants to merge 1 commit into
add-configurable-discoveryfrom
harden-fresh-install
Open

fix: Harden fresh installs against undeclared dependencies#19
kw-datamasque wants to merge 1 commit into
add-configurable-discoveryfrom
harden-fresh-install

Conversation

@kw-datamasque

@kw-datamasque kw-datamasque commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Follow-up to the v1.4.0 fresh-install breakage, stacked on #18.

What happened

Every fresh install of 1.4.0 crashed at startup.
main.py imported click without declaring it as a dependency; click had always been pulled in by typer, and typer 0.27.1 stopped depending on it, so new installs got no click and dm died on its first import.
CI stayed green because every job installs from uv.lock, which still held an older typer that shipped click.
Existing installs kept their click, so only fresh installs broke.

Warning

rich is in exactly the position click was: imported by our code, undeclared, and currently arriving only through typer.
If typer drops rich the way it dropped click, every fresh install breaks again with no commit in this repo.
#18 fixed the click import; this PR closes the rest of the class.

Changes

  • Declare rich as a real dependency.
  • Raise the typer floor to 0.16.0.
    typer==0.15.0 crashes with the click versions installs get today, so the old floor advertised a combination that cannot work.
    The new minimums were install-tested together by hand on Python 3.11; no CI job re-checks them.
  • Add upper bounds to typer and tomli-w.
  • Add deptry to lint (CI and make lint): fails when src imports a package pyproject.toml does not declare.
    It parses the AST, so it catches imports inside functions too.
  • Add a fresh-install smoke test: build the wheel, install it into a clean Python 3.11 venv, import every module, run dm --help.
    Runs on every PR and before every publish.
    It lives in scripts/installation_smoke_test.sh, so make smoke runs the identical check locally, and its header records what it does not cover.
    The main test job already covers Python 3.11/3.12/3.13; the smoke test only proves a clean install works, and 3.11 is the oldest supported floor, the end that breaks first.

Why not pin exact versions

== pins conflict with users' other tools, still let indirect dependencies float, and block upstream security fixes until we re-release (typer and rich do not backport fixes to old versions).
Declaring every imported package closes this incident class outright; deptry keeps it closed.

@kw-datamasque kw-datamasque self-assigned this Aug 11, 2026
@kw-datamasque
kw-datamasque marked this pull request as ready for review August 11, 2026 23:09
@ClassicMMT
ClassicMMT force-pushed the add-configurable-discovery branch from 27b241b to 69ea485 Compare August 11, 2026 23:15
@kw-datamasque
kw-datamasque force-pushed the harden-fresh-install branch 2 times, most recently from 7f64c7a to ded04b2 Compare August 12, 2026 03:12

@ClassicMMT ClassicMMT left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job! I like the idea.

A few things to consider/finish:

Needs target branch updated

  1. CHANGELOG.md needs to be updated.
  2. Should there be enable-cache: true on setup-uv?
  3. Should make check include smoke tests?

Also should this be in other repos too?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants