Skip to content

feat(imports)!: version-pinned imports in interface.yaml (#23)#25

Merged
Ulrond merged 1 commit into
developfrom
feature/23-versioned-imports
Jun 2, 2026
Merged

feat(imports)!: version-pinned imports in interface.yaml (#23)#25
Ulrond merged 1 commit into
developfrom
feature/23-versioned-imports

Conversation

@Ulrond
Copy link
Copy Markdown
Contributor

@Ulrond Ulrond commented Jun 2, 2026

Summary

Adds support for `name@version` syntax in `interface.yaml` `imports` so consumers can declare which version of a producer they require, instead of silently inheriting whatever happens to be on disk at `/current/`.

Implements #23. Used by rdkcentral/rdk-halif-aidl#538 — once this lands and tags as `2.2.0`, rdk-halif-aidl bumps its `binder_sdk.version` pin and migrates every in-tree `interface.yaml` to explicit pins.

Syntax

```yaml
imports:

  • common@0.1.0.0 # pin to a released snapshot
  • audiodecoder@current # in-development sibling (explicit)
  • audiosink # bare name — deprecated, treated as @current
    ```

Resolver behaviour (consumer's `current` build)

Pin form Linked library
`@` `lib-v-cpp.so` — the producer's `interface.yaml` must list this version under `versions_with_info`; otherwise the dependency-tree generator fails fast with a clear, actionable error.
`@current` `lib-vcurrent-cpp.so`
bare name Same as `@current`, plus a one-shot deprecation warning per (consumer, import) pair. Suppressed for frozen-snapshot `interface.yaml` files since they are historical artefacts.

Files changed

  • `host/aidl_interface.py` — adds `parse_import_spec()`, populates a per-interface `import_versions` map alongside the existing bare-name `imports` list (preserved for back-compat with `aidl_api.py`), routes pinned versions through the dependency tree builder, and replaces the previous `KeyError: ` crash with a graceful `RuntimeError` when a pin points to an unregistered target.
  • `host/aidl_ops.py` — removes the `str(int(a))` coercion on `--version` so dotted release strings (`0.1.0.0`) can be passed through.
  • `host/CMakeLists.inc` — broadens the target-name version regex from `-v([0-9]+)` to `-v([^-]+)-cpp$` to capture dotted release strings alongside integer ordinals.

Backward compatibility

Bare-name form keeps working through the deprecation window. The warning fires once per `(consumer, imported-name)` pair per build, not once per call — production logs stay readable. Plan: hard-remove the bare-name form in 3.0.0.

Verification

Tested against the rdk-halif-aidl tree (`develop` tip):

Test Result
Bare-name imports build cleanly + emit one-shot deprecation warning
`@current` pin builds cleanly + suppresses the warning
`@` fails fast with the new RuntimeError
Topological sort no longer crashes with raw `KeyError`

Why this is `!` (breaking)

The bare-name form is technically still working, so most existing consumers are unaffected. The break is the new failure mode for `name@version` pointing at an unregistered version — previously this would silently produce broken builds (`KeyError` from the topological sort, late in the cycle); now it fails fast at configure time. For consumers who were never using pinned imports (everyone, today), this is a no-op.

Closes

Copilot AI review requested due to automatic review settings June 2, 2026 14:11
@Ulrond Ulrond requested a review from a team as a code owner June 2, 2026 14:11
@Ulrond Ulrond added the enhancement New feature or request label Jun 2, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds support for name@version (and @current) in interface.yaml imports so interface consumers can explicitly pin producer versions, improving determinism of dependency resolution and surfacing invalid pins earlier in the build/dependency graph.

Changes:

  • Extend host/aidl_interface.py to parse version-pinned imports, track per-import pins, and validate that pinned dependency targets exist (fail-fast vs. KeyError during topo sort).
  • Update host/aidl_ops.py to stop coercing --version to int, allowing dotted versions like 0.1.0.0.
  • Broaden host/CMakeLists.inc parsing of -v<version> to accept dotted versions in target names (not just integer ordinals).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
host/CMakeLists.inc Adjusts CMake target-name version parsing to accept dotted versions for interface targets.
host/aidl_ops.py Passes --version through verbatim to support dotted version strings.
host/aidl_interface.py Parses imports pins, keeps back-compat import list, generates pinned dependency targets, and improves erroring for unresolved pinned deps.

Comment thread host/aidl_interface.py
Comment on lines +56 to +79
def parse_import_spec(spec):
"""Parse a single `imports` entry from interface.yaml.

Accepts either bare-name form ("audiodecoder") or the versioned
`name@version` form ("audiodecoder@0.1.0.0", "common@current"). The
version part is opaque to the parser — any non-empty string is allowed
and resolved against the on-disk version directory layout downstream.

Returns:
(name, version_or_None) — version is `None` for bare-name imports,
the literal version string otherwise. `@current` is preserved as
the string "current".
"""
if not isinstance(spec, str):
raise ValueError(
"imports entry must be a string, got %r" % (spec,))
if "@" not in spec:
return (spec, None)
name, _, version = spec.partition("@")
if not name or not version:
raise ValueError(
"imports entry %r must be 'name@version' with both parts "
"non-empty" % (spec,))
return (name, version)
Comment thread host/aidl_interface.py Outdated
Comment on lines +169 to +173
for imprt, pin in imports.items():
if pin == IMPORT_VERSION_UNPINNED:
lib_deps.append("%s-vcurrent-cpp" % imprt)
else:
lib_deps.append("%s-v%s-cpp" % (imprt, pin))
Comment thread host/aidl_ops.py
Comment on lines 202 to +208
elif o == "-v" or o == "--version":
# Convert the given value to int and then to string.
# This is required in case the version is given along with the space.
_gen_version = str(int(a))
# Version is passed through verbatim. Integer ordinals ("1", "2")
# and dotted release strings ("0.1.0.0") are both valid — the
# latter is used by repos that pin imports via "name@X.Y.Z.W"
# in interface.yaml (linux_binder_idl#23). The value is treated
# as an opaque directory-name component downstream.
_gen_version = a.strip()
Adds support for `name@version` syntax in `interface.yaml` imports so
consumers can declare which version of a producer they require, instead
of silently inheriting whatever happens to be on disk at
`<producer>/current/`.

Syntax:
  imports:
    - common@0.1.0.0       # pin to a released snapshot
    - audiodecoder@current # in-development sibling (explicit)
    - audiosink            # bare name — deprecated, treated as @current

Resolver behaviour for the consumer's `current` build:
  - `@<version>`  — links to `lib<name>-v<version>-cpp.so`. The producer's
                    interface.yaml must list this version under
                    `versions_with_info`; otherwise the dependency-tree
                    generator fails fast with a clear, actionable error.
  - `@current`    — links to `lib<name>-vcurrent-cpp.so`.
  - bare name     — same as `@current`, plus a one-shot deprecation
                    warning per (consumer, import) pair. The warning is
                    suppressed for frozen-snapshot interface.yaml files
                    since they are historical artefacts and re-warning
                    every build would be noise.

Toolchain changes:
  - host/aidl_interface.py — adds `parse_import_spec()`, populates a
    per-interface `import_versions` map alongside the existing bare-name
    `imports` list (preserved for back-compat with aidl_api.py), routes
    pinned versions through the dependency tree builder, and replaces
    the previous `KeyError: <target>` crash with a graceful RuntimeError
    when a pin points to an unregistered target.
  - host/aidl_ops.py — removes the `str(int(a))` coercion on `--version`
    so dotted release strings (`0.1.0.0`) can be passed through.
  - host/CMakeLists.inc — broadens the target-name version regex from
    `-v([0-9]+)` to `-v([^-]+)-cpp$` to capture dotted release strings
    alongside integer ordinals.

Verified against rdk-halif-aidl tree:
  - bare-name imports build cleanly + emit one-shot deprecation warning
  - `@current` pin builds cleanly + suppresses the warning
  - `@<unregistered-version>` fails fast with the new error message

Closes #23. Related: rdkcentral/rdk-halif-aidl#538.
@Ulrond Ulrond force-pushed the feature/23-versioned-imports branch from 3d59600 to 654c27e Compare June 2, 2026 16:55
@Ulrond Ulrond merged commit 157740f into develop Jun 2, 2026
9 checks passed
@Ulrond Ulrond deleted the feature/23-versioned-imports branch June 2, 2026 22:55
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 2, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants