Fix the layer cache model behind slow builds
Your task
An assistant's Dockerfile for a Go service copies the whole source tree before go mod download. CI builds went from 40 seconds to 6 minutes, because a one-line change now downloads every module again. To see what each build order costs, the team models Docker's layer cache.
An assistant wrote rebuilt_step_count(steps, changed_files). It is in the editor. It has a bug. Find it and fix it.
Input and output:
steps: the build steps in order, one string each, as<op>|<argument>. The ops in use arecopyandrun. The list can be empty.changed_files: the paths that changed since the last build, such as"cmd/server/main.go". The list can be empty.- Return how many steps have to run again, an integer.
Rules the tests check:
- Split each step at its first
|. A step with no|is all op, with an empty argument. Ops are case sensitive. - A
copystep's argument holds patterns separated by single spaces. Ignore empty patterns. - A
copystep is stale when any of its patterns matches any changed file:.copies the whole build context, so it matches every file.- A pattern that ends in
/matches every file whose path starts with that pattern. - Any other pattern matches only a file with exactly that path. Matching is case sensitive.
- With no changed files, no step is stale.
- A step that is not
copy, such asrun, is never stale on its own. - The cache is a chain: each layer is built on the one before it. Find the first stale
copystep. That step and every step after it run again, even acopywhose files did not change. Return that count. - With no stale
copystep, return 0.
Examples
rebuilt_step_count(steps: list[str], changed_files: list[str]) -> intExample 1
Input
rebuilt_step_count(["copy|.", "run|go mod download", "run|go build"], ["cmd/server/main.go"])Output
3Example 2
Input
rebuilt_step_count(["copy|go.mod go.sum", "run|go mod download", "copy|.", "run|go build"], ["cmd/server/main.go"])Output
2Example 3
Input
rebuilt_step_count(["copy|go.mod go.sum", "run|go mod download", "copy|.", "run|go build"], [])Output
0