dlin-cli 0.1.0__tar.gz → 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dlin_cli-0.1.1/CHANGELOG.md +11 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/Cargo.lock +1 -1
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/Cargo.toml +1 -1
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/PKG-INFO +32 -4
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/README.md +31 -3
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/cli.rs +73 -11
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/graph/filter.rs +439 -197
- dlin_cli-0.1.1/src/graph/snapshots/dlin__graph__filter__tests__collapse_snapshot.snap +14 -0
- dlin_cli-0.1.1/src/graph/snapshots/dlin__graph__filter__tests__collapse_snapshot_bfs_pseudoendpoint.snap +10 -0
- dlin_cli-0.1.1/src/graph/snapshots/dlin__graph__filter__tests__collapse_snapshot_endpoints_fan_out.snap +17 -0
- dlin_cli-0.1.0/src/graph/snapshots/dlin__graph__filter__tests__collapse_snapshot_global.snap → dlin_cli-0.1.1/src/graph/snapshots/dlin__graph__filter__tests__collapse_snapshot_endpoints_leaf_model.snap +5 -5
- dlin_cli-0.1.1/src/graph/snapshots/dlin__graph__filter__tests__collapse_snapshot_multiple_focus_models.snap +26 -0
- dlin_cli-0.1.1/src/graph/snapshots/dlin__graph__filter__tests__collapse_snapshot_no_source_exposure.snap +10 -0
- dlin_cli-0.1.0/src/graph/snapshots/dlin__graph__filter__tests__collapse_snapshot_by_node_type.snap → dlin_cli-0.1.1/src/graph/snapshots/dlin__graph__filter__tests__collapse_snapshot_preserve_focus.snap +4 -7
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/main.rs +17 -4
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/mermaid.rs +5 -1
- dlin_cli-0.1.0/CHANGELOG.md +0 -5
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/.github/workflows/check.yml +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/.github/workflows/publish-crate.yml +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/.github/workflows/publish-pypi.yml +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/.github/workflows/release.yml +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/.gitignore +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/LICENSE +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/assets/tui-demo.gif +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/dist-workspace.toml +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/pyproject.toml +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/error.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/graph/builder.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/graph/impact.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/graph/mod.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/graph/snapshots/dlin__graph__filter__tests__snapshot_transitive_node_type_filter.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/graph/snapshots/dlin__graph__filter__tests__snapshot_transitive_select_filter.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/graph/snapshots/dlin__graph__filter__tests__snapshot_transitive_select_with_node_type.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/graph/types.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/input.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/lib.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/parser/cache.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/parser/columns.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/parser/discovery.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/parser/jinja.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/parser/manifest.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/parser/mod.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/parser/project.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/parser/sql.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/parser/yaml_schema.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/ascii.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/dot.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/html.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/impact.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/json.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/layout.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/list.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/mod.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/plain.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__dot__tests__group_by_node_type.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__dot__tests__snapshot_all_edge_types.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__dot__tests__snapshot_direction_tb.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__dot__tests__snapshot_direction_tb_grouped.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__dot__tests__snapshot_group_by_directory.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__dot__tests__snapshot_lineage.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__dot__tests__snapshot_transitive_edges.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__html__tests__snapshot_html_json.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__impact__tests__snapshot_impact_json.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__impact__tests__snapshot_impact_json_with_sql.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__impact__tests__snapshot_impact_text.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__impact__tests__snapshot_impact_text_with_sql.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__json__tests__snapshot_json_with_sql.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__json__tests__snapshot_lineage.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__json__tests__snapshot_node_metadata.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__list__tests__snapshot_list_json.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__list__tests__snapshot_list_plain.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__mermaid__tests__group_by_node_type.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__mermaid__tests__mixed_direct_and_transitive_edges.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__mermaid__tests__show_columns_escapes_quotes.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__mermaid__tests__show_columns_lineage.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__mermaid__tests__show_columns_single_model.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__mermaid__tests__show_columns_with_collapse.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__mermaid__tests__show_columns_with_grouping.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__mermaid__tests__snapshot_direction_tb.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__mermaid__tests__snapshot_direction_tb_grouped.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__mermaid__tests__snapshot_group_by_directory.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__mermaid__tests__snapshot_lineage.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__mermaid__tests__transitive_edge_rendering.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__plain__tests__snapshot_plain.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__summary__tests__snapshot_summary_json.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/snapshots/dlin__render__summary__tests__snapshot_summary_text.snap +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/summary.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/src/render/svg.rs +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/tests/fixtures/simple_project/.dlin_cache/.gitignore +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/tests/fixtures/simple_project/dbt_project.yml +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/tests/fixtures/simple_project/macros/order_totals.sql +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/tests/fixtures/simple_project/models/marts/combined_orders.sql +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/tests/fixtures/simple_project/models/marts/customers.sql +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/tests/fixtures/simple_project/models/marts/order_summary.sql +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/tests/fixtures/simple_project/models/marts/orders.sql +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/tests/fixtures/simple_project/models/marts/schema.yml +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/tests/fixtures/simple_project/models/staging/schema.yml +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/tests/fixtures/simple_project/models/staging/stg_customers.sql +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/tests/fixtures/simple_project/models/staging/stg_online_orders.sql +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/tests/fixtures/simple_project/models/staging/stg_orders.sql +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/tests/fixtures/simple_project/models/staging/stg_payments.sql +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/tests/fixtures/simple_project/models/staging/stg_retail_orders.sql +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/tests/fixtures/simple_project/seeds/countries.csv +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/tests/fixtures/simple_project/target/manifest.json +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/tests/fixtures/simple_project/target/run_results.json +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/tests/fixtures/simple_project/tests/assert_orders_positive_amount.sql +0 -0
- {dlin_cli-0.1.0 → dlin_cli-0.1.1}/tests/integration_test.rs +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dlin-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Classifier: Development Status :: 4 - Beta
|
|
5
5
|
Classifier: Environment :: Console
|
|
6
6
|
Classifier: Intended Audience :: Developers
|
|
@@ -87,6 +87,30 @@ dlin list -o json --json-fields unique_id,file_path
|
|
|
87
87
|
git diff --name-only main | dlin graph -o json
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
+
## AI agent integration
|
|
91
|
+
|
|
92
|
+
No MCP server or tool configuration needed.
|
|
93
|
+
Just install dlin and add the following to your `AGENTS.md`, `CLAUDE.md`, or system prompt:
|
|
94
|
+
|
|
95
|
+
````md
|
|
96
|
+
## dbt project structure analysis
|
|
97
|
+
|
|
98
|
+
Use `dlin` to explore dbt model dependencies.
|
|
99
|
+
Do NOT grep/cat/find through SQL files.
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
dlin summary # Project overview (start here)
|
|
103
|
+
dlin graph <model> -u 2 -d 1 -q # Upstream/downstream lineage
|
|
104
|
+
dlin impact <model> # Downstream impact with severity
|
|
105
|
+
dlin list -o json --json-fields unique_id,sql_content # Read SQL content
|
|
106
|
+
git diff --name-only main | dlin graph -q # Lineage of changed files
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
For full option reference: `dlin --help`, `dlin graph --help`, etc.
|
|
110
|
+
````
|
|
111
|
+
|
|
112
|
+
The key line is **"Do NOT grep/cat/find through SQL files"** — without it, agents default to familiar tools. `dlin --help` is designed for tool discovery, so the prompt can stay minimal.
|
|
113
|
+
|
|
90
114
|
## Features
|
|
91
115
|
|
|
92
116
|
- **No dependencies**: single binary, no Python, no `manifest.json`
|
|
@@ -101,11 +125,15 @@ dlin outputs Mermaid flowcharts that render natively on GitHub, GitLab, Notion,
|
|
|
101
125
|
|
|
102
126
|
### Simplified graphs with `--collapse`
|
|
103
127
|
|
|
104
|
-
Automatically remove intermediate nodes to see just the endpoints
|
|
128
|
+
Automatically remove intermediate nodes to see just the endpoints (nodes with no predecessors or no successors); everything in between becomes transitive "(via N)" edges:
|
|
105
129
|
|
|
106
130
|
```sh
|
|
107
131
|
# Collapse intermediate models — only endpoints remain
|
|
108
132
|
dlin graph --collapse -o mermaid
|
|
133
|
+
|
|
134
|
+
# Focal mode: keep only sources, exposures, and specified focus models
|
|
135
|
+
# (ignores BFS window pseudo-endpoints — ideal with -u/-d limits)
|
|
136
|
+
dlin graph orders --collapse=focal -u 3 -o mermaid
|
|
109
137
|
```
|
|
110
138
|
|
|
111
139
|
```mermaid
|
|
@@ -135,7 +163,7 @@ flowchart LR
|
|
|
135
163
|
class source_raw_payments source
|
|
136
164
|
```
|
|
137
165
|
|
|
138
|
-
|
|
166
|
+
Positional focus models are always preserved during collapse, so `dlin graph orders --collapse` keeps `orders` even if it would otherwise be intermediate.
|
|
139
167
|
|
|
140
168
|
### Pipe to build focused diagrams
|
|
141
169
|
|
|
@@ -213,8 +241,8 @@ Combines well with `--collapse` to show rich detail on fewer endpoint nodes.
|
|
|
213
241
|
|
|
214
242
|
```sh
|
|
215
243
|
dlin graph orders -u 2 -d 1 # focus on specific model
|
|
216
|
-
dlin graph -o mermaid --collapse --group-by node-type # collapse per node type layer
|
|
217
244
|
dlin graph -o mermaid --collapse --show-columns # columns in collapsed nodes
|
|
245
|
+
dlin graph orders --collapse=focal -u 3 -o mermaid # focal: sources + exposures + orders
|
|
218
246
|
dlin graph -o mermaid --group-by directory # group by directory
|
|
219
247
|
dlin graph -o mermaid --direction tb # top-to-bottom layout
|
|
220
248
|
dlin graph --node-type source,exposure # filter by node type
|
|
@@ -65,6 +65,30 @@ dlin list -o json --json-fields unique_id,file_path
|
|
|
65
65
|
git diff --name-only main | dlin graph -o json
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
+
## AI agent integration
|
|
69
|
+
|
|
70
|
+
No MCP server or tool configuration needed.
|
|
71
|
+
Just install dlin and add the following to your `AGENTS.md`, `CLAUDE.md`, or system prompt:
|
|
72
|
+
|
|
73
|
+
````md
|
|
74
|
+
## dbt project structure analysis
|
|
75
|
+
|
|
76
|
+
Use `dlin` to explore dbt model dependencies.
|
|
77
|
+
Do NOT grep/cat/find through SQL files.
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
dlin summary # Project overview (start here)
|
|
81
|
+
dlin graph <model> -u 2 -d 1 -q # Upstream/downstream lineage
|
|
82
|
+
dlin impact <model> # Downstream impact with severity
|
|
83
|
+
dlin list -o json --json-fields unique_id,sql_content # Read SQL content
|
|
84
|
+
git diff --name-only main | dlin graph -q # Lineage of changed files
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
For full option reference: `dlin --help`, `dlin graph --help`, etc.
|
|
88
|
+
````
|
|
89
|
+
|
|
90
|
+
The key line is **"Do NOT grep/cat/find through SQL files"** — without it, agents default to familiar tools. `dlin --help` is designed for tool discovery, so the prompt can stay minimal.
|
|
91
|
+
|
|
68
92
|
## Features
|
|
69
93
|
|
|
70
94
|
- **No dependencies**: single binary, no Python, no `manifest.json`
|
|
@@ -79,11 +103,15 @@ dlin outputs Mermaid flowcharts that render natively on GitHub, GitLab, Notion,
|
|
|
79
103
|
|
|
80
104
|
### Simplified graphs with `--collapse`
|
|
81
105
|
|
|
82
|
-
Automatically remove intermediate nodes to see just the endpoints
|
|
106
|
+
Automatically remove intermediate nodes to see just the endpoints (nodes with no predecessors or no successors); everything in between becomes transitive "(via N)" edges:
|
|
83
107
|
|
|
84
108
|
```sh
|
|
85
109
|
# Collapse intermediate models — only endpoints remain
|
|
86
110
|
dlin graph --collapse -o mermaid
|
|
111
|
+
|
|
112
|
+
# Focal mode: keep only sources, exposures, and specified focus models
|
|
113
|
+
# (ignores BFS window pseudo-endpoints — ideal with -u/-d limits)
|
|
114
|
+
dlin graph orders --collapse=focal -u 3 -o mermaid
|
|
87
115
|
```
|
|
88
116
|
|
|
89
117
|
```mermaid
|
|
@@ -113,7 +141,7 @@ flowchart LR
|
|
|
113
141
|
class source_raw_payments source
|
|
114
142
|
```
|
|
115
143
|
|
|
116
|
-
|
|
144
|
+
Positional focus models are always preserved during collapse, so `dlin graph orders --collapse` keeps `orders` even if it would otherwise be intermediate.
|
|
117
145
|
|
|
118
146
|
### Pipe to build focused diagrams
|
|
119
147
|
|
|
@@ -191,8 +219,8 @@ Combines well with `--collapse` to show rich detail on fewer endpoint nodes.
|
|
|
191
219
|
|
|
192
220
|
```sh
|
|
193
221
|
dlin graph orders -u 2 -d 1 # focus on specific model
|
|
194
|
-
dlin graph -o mermaid --collapse --group-by node-type # collapse per node type layer
|
|
195
222
|
dlin graph -o mermaid --collapse --show-columns # columns in collapsed nodes
|
|
223
|
+
dlin graph orders --collapse=focal -u 3 -o mermaid # focal: sources + exposures + orders
|
|
196
224
|
dlin graph -o mermaid --group-by directory # group by directory
|
|
197
225
|
dlin graph -o mermaid --direction tb # top-to-bottom layout
|
|
198
226
|
dlin graph --node-type source,exposure # filter by node type
|
|
@@ -68,6 +68,14 @@ pub struct Cli {
|
|
|
68
68
|
pub command: Command,
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
|
|
72
|
+
pub enum CollapseMode {
|
|
73
|
+
/// Keep topological endpoints (in-degree=0 or out-degree=0) and focus models
|
|
74
|
+
Endpoints,
|
|
75
|
+
/// Keep only source/exposure nodes and focus models (ignores BFS window boundaries)
|
|
76
|
+
Focal,
|
|
77
|
+
}
|
|
78
|
+
|
|
71
79
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
|
|
72
80
|
pub enum GroupBy {
|
|
73
81
|
/// Group nodes by node type (source, model, test, etc.)
|
|
@@ -202,6 +210,11 @@ Examples:
|
|
|
202
210
|
dlin graph -o dot | dot -Tsvg > lineage.svg
|
|
203
211
|
dlin graph -o mermaid --direction tb # top-to-bottom layout
|
|
204
212
|
|
|
213
|
+
# === Collapse (simplify by removing intermediate nodes) ===
|
|
214
|
+
dlin graph --collapse # keep only graph endpoints
|
|
215
|
+
dlin graph orders --collapse # endpoints + orders preserved
|
|
216
|
+
dlin graph orders --collapse=focal -u 3 # sources + exposures + orders only
|
|
217
|
+
|
|
205
218
|
# === Column display (mermaid only) ===
|
|
206
219
|
dlin graph -o mermaid --show-columns # show columns in node labels
|
|
207
220
|
dlin graph -o mermaid --collapse --show-columns # rich detail on fewer nodes"
|
|
@@ -261,18 +274,24 @@ pub struct GraphArgs {
|
|
|
261
274
|
#[arg(long)]
|
|
262
275
|
pub no_transitive: bool,
|
|
263
276
|
|
|
264
|
-
/// Collapse intermediate nodes,
|
|
265
|
-
///
|
|
266
|
-
///
|
|
267
|
-
///
|
|
268
|
-
///
|
|
269
|
-
///
|
|
270
|
-
///
|
|
271
|
-
///
|
|
272
|
-
///
|
|
277
|
+
/// Collapse intermediate nodes, replacing them with transitive edges
|
|
278
|
+
/// shown as "(via N)" in DOT/Mermaid output.
|
|
279
|
+
///
|
|
280
|
+
/// Without a value (--collapse), defaults to "endpoints" mode: keeps
|
|
281
|
+
/// nodes with no predecessors or no successors, plus focus models.
|
|
282
|
+
///
|
|
283
|
+
/// With --collapse=focal: keeps only source/exposure nodes and focus
|
|
284
|
+
/// models as endpoints. Endpoint selection ignores BFS window boundaries
|
|
285
|
+
/// (-u/-d), so window-edge nodes are not treated as pseudo-endpoints,
|
|
286
|
+
/// but traversal still respects the -u/-d limits.
|
|
287
|
+
///
|
|
288
|
+
/// Focus models are preserved even if they would otherwise be intermediate,
|
|
289
|
+
/// as long as they are not removed earlier by filters like --select or
|
|
290
|
+
/// --node-type.
|
|
291
|
+
///
|
|
273
292
|
/// Ignored when --no-transitive is set.
|
|
274
|
-
#[arg(long)]
|
|
275
|
-
pub collapse:
|
|
293
|
+
#[arg(long, value_name = "MODE", default_missing_value = "endpoints", num_args = 0..=1, require_equals = true)]
|
|
294
|
+
pub collapse: Option<CollapseMode>,
|
|
276
295
|
|
|
277
296
|
/// Group nodes using subgraph/cluster blocks in supported formats (dot, mermaid).
|
|
278
297
|
/// Supported values: node-type (group by source, model, test, etc.),
|
|
@@ -1182,4 +1201,47 @@ mod tests {
|
|
|
1182
1201
|
Cli::try_parse_from(["dlin", "--error-format", "json", "impact", "orders"]).unwrap();
|
|
1183
1202
|
assert_eq!(cli.error_format, ErrorFormat::Json);
|
|
1184
1203
|
}
|
|
1204
|
+
|
|
1205
|
+
// -- Collapse CLI parsing tests -------------------------------------------
|
|
1206
|
+
|
|
1207
|
+
#[test]
|
|
1208
|
+
fn test_collapse_none_by_default() {
|
|
1209
|
+
let args = unwrap_graph(Cli::try_parse_from(["dlin", "graph"]).unwrap());
|
|
1210
|
+
assert_eq!(args.collapse, None);
|
|
1211
|
+
}
|
|
1212
|
+
|
|
1213
|
+
#[test]
|
|
1214
|
+
fn test_collapse_bare_defaults_to_endpoints() {
|
|
1215
|
+
let args = unwrap_graph(Cli::try_parse_from(["dlin", "graph", "--collapse"]).unwrap());
|
|
1216
|
+
assert_eq!(args.collapse, Some(CollapseMode::Endpoints));
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
#[test]
|
|
1220
|
+
fn test_collapse_explicit_endpoints() {
|
|
1221
|
+
let args =
|
|
1222
|
+
unwrap_graph(Cli::try_parse_from(["dlin", "graph", "--collapse=endpoints"]).unwrap());
|
|
1223
|
+
assert_eq!(args.collapse, Some(CollapseMode::Endpoints));
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
#[test]
|
|
1227
|
+
fn test_collapse_focal() {
|
|
1228
|
+
let args =
|
|
1229
|
+
unwrap_graph(Cli::try_parse_from(["dlin", "graph", "--collapse=focal"]).unwrap());
|
|
1230
|
+
assert_eq!(args.collapse, Some(CollapseMode::Focal));
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
#[test]
|
|
1234
|
+
fn test_collapse_invalid_mode_rejected() {
|
|
1235
|
+
let result = Cli::try_parse_from(["dlin", "graph", "--collapse=invalid"]);
|
|
1236
|
+
assert!(result.is_err());
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
#[test]
|
|
1240
|
+
fn test_collapse_bare_does_not_consume_model() {
|
|
1241
|
+
// --collapse without = must not swallow the next positional as MODE
|
|
1242
|
+
let args =
|
|
1243
|
+
unwrap_graph(Cli::try_parse_from(["dlin", "graph", "--collapse", "orders"]).unwrap());
|
|
1244
|
+
assert_eq!(args.collapse, Some(CollapseMode::Endpoints));
|
|
1245
|
+
assert_eq!(args.model, vec!["orders".to_string()]);
|
|
1246
|
+
}
|
|
1185
1247
|
}
|