Skip to content

feat(scaffold): add --merge-driver flag to force text-based merging - #2925

Merged
Erik Osterman (Cloud Posse) (osterman) merged 7 commits into
cloudposse:mainfrom
jorrite:feat-scaffold-update-merge-driver
Aug 14, 2026
Merged

Erik Osterman (Cloud Posse) (osterman) merged 7 commits into
cloudposse:mainfrom
jorrite:feat-scaffold-update-merge-driver

Conversation

@jorrite

@jorrite Jorrit Elfferich (jorrite) commented Aug 11, 2026 •

Copy link
Copy Markdown
Contributor

what

  • Adds a --merge-driver flag (auto / text) to atmos scaffold generate --update and atmos init --update, alongside the existing --merge-strategy flag.
  • auto (default) is today's existing behavior: pick the merger by file extension (YAML-aware for .yaml/.yml, line-oriented text otherwise).
  • text forces every file — YAML included — through the line-oriented diff3 merger, bypassing the YAML-aware re-encode that has no concept of blank lines between blocks and silently drops them on every update, even when nothing meaningful changed.
  • Adds a changelog post and roadmap entry for the new flag.

why

Structure-aware YAML merging is the right default for most files, but it re-encodes the whole document through a YAML parser/serializer, and formatting like blank lines between top-level blocks isn't part of what a YAML parser models. Templates that bundle CI pipeline YAML (a common convention uses blank lines to visually separate jobs/stages) lost that formatting on every --update, whether or not the file actually changed. --merge-driver=text gives users an explicit opt-out, mirroring git's own merge driver concept (auto/text), so this class of file can go through the same merge algorithm git merge itself uses on ordinary text files.

references

Closes #2886.

@jorrite
Jorrit Elfferich (jorrite) requested a review from a team as a code owner August 11, 2026 17:22
@atmos-pro

atmos-pro Bot commented Aug 11, 2026 •

Copy link
Copy Markdown
Contributor

Tip

Atmos Pro  

No affected stacks workflow was detected for this pull request.
If this is expected, no action is needed.
Learn More. Ask AI.

@jorrite

Copy link
Copy Markdown
Contributor Author

Per the semver label decision tree, this should be labeled minor (new user-visible --merge-driver flag) — I don't have permission to self-label as an external contributor, could a maintainer apply it? A changelog post and roadmap entry are already included in the second commit.

@github-actions github-actions Bot added the size/m Medium size PR label Aug 11, 2026
The YAML-aware 3-way merger re-encodes matched files through
gopkg.in/yaml.v3, which has no concept of blank lines between blocks
and silently drops them on every --update, even when nothing
meaningful changed. --merge-driver=text (default stays auto) forces
every file through the line-oriented diff3 merger instead, preserving
formatting conventions YAML re-encoding can't. Applies to both
`atmos scaffold generate --update` and `atmos init --update`, which
share the same merge engine.

Closes cloudposse#2886.
Adds the scaffold-merge-driver blog post announcing the new flag, links it from the dx initiative's roadmap milestone, and registers jorrite in authors.yml.
@jorrite
Jorrit Elfferich (jorrite) force-pushed the feat-scaffold-update-merge-driver branch from 622e0f4 to 1589d65 Compare August 11, 2026 17:27
@coderabbitai

coderabbitai Bot commented Aug 11, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR adds auto and text merge-driver selection to atmos init and scaffold generation. It propagates the setting through the UI and generator engine, validates invalid values, preserves text formatting, and documents the new options.

Changes

Merge-driver selection

Layer / File(s) Summary
Merge engine driver selection
pkg/generator/merge/...
Adds merge-driver types, parsing, forced text merging, and behavior tests.
Generator and UI propagation
pkg/generator/engine/..., pkg/generator/ui/...
Forwards the selected driver from the UI through the processor to the merger. Tests cover identical and diverging inputs.
Init and scaffold command integration
cmd/init/..., cmd/scaffold/..., errors/errors.go
Adds --merge-driver, environment bindings, option propagation, interface updates, validation, and invalid-value tests.
Documentation and roadmap updates
website/docs/..., website/blog/..., website/src/data/roadmap.js
Documents the merge-driver modes, adds a roadmap entry, and adds an author profile.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant InitOrScaffold
  participant InitUI
  participant Processor
  participant ThreeWayMerger
  InitOrScaffold->>InitUI: apply parsed merge.Driver
  InitUI->>Processor: SetMergeDriver(driver)
  Processor->>ThreeWayMerger: SetDriver(driver)
  ThreeWayMerger->>ThreeWayMerger: select YAML-aware or text merge
Loading

Possibly related PRs

Suggested reviewers: aknysh

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR adds an explicit text driver, but the default auto driver can still rewrite unchanged YAML files, so issue #2886 remains unresolved by default. Ensure unchanged YAML files remain byte-for-byte identical during default scaffold updates, or change the default behavior to avoid unnecessary rewrites.
Docstring Coverage ⚠️ Warning Docstring coverage is 18.75% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the primary scaffold merge-driver feature, although it does not mention the corresponding init support.
Out of Scope Changes check ✅ Passed The code, tests, documentation, roadmap entry, and blog content support the merge-driver feature and linked issue objectives.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
website/docs/cli/commands/init.mdx (1)

122-128: 📐 Maintainability & Code Quality | 🔵 Trivial

Run the required website validation for both changed command pages.

  • website/docs/cli/commands/init.mdx#L122-L128: run cd website && npm run build, then verify links, images, and MDX rendering.
  • website/docs/cli/commands/scaffold/generate.mdx#L43-L46: run the same build and verification.
  • website/docs/cli/commands/scaffold/generate.mdx#L144-L150: run the same build and verification.

As per coding guidelines: "website/docs/**/*.mdx: Always run cd website && npm run build after documentation changes and verify links, images, and MDX rendering."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@website/docs/cli/commands/init.mdx` around lines 122 - 128, Run `cd website
&& npm run build` after the documentation changes, then verify links, images,
and MDX rendering for website/docs/cli/commands/init.mdx lines 122-128,
website/docs/cli/commands/scaffold/generate.mdx lines 43-46, and
website/docs/cli/commands/scaffold/generate.mdx lines 144-150.

Source: Coding guidelines

cmd/scaffold/interfaces.go (1)

16-16: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Document SetMergeDriver.

Add a method comment that states that it selects the merger used by scaffold updates. This method is part of the public ScaffoldUI contract.

As per coding guidelines, “Document all exported functions, types, and methods following Go's documentation conventions.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmd/scaffold/interfaces.go` at line 16, Add a Go-style documentation comment
immediately before ScaffoldUI.SetMergeDriver stating that it selects the merger
used by scaffold updates, and ensure the comment begins with SetMergeDriver.

Source: Coding guidelines

pkg/generator/merge/merge_test.go (1)

361-388: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use a table for the driver scenarios.

Lines 361-388 test two variants of the same merge flow. Put the driver and expected formatting properties in a test table. This keeps new driver cases in one execution path.

As per coding guidelines, “Use table-driven tests for testing multiple scenarios in Go.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/generator/merge/merge_test.go` around lines 361 - 388, Refactor the two
driver-specific subtests around NewThreeWayMerger into a table-driven test
covering each driver and its expected blank-line and formatting behavior.
Iterate over the cases through one shared Merge execution path, while preserving
the existing assertions for DriverAuto and DriverText, including list
indentation and merged task checks.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/generator/engine/update_test.go`:
- Around line 268-278: Strengthen TestProcessorSetMergeDriverForcesTextMerge in
pkg/generator/engine/update_test.go (lines 268-278) by asserting the complete
expected output and adding a changed-side merge case that verifies text-driver
selection and byte-for-byte formatting. Apply the same exact-output and
changed-side assertions in pkg/generator/ui/ui_test.go (lines 131-141) through
InitUI.SetMergeDriver; both sites require direct test updates.

In `@website/src/data/roadmap.js`:
- Line 250: Update the roadmap entry’s description for the
`scaffold-merge-driver` changelog to describe `text` as using a line-oriented
diff3-style merge, removing the claim that it is the same algorithm Git uses
while preserving the YAML-aware merger contrast.

---

Nitpick comments:
In `@cmd/scaffold/interfaces.go`:
- Line 16: Add a Go-style documentation comment immediately before
ScaffoldUI.SetMergeDriver stating that it selects the merger used by scaffold
updates, and ensure the comment begins with SetMergeDriver.

In `@pkg/generator/merge/merge_test.go`:
- Around line 361-388: Refactor the two driver-specific subtests around
NewThreeWayMerger into a table-driven test covering each driver and its expected
blank-line and formatting behavior. Iterate over the cases through one shared
Merge execution path, while preserving the existing assertions for DriverAuto
and DriverText, including list indentation and merged task checks.

In `@website/docs/cli/commands/init.mdx`:
- Around line 122-128: Run `cd website && npm run build` after the documentation
changes, then verify links, images, and MDX rendering for
website/docs/cli/commands/init.mdx lines 122-128,
website/docs/cli/commands/scaffold/generate.mdx lines 43-46, and
website/docs/cli/commands/scaffold/generate.mdx lines 144-150.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f4e2e9a8-7593-4d92-acc3-bb28e85b8492

📥 Commits

Reviewing files that changed from the base of the PR and between 6fbcc38 and d27b586.

📒 Files selected for processing (18)
  • cmd/init/init.go
  • cmd/init/init_test.go
  • cmd/scaffold/interfaces.go
  • cmd/scaffold/mock_interfaces.go
  • cmd/scaffold/scaffold.go
  • cmd/scaffold/scaffold_coverage_test.go
  • cmd/scaffold/scaffold_test.go
  • errors/errors.go
  • pkg/generator/engine/merge_update.go
  • pkg/generator/engine/update_test.go
  • pkg/generator/merge/merge.go
  • pkg/generator/merge/merge_test.go
  • pkg/generator/ui/ui.go
  • pkg/generator/ui/ui_test.go
  • website/blog/authors.yml
  • website/docs/cli/commands/init.mdx
  • website/docs/cli/commands/scaffold/generate.mdx
  • website/src/data/roadmap.js

Comment thread pkg/generator/engine/update_test.go
Comment thread website/src/data/roadmap.js Outdated
Comment thread website/blog/2026-08-11-scaffold-merge-driver.mdx Outdated
Strengthens merge-driver tests with exact-content assertions and a
genuine-divergence case (instead of partial substring checks), adds
the missing SetMergeDriver doc comment, converts the driver test to
table-driven, and drops the overclaimed 'same as git' phrasing from
the roadmap entry and changelog post (the text driver uses a
diff3-style merge, not git's own diff3/merge-file implementation).
coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 11, 2026
@osterman Erik Osterman (Cloud Posse) (osterman) added the minor New features that do not break anything label Aug 11, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@website/blog/2026-08-11-scaffold-merge-driver.mdx`:
- Around line 9-10: Revise the merge-preservation claims in the scaffold
merge-driver description, including the corresponding text at the later
referenced section, to use conditional wording. Clarify that local
customizations and comments/blank lines are preserved only when changes are
non-conflicting, while --merge-strategy=theirs may replace local changes in
genuine conflicts.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 368ae820-d041-4fca-97f5-ff3c94363254

📥 Commits

Reviewing files that changed from the base of the PR and between f0234fe and 83bfe48.

📒 Files selected for processing (1)
  • website/blog/2026-08-11-scaffold-merge-driver.mdx

Comment thread website/blog/2026-08-11-scaffold-merge-driver.mdx Outdated
@atmos-pro

atmos-pro Bot commented Aug 14, 2026 •

Copy link
Copy Markdown
Contributor

Tip

Atmos Pro  

No affected stacks workflow was detected for this pull request.
If this is expected, no action is needed.
Learn More. Ask AI.

@codecov

codecov Bot commented Aug 14, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 83.20%. Comparing base (ba152b4) to head (67d26a2).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #2925      +/-   ##
==========================================
- Coverage   83.21%   83.20%   -0.01%     
==========================================
  Files        1893     1893              
  Lines      184127   184170      +43     
==========================================
+ Hits       153216   153238      +22     
- Misses      23082    23096      +14     
- Partials     7829     7836       +7     
Flag Coverage Δ
unittests 83.20% <100.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
cmd/init/init.go 81.86% <100.00%> (+0.83%) ⬆️
cmd/scaffold/scaffold.go 84.56% <100.00%> (+0.24%) ⬆️
errors/errors.go 100.00% <ø> (ø)
pkg/generator/engine/merge_update.go 88.80% <100.00%> (+0.25%) ⬆️
pkg/generator/merge/merge.go 94.02% <100.00%> (+2.54%) ⬆️
pkg/generator/ui/ui.go 53.29% <100.00%> (+0.14%) ⬆️

... and 7 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Merged via the queue into cloudposse:main with commit a4d6427 Aug 14, 2026
156 checks passed
@atmos-pro

atmos-pro Bot commented Aug 14, 2026 •

Copy link
Copy Markdown
Contributor

Tip

Atmos Pro  

No affected stacks workflow was detected for this pull request.
If this is expected, no action is needed.
Learn More. Ask AI.

@github-actions

Copy link
Copy Markdown

These changes were released in v1.226.0-rc.8.

@jorrite
Jorrit Elfferich (jorrite) deleted the feat-scaffold-update-merge-driver branch September 12, 2026 21:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

minor New features that do not break anything size/m Medium size PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

scaffold generate --update collapses blank lines in YAML files that didn't actually change

3 participants