Skip to content

Prefixed versions#326

Draft
micprog wants to merge 11 commits into
masterfrom
prefixed_versions
Draft

Prefixed versions#326
micprog wants to merge 11 commits into
masterfrom
prefixed_versions

Conversation

@micprog

@micprog micprog commented Jul 2, 2026

Copy link
Copy Markdown
Member

Allow for custom version prefixes to allow forks to use semver without requiring alignment of the upstream project or artificial version numbers.

micprog and others added 11 commits July 2, 2026 21:24
Replace the hardcoded `v` tag-prefix stripping with a generic
`split_version_tag` helper that splits any tag into its literal prefix
(e.g. `v` or `companyX-v`) and semantic version. Carry that prefix
alongside each version via the new `GitTagVersion` struct.

This is a behaviour-preserving refactor: version matching, lockfile
writing, and audit are all still pinned to the default `v` prefix, so
only `v*` tags are considered. Subsequent commits wire the per-dependency
`version_prefix` through resolution to activate namespacing.

Also removes the unused, `-v`-separator `PrefixedVersion`/
`PrefixedVersionReq` scaffolding, superseded by the literal-prefix model.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Carry the per-dependency `version_prefix` through resolution by adding a
`prefix` field to `DependencyConstraint::Version` (defaulting to `v` via the
new `DEFAULT_VERSION_PREFIX` constant). Version matching now only accepts
git tags whose literal prefix equals the constraint's prefix, so a default
dependency sees only `v*` tags and a `companyX-v` dependency sees only
`companyX-v*` tags. There is no fallback between namespaces.

Because namespaces are exclusive, a dependency required with more than one
distinct prefix has no shared version space. Rather than silently picking a
commit, resolution now bails with a clear error instructing the user to add
an override, which collapses the requirements to a single namespace and
reuses the existing override-based manual-resolution mechanism.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Record the namespace a git dependency resolved under so that re-resolution
(`bender update`) stays in the same namespace instead of falling back to the
default `v`. The resolver now tracks the resolved prefix per dependency,
writes it into the new optional `version_prefix` field of LockedPackage, and
reads it back when reconstructing constraints from the lockfile.

The field is `#[serde(default, skip_serializing_if = "Option::is_none")]`, so
default-`v` dependencies neither read nor write it: existing lockfiles
deserialize unchanged and keep serializing byte-for-byte identically.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Carry the resolved version prefix on DependencyEntry (populated from the
lockfile) and use it in `bender packages --version` instead of hardcoding
`v`. Default-`v` dependencies still print as `v1.2.3`; a namespaced
dependency now prints as e.g. `companyX-v1.2.3`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add unit tests for `split_version_tag` covering the default `v` prefix,
custom and digit-containing prefixes, the empty prefix, prerelease/build
metadata, and rejection of non-versions.

Add an integration test that builds git fixtures carrying both `v*` and
`companyX-v*` tags and drives the real binary to verify: default resolution
picks the highest `v*` tag and records no prefix; a `companyX-v` dependency
resolves within its namespace (ignoring `v*`) and persists the prefix; and
mixing prefixes for one dependency fails with a clear conflict error.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a "Version Namespaces" section to the dependencies docs explaining
`version_prefix`, the default `v` prefix, the strict no-mixing/no-fallback
rule, and override-based conflict resolution. Note the new lockfile
`version_prefix` field and add a CHANGELOG entry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Support specifying a namespace inline, e.g. `version: "companyX-v1.2.*"`,
in addition to the separate `version_prefix` field. Manifest validation now
splits the version requirement into an optional literal prefix and the semver
requirement via `split_version_req`, normalizing the embedded form into the
existing internal representation.

The split only triggers when the version part begins with a number, so bare
requirements (`1.2.*`, `>=1.0.0`, `*`) keep the default `v` prefix and remain
backwards compatible; operator-led prefixed ranges are rejected rather than
mis-parsed and must use the `version_prefix` field. When both an embedded
prefix and the field are given they must agree, otherwise validation fails.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add integration tests covering the embedded form: `version: "companyX-v2"`
resolves within the namespace and persists the prefix, and an embedded prefix
that disagrees with the `version_prefix` field fails. Document both forms and
the embedded-form limitations in the dependencies guide and CHANGELOG.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`bender audit` previously only ever considered the default `v` namespace when
computing version-bump suggestions. It now filters candidate versions to the
namespace the dependency is currently resolved under, falling back to the
default `v` when the current checkout is not a version (path or revision).

Parent version requirements are read from `DependencyConstraint`'s display,
which annotates non-default namespaces as `<req> (prefix `<p>`)`; the audit
now strips that annotation before parsing, since the namespace is already
fixed by resolution. Add an integration test covering a namespaced bump
suggestion.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@micprog micprog requested a review from fischeti July 2, 2026 19:25
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