Skip to content

CLI sorts Feature options fewest-first, against spec #755

Description

@nozaq

Note on repo choice: Per the devcontainers/cli CONTRIBUTING guide, issues concerning the CLI should be filed in this spec repository, so I've opened it here even though it's about devcontainers/cli behavior. Please let me know if you'd prefer it moved to the devcontainers/cli repo instead.

Summary

When sorting Features within an installation round, the spec says Features are ordered by the greatest number of user-defined options first, but containerFeaturesOrder.ts orders by the fewest options first.

Specification

Features spec — Definition: Round Stable Sort:

Greatest number of user-defined options (note omitting an option will default that value to the Feature's default value and is not considered a user-defined option)

Implementation

optionsCompareTo returns aKeys.length - bKeys.length, which is negative when a has fewer options, so the Feature with fewer options sorts earlier:

https://github.com/devcontainers/cli/blob/f683c29f64a20109b4453e5149807e390ff65133/src/spec-configuration/containerFeaturesOrder.ts#L123-L125

This is the option tiebreaker for every source type (OCI, file-path, direct-tarball, legacy).

Test evidence

The existing test valid dependsOn with round sorting based on options (fixture configs/feature-dependencies/dependsOn/local-with-options) pins the fewest-first behavior — the ./b variant with {} (zero options) is expected first, ahead of the two-option variants:

https://github.com/devcontainers/cli/blob/f683c29f64a20109b4453e5149807e390ff65133/src/test/container-features/containerFeaturesOrder.test.ts#L135-L209

So the implementation and its tests are internally consistent; only the behavior disagrees with the spec.

Proposed fix

Sort by the greatest option count to match the spec (bKeys.length - aKeys.length), with the fixture/expected order updated accordingly. This changes the install order of the same Feature requested with differing option sets within a round.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions