Skip to content

sm new scaffold pins ^0.0.3 npm deps and ==0.0.7 python deps even when 0.0.8 is published; npm caret on 0.0.x silently blocks the bump #119

Description

@antosubash

Summary

The sm new scaffold (in simple_module_cli==0.0.8) hard-codes outdated version pins:

  • client_app/package.json pins \"@simple-module-py/ui\": \"^0.0.3\" and \"@simple-module-py/i18n\": \"^0.0.3\". Both are at 0.0.8 on npm.
  • pyproject.toml pins simple_module_hosting==0.0.7, simple_module_users==0.0.7, etc. All are at 0.0.8 on PyPI.
  • pyproject.toml[dependency-groups].dev pins simple_module_test==0.0.7. Also at 0.0.8.

The npm side fails silently and with worse consequences: ^0.0.3 doesn't behave the way it does for ^1.2.3. Per the npm semver rules, when the major and minor are both zero, caret is locked to that exact patch — so \"^0.0.3\" resolves to 0.0.3 and never to 0.0.4..0.0.99. Result: a fresh npm install pulls @simple-module-py/ui@0.0.3 (with the broken exports map and missing deps from #114/#115) even though 0.0.8 shipped both fixes.

Reproduction

$ uvx --from simple_module_cli sm new my-app --db sqlite --preset standard -y --no-install
$ cd my-app && cat client_app/package.json | grep simple-module
\"@simple-module-py/i18n\": \"^0.0.3\",
\"@simple-module-py/ui\": \"^0.0.3\",
$ cat pyproject.toml | grep simple_module
dependencies = [\"simple_module_hosting==0.0.7\", \"simple_module_auth==0.0.7\", \"simple_module_users==0.0.7\", \"simple_module_dashboard==0.0.7\", \"simple_module_permissions==0.0.7\"]
dev = [\"simple_module_test==0.0.7\", \"pytest>=8.0\"]
$ make install # (after the dependency-group entry is fixed if test wasn't published)# uv pulls 0.0.7# npm pulls @simple-module-py/ui@0.0.3 — NOT 0.0.8
$ cd client_app && ls node_modules/@simple-module-py/ui/package.json && grep '\"version\"' node_modules/@simple-module-py/ui/package.json
\"version\": \"0.0.3\",

Root cause

The CLI ships a static template with hard-coded version strings. Every simple_module_cli release would have to bump those strings to match its own version, and they currently don't. As a result, version drift between simple_module_cli and the rest of the workspace silently downgrades users.

Worse, the npm pins use ^0.0.x syntax that defeats its own purpose. Even if the strings did keep up, anyone doing npm install --save @simple-module-py/ui@latest after the fact would be fine, but the standard make install flow won't bump them.

Proposed fix

Two complementary changes:

A. Tie the scaffold's pinned versions to the CLI's own version at scaffold time

Either:

A1. Have sm new substitute its own simple_module_cli.__version__ into the template at write time. Every PyPI/npm release is cut as a coordinated set (0.0.8 is consistent across simple_module_* PyPI and @simple-module-py/* npm), so a single version variable works.

A2. Have sm new query PyPI/npm at scaffold time for latest and substitute that. Adds a network dep and is harder to hermeticize, but always picks the latest.

(A1) is the cleanest — the version that exists on PyPI/npm under the same tag as the running CLI is the one that will work with it.

B. Don't use ^ for 0.0.x versions

For zero-major releases, switch to either:

\"@simple-module-py/ui\": \"~0.0.8\" // patch range that actually works for 0.0.x\"@simple-module-py/ui\": \"0.0.8\" // exact pin, simplest\"@simple-module-py/ui\": \">=0.0.8 <0.1.0\"

Tilde (~0.0.8) is the conventional fix and matches what most pre-1.0 packages do. Once you ship 0.1.0+, caret can come back.

Suggested test

Add a regression test in the CLI repo that runs sm new into a tmpdir, then asserts:

importjson, re, tomllibfrompathlibimportPathimportsimple_module_clidest=Path(\"<scaffolded_dir>\")
v=simple_module_cli.__version__py=tomllib.loads((dest/ \"pyproject.toml\").read_text())
fordepinpy[\"project\"][\"dependencies\"]:
ifdep.startswith(\"simple_module_\"):
assertdep.endswith(f\"=={v}\"), depjs=json.loads((dest/ \"client_app/package.json\").read_text())
fork, specinjs[\"dependencies\"].items():
ifk.startswith(\"@simple-module-py/\"):
assertspecin (v, f\"~{v}\"), (k, spec)

Workaround

Hand-bump every 0.0.7/^0.0.3 reference and re-run uv sync / npm install:

sed -i '''s/0\\.0\\.7/0.0.8/g' pyproject.toml
sed -i '''s/\\^0\\.0\\.3/0.0.8/g' client_app/package.json
rm -rf client_app/node_modules client_app/package-lock.json
uv sync && (cd client_app && npm install)

Related

Environment

  • simple_module_cli 0.0.8
  • @simple-module-py/ui 0.0.8 (latest on npm)
  • All simple_module_* PyPI packages at 0.0.8

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions