Skip to content

fix(generate): a generated client carries its library's version, not 0.0.1 - #1164

Merged
antoinetoussaint-byte merged 2 commits into
mainfrom
fix/client-library-version
Oct 26, 2026
Merged

antoinetoussaint-byte merged 2 commits into
mainfrom
fix/client-library-version

Conversation

@antoinetoussaint-byte

Copy link
Copy Markdown
Contributor

What was wrong

codefly generate client writes typescript/package.json and python/pyproject.toml from a scaffold that says 0.0.1, once (writeFileIfMissing), and never updates the version again. The library's own version, the value library.codefly.yaml records, never reached them. Live example: obin-ai/module-document-store clients/library.codefly.yaml says version: 0.1.14 (producer codefly/documents@0.1.14), while clients/typescript/package.json says "version": "0.0.1", which is what gets published.

Fix

  • libraryVersion(output, entries) is the one source of the library's version. It is the logic writeLibraryManifest already had: for a single contract, the producer's declared version (the composed module package's, or the local service's); for an aggregate, the existing top-level version. It is computed once per run and used for the manifest and for every language.
  • stampPackageVersion runs after each language generates:
    • TypeScript: package.json's top-level "version" member is found by walking the JSON tokens, and only its value bytes are replaced. Formatting, key order and hand-edits stay byte-for-byte; a nested "version" key is never touched.
    • Python: pyproject.toml's version = "…" project line, in place, the same way ensurePythonDependencies already edits that file.
    • Go: nothing to set; its version is its tag.
    • A library with no version is refused with a reason ("the library declares no version") instead of being written empty.

No new input or flag: the version is what the module already declares (Codefly generates every value).

Tests

  • pkg/generators/client_version_test.go (ungated):
    • the scaffold gets the library version, and a later run moves it again
    • a compact, hand-edited package.json with a nested "version" keeps every other byte
    • pyproject.toml with a hand-added section keeps it
    • an empty version is refused by name
    • Go is a no-op
    • libraryVersion returns the producer's version
  • cmd/generate/client_test.go TestGenerateClientPreservesHandEditedFiles (gated, CODEFLY_GENERATE_QUALIFY=1): after a regenerate, package.json's version equals library.codefly.yaml's and is not 0.0.1. Ran locally: PASS. With the stamp call removed it FAILS: package.json version = 0.0.1, library.codefly.yaml version = "0.0.0".

Classification

Fix, at the place that writes the package manifests. Reused: the library-version rule writeLibraryManifest already applied, and the in-place edit pattern of ensurePythonDependencies. Not done: the local-service fallback 0.0.1 in resolveLocalSource (a service that declares no version) is unchanged.

Not verified: the rest of the gated cmd/generate qualify suite; CI does not run gated tests.

🤖 Generated with Claude Code

antoinetoussaint-byte and others added 2 commits October 25, 2026 19:44
…0.0.1

`codefly generate client` wrote package.json and pyproject.toml once,
from a scaffold that says 0.0.1, and never touched them again. The
library's own version (library.codefly.yaml: the producer's declared
version for one contract, the existing one for an aggregate) never
reached them, so the document store's client library said 0.1.14 while
its TypeScript package said 0.0.1 and was published as that.

Every generation now sets the package manifest's version to the
library's. package.json's top-level "version" member is found by walking
the document's tokens and only its value is replaced; pyproject.toml's
project version line likewise. Hand-edits stay byte-for-byte. A library
with no version is refused by name. Go's version is its tag.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Resolves pkg/generators/client.go against #1169's staged generation: the
version stamp runs after each staged language is applied, and a library
with no version is refused before anything is staged, so the library is
untouched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@antoinetoussaint-byte
antoinetoussaint-byte added this pull request to the merge queue Oct 26, 2026
Merged via the queue into main with commit 2b804f1 Oct 26, 2026
14 checks passed
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.

1 participant