Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/examples/cute-dbt-pr-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ jobs:
run: |
set -euo pipefail
mkdir -p _site
git diff --unified=0 \
git diff --unified=0 --find-renames \
"${{ github.event.pull_request.base.sha }}...${{ github.event.pull_request.head.sha }}" \
> diff.patch
cute-dbt \
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/report-preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ jobs:
# consumed from git), so changes there are not a model/test SOURCE
# change and must NOT trigger the full fusion-install + compile +
# render for an empty-scope report.
git diff --unified=0 "${BASE_SHA}...${HEAD_SHA}" \
git diff --unified=0 --find-renames "${BASE_SHA}...${HEAD_SHA}" \
-- dbt-project/ ':(exclude)dbt-project/target/' \
> target/report-preview/prdiff.patch
if [ -s target/report-preview/prdiff.patch ]; then
Expand Down
9 changes: 7 additions & 2 deletions book/src/how-it-works.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,13 @@ path-granular**. So in v0.1:
- A `packages.yml` / `dbt deps` change that alters compiled output
without touching a model `.sql` / `.yml` is not detected — the diff
carries no path that maps to an affected node.
- A **renamed** model shows as deleted-path + added-path; the deleted
path maps to no current node.

A **renamed** model is handled: `git diff` detects renames by default
(since git 2.9) and emits a `rename from`/`rename to` header pair;
cute-dbt maps **both** paths onto the scope match, and the current
manifest (compiled at the PR head) resolves the new path to the renamed
node — so even a *pure* rename (100% similarity, no hunks at all)
scopes the model under its new name.
Comment thread
cmbays marked this conversation as resolved.

Need any of these? Use `--baseline-manifest`, which compares compiled
bodies directly. The [recipe](./recipes/github-actions-pr-review.md)
Expand Down
23 changes: 18 additions & 5 deletions book/src/recipes/github-actions-pr-review.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ depend on `origin` remote semantics or branch-name resolution), with

```bash
mkdir -p _site
git diff --unified=0 \
git diff --unified=0 --find-renames \
"${{ github.event.pull_request.base.sha }}...${{ github.event.pull_request.head.sha }}" \
> diff.patch

Expand All @@ -96,7 +96,14 @@ cute-dbt \
"read from this file"). cute-dbt parses the diff's `+++ b/<path>` headers
to pick the in-scope set and its `@@ … @@` hunks to flag which tests the
PR actually edited (block-precise updated detection + the inline YAML diff
drawer key off the hunk spans). When a hunk changes a model's `.sql`, the
drawer key off the hunk spans). It also reads the `rename from`/`rename
to` headers git emits for detected renames, so a renamed model — even a
*pure* rename, which carries no hunks — scopes under its new name.
`--find-renames` just makes git's default rename detection explicit
(config-proof against a runner that sets `diff.renames = false`); a
patch produced without it still works — a rename-detection-off diff
shows the rename as a deleted + an added file, and the added path
scopes the same node. When a hunk changes a model's `.sql`, the
Model SQL section also shows an inline **SQL diff** of the model's raw
Jinja with a Raw ↔ Diff toggle — same diff engine, keyed off the same
hunks. Both inline diffs ignore whitespace-only edits as standard (a pure
Expand Down Expand Up @@ -234,7 +241,7 @@ jobs:
run: |
set -euo pipefail
mkdir -p _site
git diff --unified=0 \
git diff --unified=0 --find-renames \
"${{ github.event.pull_request.base.sha }}...${{ github.event.pull_request.head.sha }}" \
> diff.patch
cute-dbt \
Expand Down Expand Up @@ -561,8 +568,14 @@ scope by design (use `--baseline-manifest` if you need them):
- A `packages.yml` / `dbt deps` change that alters compiled output without
touching a `.sql`/`.yml` model file — the diff carries no path that maps
to an affected node.
- A **renamed** model (the diff shows a deleted path + an added path; the
deleted path maps to no current-manifest node).

A **renamed** model is no longer on this list: cute-dbt reads the
`rename from`/`rename to` headers `git diff` emits (rename detection is
on by default since git 2.9) and maps both paths onto the scope match,
so even a pure rename — which carries no hunks at all — scopes the
model under its new name. The `--find-renames` flag in § 3 makes that
detection explicit, so a runner whose git config sets
`diff.renames = false` produces the same patch shape.

A YAML **config-block** edit no longer mislabels a sibling test as
updated: block precision flags only the tests whose block a diff hunk
Expand Down
30 changes: 24 additions & 6 deletions features/pr_diff_scoping.feature
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,30 @@ Feature: Diff-scope unit tests and models via PR file diff (CI path)
Then the exit code is 0
And the rendered report shows the "0 unit tests in scope" banner

# Renamed-model behavior is a documented fidelity limit (PR-diff sees the
# rename as one deleted path + one added path; the deleted path maps to no
# current-manifest node, the added path maps to the new node).
# tracked: cute-dbt#80 — restoration condition: if rename detection becomes
# load-bearing, layer a git-rename signal on top of `git diff --name-only`.
# Not blocking v0.1.x.
# --- Renamed models (cute-dbt#80) ---
# `git diff` detects renames by default (since git 2.9) and emits a
# `rename from`/`rename to` header pair. A PURE rename (100% similarity)
# carries no `+++ b/` header and no hunks — before cute-dbt#80 it scoped
# nothing. cute-dbt now maps BOTH rename sides onto the scope match; the
# current manifest (compiled at the PR head) resolves the new path to the
# renamed node, so the model scopes under its new name.

Scenario: A pure model rename puts the renamed model in scope under its new name
Given a PR diff that renames "models/marts/core/dim_payers.sql" to "models/marts/core/payer_dimensions.sql" with no content change
And the manifest contains a model with original_file_path "models/marts/core/payer_dimensions.sql"
And the model "payer_dimensions" has a unit test "test_payer_dimensions_injects_unknown_sentinel"
When I run cute-dbt with --manifest current.json --pr-diff @diff.patch --project-root . --out report.html
Then the exit code is 0
And the rendered report's models-in-scope listing contains "payer_dimensions"
And the rendered report's models-in-scope listing does NOT contain "dim_payers"
And the rendered report's test rows include "test_payer_dimensions_injects_unknown_sentinel"

Scenario: A rename with edits puts the renamed model in scope under its new name
Given a PR diff that renames "models/marts/core/dim_payers.sql" to "models/marts/core/payer_dimensions.sql" and edits it
And the manifest contains a model with original_file_path "models/marts/core/payer_dimensions.sql"
When I run cute-dbt with --manifest current.json --pr-diff @diff.patch --project-root . --out report.html
Then the exit code is 0
And the rendered report's models-in-scope listing contains "payer_dimensions"

# --- Malformed input (clap usage error; cute-dbt#96) ---

Expand Down
1 change: 1 addition & 0 deletions src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1257,6 +1257,7 @@ mod tests {
fn index_for(path: &str, removed: &str, added: &str, line: usize) -> NormalizedDiffIndex {
use crate::domain::{FileHunks, Hunk, PrDiff};
let diff = PrDiff {
renames: Vec::new(),
files: vec![FileHunks {
path: path.to_owned(),
hunks: vec![Hunk {
Expand Down
Loading
Loading