Skip to content

Collapse

When chaining multiple upgrades, the collapse engine merges redundant operations into a minimal set.

Function

collapse_operations(operations) → list[AnyOperation]

Takes a flat list of operations (from all upgrade steps) and returns a collapsed list.

from bluefox_upgrade import collapse_operations

collapsed = collapse_operations(all_ops)

Collapse rules

File operations

Scenario Result
Multiple ReplaceFile on same path Keep last
CreateFile then ReplaceFile on same path Keep CreateFile with last template
ReplaceFile then RemoveFile on same path Keep RemoveFile
CreateFile then RemoveFile on same path Both removed (no-op)

Section operations

Scenario Result
Multiple UpdateSection on same path + marker Keep last

Dependency operations

Scenario Result
Multiple BumpDependency on same package Merge: first old_spec → last new_spec
AddDependency then BumpDependency on same package AddDependency with final new_spec
AddDependency then RemoveDependency on same package Both removed (no-op)

Example

Three upgrades with redundant Dockerfile replacements:

ops = [
    ReplaceFile(path="Dockerfile", template="v2.jinja", description="v2"),
    BumpDependency(name="fastapi", old_spec=">=0.115", new_spec=">=0.118"),
    ReplaceFile(path="Dockerfile", template="v3.jinja", description="v3"),
    BumpDependency(name="fastapi", old_spec=">=0.118", new_spec=">=0.120"),
]

collapsed = collapse_operations(ops)
# Result: [
#   ReplaceFile(path="Dockerfile", template="v3.jinja", ...),
#   BumpDependency(name="fastapi", old_spec=">=0.115", new_spec=">=0.120"),
# ]