Order Build Stages by Dependency
Problem Statement
A multi-stage Dockerfile has named stages that COPY --from earlier stages. Produce a build order so each stage is built after the stages it copies from.
Background
This is a topological sort over stage dependencies. Each stage names the stages it depends on. Build order lists dependencies before dependents; among stages that are simultaneously ready, choose the alphabetically smallest name for determinism. A dependency cycle returns "CYCLE".
Your Task
def build_order(stages):
- stages: dict mapping stage name -> list of stage names it depends on.
- Return the ordered list of stage names, or "CYCLE".
Input Format
- stages (dict of str -> list of str).
Output Format
- A list of strings, or "CYCLE".
Sample
print(build_order({"app": ["builder"], "builder": []}))
Output:
['builder', 'app']
Example
print(build_order({"app": ["builder"], "builder": []}))['builder', 'app']
- Initialize Dependencies: Analyze the input stages to determine in-degrees (number of unmet dependencies) for each stage. "builder" has no dependencies, so its in-degree is . "app" depends on "builder", so its in-degree is .
- Select Initial Stage: Identify all stages with an in-degree of as ready to build. Only "builder" qualifies, so it is selected first and added to the build order.
- Update Dependencies: Remove "builder" from the ready set and decrement the in-degree of any stage that depended on it. "app" depended on "builder", so its in-degree decreases from to .
- Select Next Stage: With "builder" built, "app" now has an in-degree of and becomes ready. It is selected next and appended to the build order.
- Finalize Order: The heap of ready stages is now empty, and the build order contains both stages. Since the length of the order () matches the total number of stages (), no cycle exists, and the process terminates successfully.
- The final output is
['builder', 'app']
Constraints
- Dependencies build before dependents.
- Ties broken by alphabetically smallest ready stage.
- Return
"CYCLE"if no valid order exists.