Skip to content

Epic: split pkg/compose into focused internal packages #14396

Open

Description

@ndeloof

Context

pkg/compose is one flat package: about 62 non-test files and 19.5k lines, where every operation is a method of the same composeService (214 methods over 46 files). Any operation can therefore reach anything else — the Docker client, the event bus, the prompt, any other operation. Nothing but convention keeps a read-only command from depending on lifecycle code, and every test builds a whole service.

The package also exports about 60 top-level symbols, among them internals (Plan, Operation, ObservedState, Graph, the *Hash helpers). The module is /v5: every exported symbol is a compatibility commitment, and the more of the engine lives in the public package, the harder it is to change.

This epic tracks two linked goals, one reviewable PR at a time:

  1. splitting pkg/compose into focused packages under internal/;
  2. reducing its exported surface, before SDK callers build on symbols that were never meant to be public. The two go together: moving a cluster into internal/ is also what stops its types from being public API, so the public-surface items below are tracked here rather than separately.

Approach

The pattern settled by the first moves:

  • each cluster becomes its own internal/ package, starting with the most isolated ones;
  • it declares what it needs from the engine as a small Backend interface, and cannot reach anything else (importing pkg/compose back would be an import cycle);
  • composeService implements that interface and keeps one-line forwarders, so the callers of the moved code don't change;
  • behavior is unchanged, and tests move with the code with the same assertions.

The lifecycle clusters (the plan engine, up, down, …) come last, once the start-phase series of #14081 has landed.

Progress

Preparation and first moves

Remaining moves

The order is a proposal and each item is to be confirmed against what it needs from composeService before it starts.

Public surface

What pkg/compose exports today is a compatibility commitment of the /v5 module for anything that doesn't need to be. These items shrink it, and are best done together with the moves above, since a package that moves to internal/ no longer exports its types.

Non-goals

  • No behavior change: a move PR is a move. Fixes found on the way go in their own PR.
  • No new public API: what a package needs from the engine goes through its Backend interface, not through an exported symbol of pkg/compose.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions