dlin-cli 0.1.1__tar.gz → 0.1.2__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 → dlin_cli-0.1.2}/Cargo.lock +23 -2
- {dlin_cli-0.1.1 → dlin_cli-0.1.2}/Cargo.toml +18 -22
- {dlin_cli-0.1.1 → dlin_cli-0.1.2}/PKG-INFO +4 -2
- {dlin_cli-0.1.1 → dlin_cli-0.1.2}/README.md +3 -1
- dlin_cli-0.1.2/crates/dlin/Cargo.toml +35 -0
- dlin_cli-0.1.2/crates/dlin/README.md +292 -0
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin}/src/cli.rs +272 -132
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin}/src/main.rs +63 -42
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin}/tests/integration_test.rs +241 -8
- dlin_cli-0.1.2/crates/dlin-core/Cargo.toml +40 -0
- dlin_cli-0.1.2/crates/dlin-core/README.md +292 -0
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/graph/builder.rs +360 -10
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/graph/filter.rs +5 -5
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/graph/impact.rs +2 -1
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/input.rs +4 -2
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/lib.rs +47 -1
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/parser/manifest.rs +20 -7
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/parser/yaml_schema.rs +63 -0
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/render/dot.rs +1 -1
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/render/html.rs +2 -1
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/render/json.rs +2 -1
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/render/list.rs +1 -1
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/render/mermaid.rs +2 -2
- {dlin_cli-0.1.1 → dlin_cli-0.1.2}/pyproject.toml +1 -1
- dlin_cli-0.1.1/.github/workflows/check.yml +0 -86
- dlin_cli-0.1.1/.github/workflows/publish-crate.yml +0 -24
- dlin_cli-0.1.1/.github/workflows/publish-pypi.yml +0 -74
- dlin_cli-0.1.1/.github/workflows/release.yml +0 -296
- dlin_cli-0.1.1/.gitignore +0 -2
- dlin_cli-0.1.1/CHANGELOG.md +0 -11
- dlin_cli-0.1.1/assets/tui-demo.gif +0 -0
- dlin_cli-0.1.1/dist-workspace.toml +0 -23
- dlin_cli-0.1.1/tests/fixtures/simple_project/.dlin_cache/.gitignore +0 -2
- dlin_cli-0.1.1/tests/fixtures/simple_project/dbt_project.yml +0 -12
- dlin_cli-0.1.1/tests/fixtures/simple_project/macros/order_totals.sql +0 -7
- dlin_cli-0.1.1/tests/fixtures/simple_project/models/marts/combined_orders.sql +0 -4
- dlin_cli-0.1.1/tests/fixtures/simple_project/models/marts/customers.sql +0 -12
- dlin_cli-0.1.1/tests/fixtures/simple_project/models/marts/order_summary.sql +0 -5
- dlin_cli-0.1.1/tests/fixtures/simple_project/models/marts/orders.sql +0 -9
- dlin_cli-0.1.1/tests/fixtures/simple_project/models/marts/schema.yml +0 -16
- dlin_cli-0.1.1/tests/fixtures/simple_project/models/staging/schema.yml +0 -18
- dlin_cli-0.1.1/tests/fixtures/simple_project/models/staging/stg_customers.sql +0 -6
- dlin_cli-0.1.1/tests/fixtures/simple_project/models/staging/stg_online_orders.sql +0 -2
- dlin_cli-0.1.1/tests/fixtures/simple_project/models/staging/stg_orders.sql +0 -6
- dlin_cli-0.1.1/tests/fixtures/simple_project/models/staging/stg_payments.sql +0 -6
- dlin_cli-0.1.1/tests/fixtures/simple_project/models/staging/stg_retail_orders.sql +0 -2
- dlin_cli-0.1.1/tests/fixtures/simple_project/seeds/countries.csv +0 -4
- dlin_cli-0.1.1/tests/fixtures/simple_project/target/manifest.json +0 -175
- dlin_cli-0.1.1/tests/fixtures/simple_project/target/run_results.json +0 -76
- dlin_cli-0.1.1/tests/fixtures/simple_project/tests/assert_orders_positive_amount.sql +0 -3
- {dlin_cli-0.1.1 → dlin_cli-0.1.2}/LICENSE +0 -0
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/error.rs +0 -0
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/graph/mod.rs +0 -0
- /dlin_cli-0.1.1/src/graph/snapshots/dlin__graph__filter__tests__collapse_snapshot.snap → /dlin_cli-0.1.2/crates/dlin-core/src/graph/snapshots/dlin_core__graph__filter__tests__collapse_snapshot.snap +0 -0
- /dlin_cli-0.1.1/src/graph/snapshots/dlin__graph__filter__tests__collapse_snapshot_bfs_pseudoendpoint.snap → /dlin_cli-0.1.2/crates/dlin-core/src/graph/snapshots/dlin_core__graph__filter__tests__collapse_snapshot_bfs_pseudoendpoint.snap +0 -0
- /dlin_cli-0.1.1/src/graph/snapshots/dlin__graph__filter__tests__collapse_snapshot_endpoints_fan_out.snap → /dlin_cli-0.1.2/crates/dlin-core/src/graph/snapshots/dlin_core__graph__filter__tests__collapse_snapshot_endpoints_fan_out.snap +0 -0
- /dlin_cli-0.1.1/src/graph/snapshots/dlin__graph__filter__tests__collapse_snapshot_endpoints_leaf_model.snap → /dlin_cli-0.1.2/crates/dlin-core/src/graph/snapshots/dlin_core__graph__filter__tests__collapse_snapshot_endpoints_leaf_model.snap +0 -0
- /dlin_cli-0.1.1/src/graph/snapshots/dlin__graph__filter__tests__collapse_snapshot_multiple_focus_models.snap → /dlin_cli-0.1.2/crates/dlin-core/src/graph/snapshots/dlin_core__graph__filter__tests__collapse_snapshot_multiple_focus_models.snap +0 -0
- /dlin_cli-0.1.1/src/graph/snapshots/dlin__graph__filter__tests__collapse_snapshot_no_source_exposure.snap → /dlin_cli-0.1.2/crates/dlin-core/src/graph/snapshots/dlin_core__graph__filter__tests__collapse_snapshot_no_source_exposure.snap +0 -0
- /dlin_cli-0.1.1/src/graph/snapshots/dlin__graph__filter__tests__collapse_snapshot_preserve_focus.snap → /dlin_cli-0.1.2/crates/dlin-core/src/graph/snapshots/dlin_core__graph__filter__tests__collapse_snapshot_preserve_focus.snap +0 -0
- /dlin_cli-0.1.1/src/graph/snapshots/dlin__graph__filter__tests__snapshot_transitive_node_type_filter.snap → /dlin_cli-0.1.2/crates/dlin-core/src/graph/snapshots/dlin_core__graph__filter__tests__snapshot_transitive_node_type_filter.snap +0 -0
- /dlin_cli-0.1.1/src/graph/snapshots/dlin__graph__filter__tests__snapshot_transitive_select_filter.snap → /dlin_cli-0.1.2/crates/dlin-core/src/graph/snapshots/dlin_core__graph__filter__tests__snapshot_transitive_select_filter.snap +0 -0
- /dlin_cli-0.1.1/src/graph/snapshots/dlin__graph__filter__tests__snapshot_transitive_select_with_node_type.snap → /dlin_cli-0.1.2/crates/dlin-core/src/graph/snapshots/dlin_core__graph__filter__tests__snapshot_transitive_select_with_node_type.snap +0 -0
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/graph/types.rs +0 -0
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/parser/cache.rs +0 -0
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/parser/columns.rs +0 -0
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/parser/discovery.rs +0 -0
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/parser/jinja.rs +0 -0
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/parser/mod.rs +0 -0
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/parser/project.rs +0 -0
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/parser/sql.rs +0 -0
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/render/ascii.rs +0 -0
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/render/impact.rs +0 -0
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/render/layout.rs +0 -0
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/render/mod.rs +0 -0
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/render/plain.rs +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__dot__tests__group_by_node_type.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__group_by_node_type.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__dot__tests__snapshot_all_edge_types.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_all_edge_types.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__dot__tests__snapshot_direction_tb.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_direction_tb.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__dot__tests__snapshot_direction_tb_grouped.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_direction_tb_grouped.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__dot__tests__snapshot_group_by_directory.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_group_by_directory.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__dot__tests__snapshot_lineage.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_lineage.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__dot__tests__snapshot_transitive_edges.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_transitive_edges.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__html__tests__snapshot_html_json.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__html__tests__snapshot_html_json.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__impact__tests__snapshot_impact_json.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__impact__tests__snapshot_impact_json.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__impact__tests__snapshot_impact_json_with_sql.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__impact__tests__snapshot_impact_json_with_sql.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__impact__tests__snapshot_impact_text.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__impact__tests__snapshot_impact_text.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__impact__tests__snapshot_impact_text_with_sql.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__impact__tests__snapshot_impact_text_with_sql.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__json__tests__snapshot_json_with_sql.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__json__tests__snapshot_json_with_sql.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__json__tests__snapshot_lineage.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__json__tests__snapshot_lineage.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__json__tests__snapshot_node_metadata.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__json__tests__snapshot_node_metadata.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__list__tests__snapshot_list_json.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__list__tests__snapshot_list_json.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__list__tests__snapshot_list_plain.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__list__tests__snapshot_list_plain.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__mermaid__tests__group_by_node_type.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__group_by_node_type.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__mermaid__tests__mixed_direct_and_transitive_edges.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__mixed_direct_and_transitive_edges.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__mermaid__tests__show_columns_escapes_quotes.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_escapes_quotes.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__mermaid__tests__show_columns_lineage.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_lineage.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__mermaid__tests__show_columns_single_model.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_single_model.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__mermaid__tests__show_columns_with_collapse.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_with_collapse.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__mermaid__tests__show_columns_with_grouping.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_with_grouping.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__mermaid__tests__snapshot_direction_tb.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__snapshot_direction_tb.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__mermaid__tests__snapshot_direction_tb_grouped.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__snapshot_direction_tb_grouped.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__mermaid__tests__snapshot_group_by_directory.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__snapshot_group_by_directory.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__mermaid__tests__snapshot_lineage.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__snapshot_lineage.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__mermaid__tests__transitive_edge_rendering.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__transitive_edge_rendering.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__plain__tests__snapshot_plain.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__plain__tests__snapshot_plain.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__summary__tests__snapshot_summary_json.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__summary__tests__snapshot_summary_json.snap +0 -0
- /dlin_cli-0.1.1/src/render/snapshots/dlin__render__summary__tests__snapshot_summary_text.snap → /dlin_cli-0.1.2/crates/dlin-core/src/render/snapshots/dlin_core__render__summary__tests__snapshot_summary_text.snap +0 -0
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/render/summary.rs +0 -0
- {dlin_cli-0.1.1 → dlin_cli-0.1.2/crates/dlin-core}/src/render/svg.rs +0 -0
|
@@ -231,7 +231,22 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
|
|
231
231
|
|
|
232
232
|
[[package]]
|
|
233
233
|
name = "dlin"
|
|
234
|
-
version = "0.1.
|
|
234
|
+
version = "0.1.2"
|
|
235
|
+
dependencies = [
|
|
236
|
+
"anyhow",
|
|
237
|
+
"clap",
|
|
238
|
+
"dlin-core",
|
|
239
|
+
"libc",
|
|
240
|
+
"path-slash",
|
|
241
|
+
"regex",
|
|
242
|
+
"serde-saphyr",
|
|
243
|
+
"serde_json",
|
|
244
|
+
"tempfile",
|
|
245
|
+
]
|
|
246
|
+
|
|
247
|
+
[[package]]
|
|
248
|
+
name = "dlin-core"
|
|
249
|
+
version = "0.1.2"
|
|
235
250
|
dependencies = [
|
|
236
251
|
"anyhow",
|
|
237
252
|
"clap",
|
|
@@ -239,8 +254,8 @@ dependencies = [
|
|
|
239
254
|
"globset",
|
|
240
255
|
"indexmap",
|
|
241
256
|
"insta",
|
|
242
|
-
"libc",
|
|
243
257
|
"minijinja",
|
|
258
|
+
"path-slash",
|
|
244
259
|
"petgraph",
|
|
245
260
|
"rayon",
|
|
246
261
|
"regex",
|
|
@@ -576,6 +591,12 @@ dependencies = [
|
|
|
576
591
|
"windows-link",
|
|
577
592
|
]
|
|
578
593
|
|
|
594
|
+
[[package]]
|
|
595
|
+
name = "path-slash"
|
|
596
|
+
version = "0.2.1"
|
|
597
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
598
|
+
checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42"
|
|
599
|
+
|
|
579
600
|
[[package]]
|
|
580
601
|
name = "petgraph"
|
|
581
602
|
version = "0.6.5"
|
|
@@ -1,21 +1,15 @@
|
|
|
1
|
-
[
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
[workspace]
|
|
2
|
+
members = ["crates/*"]
|
|
3
|
+
resolver = "3"
|
|
4
|
+
|
|
5
|
+
[workspace.package]
|
|
6
|
+
version = "0.1.2"
|
|
4
7
|
edition = "2024"
|
|
5
|
-
description = "A fast CLI tool for dbt model lineage analysis"
|
|
6
8
|
license = "MIT"
|
|
7
9
|
repository = "https://github.com/eitsupi/dlin"
|
|
8
10
|
homepage = "https://github.com/eitsupi/dlin"
|
|
9
|
-
readme = "README.md"
|
|
10
|
-
keywords = ["dbt", "lineage", "dag", "sql", "cli"]
|
|
11
|
-
categories = ["command-line-utilities", "visualization"]
|
|
12
|
-
|
|
13
|
-
[[bin]]
|
|
14
|
-
name = "dlin"
|
|
15
|
-
path = "src/main.rs"
|
|
16
11
|
|
|
17
|
-
[dependencies]
|
|
18
|
-
clap = { version = "4", features = ["derive", "env"] }
|
|
12
|
+
[workspace.dependencies]
|
|
19
13
|
petgraph = "0.6"
|
|
20
14
|
serde = { version = "1", features = ["derive"] }
|
|
21
15
|
serde_json = "1"
|
|
@@ -29,11 +23,19 @@ indexmap = "2"
|
|
|
29
23
|
minijinja = "2"
|
|
30
24
|
rayon = "1"
|
|
31
25
|
globset = "0.4"
|
|
32
|
-
|
|
33
|
-
[
|
|
26
|
+
path-slash = "0.2.1"
|
|
27
|
+
clap = { version = "4", features = ["derive", "env"] }
|
|
34
28
|
libc = "0.2"
|
|
35
29
|
|
|
36
|
-
|
|
30
|
+
# dev
|
|
31
|
+
tempfile = "3"
|
|
32
|
+
insta = "1"
|
|
33
|
+
serial_test = "3.4.0"
|
|
34
|
+
|
|
35
|
+
# internal
|
|
36
|
+
dlin-core = { version = "0.1.2", path = "crates/dlin-core" }
|
|
37
|
+
|
|
38
|
+
[workspace.lints.rust]
|
|
37
39
|
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tarpaulin_include)'] }
|
|
38
40
|
|
|
39
41
|
[profile.dist]
|
|
@@ -43,9 +45,3 @@ codegen-units = 1
|
|
|
43
45
|
strip = true
|
|
44
46
|
opt-level = "s"
|
|
45
47
|
panic = "abort"
|
|
46
|
-
|
|
47
|
-
[dev-dependencies]
|
|
48
|
-
tempfile = "3"
|
|
49
|
-
regex = "1"
|
|
50
|
-
insta = "1"
|
|
51
|
-
serial_test = "3.4.0"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dlin-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Classifier: Development Status :: 4 - Beta
|
|
5
5
|
Classifier: Environment :: Console
|
|
6
6
|
Classifier: Intended Audience :: Developers
|
|
@@ -24,6 +24,7 @@ Project-URL: Repository, https://github.com/eitsupi/dlin
|
|
|
24
24
|
|
|
25
25
|
[](https://crates.io/crates/dlin)
|
|
26
26
|
[](https://pypi.org/project/dlin-cli/)
|
|
27
|
+
[](https://deepwiki.com/eitsupi/dlin)
|
|
27
28
|
|
|
28
29
|
dbt lineage analysis CLI that parses SQL files directly. No `dbt compile`, no Python, no `manifest.json`.
|
|
29
30
|
|
|
@@ -291,7 +292,7 @@ dlin graph --node-type model,source # filter by node type
|
|
|
291
292
|
|
|
292
293
|
dlin aims to work without `dbt compile`. By default it parses SQL files directly, but it can also leverage a pre-compiled `manifest.json` for additional accuracy when one is available.
|
|
293
294
|
|
|
294
|
-
**SQL parsing (default)**: extracts `ref()` and `source()` from SQL via regex + Jinja template evaluation. No Python or dbt needed.
|
|
295
|
+
**SQL parsing (default)**: extracts `ref()` and `source()` from SQL via regex + Jinja template evaluation. No Python or dbt needed. Generic tests (`not_null`, `unique`, `relationships`, etc.) are inferred from YAML schema declarations.
|
|
295
296
|
|
|
296
297
|
**Manifest mode** (`--source manifest`): reads a pre-compiled `manifest.json` for full accuracy with complex Jinja logic.
|
|
297
298
|
|
|
@@ -300,6 +301,7 @@ dlin aims to work without `dbt compile`. By default it parses SQL files directly
|
|
|
300
301
|
- `var()` resolves from `dbt_project.yml` only (`--vars` CLI overrides not supported)
|
|
301
302
|
- Runtime context (`target.type`, `env_var()`) is not evaluated
|
|
302
303
|
- Conditional Jinja branches use default values; non-default paths may be missed
|
|
304
|
+
- Generic test IDs are dlin-specific (e.g. `test.not_null.orders.order_id`) and do not match dbt's naming; use manifest mode when exact test IDs matter
|
|
303
305
|
|
|
304
306
|
When these limitations matter, use `--source manifest`.
|
|
305
307
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://crates.io/crates/dlin)
|
|
4
4
|
[](https://pypi.org/project/dlin-cli/)
|
|
5
|
+
[](https://deepwiki.com/eitsupi/dlin)
|
|
5
6
|
|
|
6
7
|
dbt lineage analysis CLI that parses SQL files directly. No `dbt compile`, no Python, no `manifest.json`.
|
|
7
8
|
|
|
@@ -269,7 +270,7 @@ dlin graph --node-type model,source # filter by node type
|
|
|
269
270
|
|
|
270
271
|
dlin aims to work without `dbt compile`. By default it parses SQL files directly, but it can also leverage a pre-compiled `manifest.json` for additional accuracy when one is available.
|
|
271
272
|
|
|
272
|
-
**SQL parsing (default)**: extracts `ref()` and `source()` from SQL via regex + Jinja template evaluation. No Python or dbt needed.
|
|
273
|
+
**SQL parsing (default)**: extracts `ref()` and `source()` from SQL via regex + Jinja template evaluation. No Python or dbt needed. Generic tests (`not_null`, `unique`, `relationships`, etc.) are inferred from YAML schema declarations.
|
|
273
274
|
|
|
274
275
|
**Manifest mode** (`--source manifest`): reads a pre-compiled `manifest.json` for full accuracy with complex Jinja logic.
|
|
275
276
|
|
|
@@ -278,6 +279,7 @@ dlin aims to work without `dbt compile`. By default it parses SQL files directly
|
|
|
278
279
|
- `var()` resolves from `dbt_project.yml` only (`--vars` CLI overrides not supported)
|
|
279
280
|
- Runtime context (`target.type`, `env_var()`) is not evaluated
|
|
280
281
|
- Conditional Jinja branches use default values; non-default paths may be missed
|
|
282
|
+
- Generic test IDs are dlin-specific (e.g. `test.not_null.orders.order_id`) and do not match dbt's naming; use manifest mode when exact test IDs matter
|
|
281
283
|
|
|
282
284
|
When these limitations matter, use `--source manifest`.
|
|
283
285
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "dlin"
|
|
3
|
+
version.workspace = true
|
|
4
|
+
edition.workspace = true
|
|
5
|
+
license.workspace = true
|
|
6
|
+
repository.workspace = true
|
|
7
|
+
homepage.workspace = true
|
|
8
|
+
description = "A fast CLI tool for dbt model lineage analysis"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
keywords = ["dbt", "lineage", "dag", "sql", "cli"]
|
|
11
|
+
categories = ["command-line-utilities", "visualization"]
|
|
12
|
+
|
|
13
|
+
[[bin]]
|
|
14
|
+
name = "dlin"
|
|
15
|
+
path = "src/main.rs"
|
|
16
|
+
|
|
17
|
+
[dependencies]
|
|
18
|
+
dlin-core = { workspace = true, features = ["clap"] }
|
|
19
|
+
clap = { workspace = true }
|
|
20
|
+
anyhow = { workspace = true }
|
|
21
|
+
serde_json = { workspace = true }
|
|
22
|
+
path-slash = { workspace = true }
|
|
23
|
+
|
|
24
|
+
[target.'cfg(unix)'.dependencies]
|
|
25
|
+
libc = { workspace = true }
|
|
26
|
+
|
|
27
|
+
[dev-dependencies]
|
|
28
|
+
dlin-core = { workspace = true }
|
|
29
|
+
tempfile = { workspace = true }
|
|
30
|
+
regex = { workspace = true }
|
|
31
|
+
serde_json = { workspace = true }
|
|
32
|
+
serde-saphyr = { workspace = true }
|
|
33
|
+
|
|
34
|
+
[lints]
|
|
35
|
+
workspace = true
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
# dlin
|
|
2
|
+
|
|
3
|
+
[](https://crates.io/crates/dlin)
|
|
4
|
+
[](https://pypi.org/project/dlin-cli/)
|
|
5
|
+
[](https://deepwiki.com/eitsupi/dlin)
|
|
6
|
+
|
|
7
|
+
dbt lineage analysis CLI that parses SQL files directly. No `dbt compile`, no Python, no `manifest.json`.
|
|
8
|
+
|
|
9
|
+
Builds a dependency graph from `ref()` and `source()` calls in SQL. Designed for AI agents and CI pipelines.
|
|
10
|
+
|
|
11
|
+
## Motivation
|
|
12
|
+
|
|
13
|
+
When I edited dbt models in VS Code, [dbt Power User](https://marketplace.visualstudio.com/items?itemName=innoverio.vscode-dbt-power-user) was my go-to companion for navigating lineage. AI agents have no such companion. I watched them `grep` through dbt projects to find model dependencies. It works, but they end up calling `grep` repeatedly and relying on fragile string matching to piece together `ref()` and `source()` relationships.
|
|
14
|
+
|
|
15
|
+
dlin is designed to fill that gap: a CLI tool that lets AI agents understand a dbt project's structure without falling back to `grep`. It is equally useful for humans, and its stdin/stdout interface makes it easy to combine with `jq`, `git diff`, and other CLI tools.
|
|
16
|
+
|
|
17
|
+
To replace `grep`, speed and size matter. dlin is a small, self-contained binary with no runtime dependencies. It parses SQL directly, evaluates common Jinja patterns without Python, parallelizes file I/O, and caches aggressively.
|
|
18
|
+
|
|
19
|
+
The key idea behind dlin is that finding the right models fast is what matters most. AI agents can read SQL and trace column-level relationships on their own; the hard part is knowing which models to look at in the first place. So dlin focuses on model-level lineage and makes that as fast as possible.
|
|
20
|
+
|
|
21
|
+
## Install
|
|
22
|
+
|
|
23
|
+
### Cargo (Rust)
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
cargo install dlin
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### pip / uv (Python)
|
|
30
|
+
|
|
31
|
+
For convenience, dlin is also available as a Python package. The installed binary is native and does not require Python at runtime.
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
pip install dlin-cli # or: uv tool install dlin-cli
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### GitHub Releases
|
|
38
|
+
|
|
39
|
+
Pre-built binaries for Linux, macOS, and Windows are available on the [Releases](https://github.com/eitsupi/dlin/releases) page. You can also use the installer scripts:
|
|
40
|
+
|
|
41
|
+
macOS / Linux:
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/eitsupi/dlin/releases/latest/download/dlin-installer.sh | sh
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Windows (PowerShell):
|
|
48
|
+
|
|
49
|
+
```powershell
|
|
50
|
+
powershell -ExecutionPolicy Bypass -c "irm https://github.com/eitsupi/dlin/releases/latest/download/dlin-installer.ps1 | iex"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Quick start
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
# Full lineage graph
|
|
57
|
+
dlin graph -p path/to/dbt/project
|
|
58
|
+
|
|
59
|
+
# Downstream impact analysis
|
|
60
|
+
dlin impact orders
|
|
61
|
+
|
|
62
|
+
# List models as JSON
|
|
63
|
+
dlin list -o json --json-fields unique_id,file_path
|
|
64
|
+
|
|
65
|
+
# Pipe changed files into lineage
|
|
66
|
+
git diff --name-only main | dlin graph -o json
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## AI agent integration
|
|
70
|
+
|
|
71
|
+
No MCP server or tool configuration needed.
|
|
72
|
+
Just install dlin and add the following to your `AGENTS.md`, `CLAUDE.md`, or system prompt:
|
|
73
|
+
|
|
74
|
+
````md
|
|
75
|
+
## dbt project structure analysis
|
|
76
|
+
|
|
77
|
+
Use `dlin` to explore dbt model dependencies.
|
|
78
|
+
Do NOT grep/cat/find through SQL files.
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
dlin summary # Project overview (start here)
|
|
82
|
+
dlin graph <model> -u 2 -d 1 -q # Upstream/downstream lineage
|
|
83
|
+
dlin impact <model> # Downstream impact with severity
|
|
84
|
+
dlin list -o json --json-fields unique_id,sql_content # Read SQL content
|
|
85
|
+
git diff --name-only main | dlin graph -q # Lineage of changed files
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
For full option reference: `dlin --help`, `dlin graph --help`, etc.
|
|
89
|
+
````
|
|
90
|
+
|
|
91
|
+
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.
|
|
92
|
+
|
|
93
|
+
## Features
|
|
94
|
+
|
|
95
|
+
- **No dependencies**: single binary, no Python, no `manifest.json`
|
|
96
|
+
- **Recursive upstream / downstream**: `-u N` / `-d N` to control traversal depth
|
|
97
|
+
- **Impact analysis with severity**: `dlin impact` scores downstream nodes and flags exposure reachability
|
|
98
|
+
- **Composable**: stdin accepts model names or file paths; pipe with `jq`, `dlin list`, `git diff`, etc.
|
|
99
|
+
- **Agent-friendly**: `--error-format json` emits structured `{"level","what","why","hint"}` on stderr; `--help` is designed for tool discovery
|
|
100
|
+
|
|
101
|
+
## Mermaid diagrams
|
|
102
|
+
|
|
103
|
+
dlin outputs Mermaid flowcharts that render natively on GitHub, GitLab, Notion, and other Markdown environments.
|
|
104
|
+
|
|
105
|
+
### Simplified graphs with `--collapse`
|
|
106
|
+
|
|
107
|
+
Automatically remove intermediate nodes to see just the endpoints (nodes with no predecessors or no successors); everything in between becomes transitive "(via N)" edges:
|
|
108
|
+
|
|
109
|
+
```sh
|
|
110
|
+
# Collapse intermediate models — only endpoints remain
|
|
111
|
+
dlin graph --collapse -o mermaid
|
|
112
|
+
|
|
113
|
+
# Focal mode: keep only sources, exposures, and specified focus models
|
|
114
|
+
# (ignores BFS window pseudo-endpoints — ideal with -u/-d limits)
|
|
115
|
+
dlin graph orders --collapse=focal -u 3 -o mermaid
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
```mermaid
|
|
119
|
+
flowchart LR
|
|
120
|
+
exposure_weekly_report>"weekly_report"]
|
|
121
|
+
model_combined_orders["combined_orders"]
|
|
122
|
+
model_order_summary["order_summary"]
|
|
123
|
+
source_raw_customers(["raw.customers"])
|
|
124
|
+
source_raw_orders(["raw.orders"])
|
|
125
|
+
source_raw_payments(["raw.payments"])
|
|
126
|
+
|
|
127
|
+
source_raw_customers ==>|"exposure (via 2)"| exposure_weekly_report
|
|
128
|
+
source_raw_orders ==>|"exposure (via 3)"| exposure_weekly_report
|
|
129
|
+
source_raw_orders -.->|"source (via 1)"| model_combined_orders
|
|
130
|
+
source_raw_orders -.->|"source (via 1)"| model_order_summary
|
|
131
|
+
source_raw_payments ==>|"exposure (via 3)"| exposure_weekly_report
|
|
132
|
+
source_raw_payments -.->|"source (via 1)"| model_order_summary
|
|
133
|
+
|
|
134
|
+
classDef model fill:#4A90D9,stroke:#333,color:#fff
|
|
135
|
+
classDef source fill:#27AE60,stroke:#333,color:#fff
|
|
136
|
+
classDef exposure fill:#E74C3C,stroke:#333,color:#fff
|
|
137
|
+
class exposure_weekly_report exposure
|
|
138
|
+
class model_combined_orders model
|
|
139
|
+
class model_order_summary model
|
|
140
|
+
class source_raw_customers source
|
|
141
|
+
class source_raw_orders source
|
|
142
|
+
class source_raw_payments source
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Positional focus models are always preserved during collapse, so `dlin graph orders --collapse` keeps `orders` even if it would otherwise be intermediate.
|
|
146
|
+
|
|
147
|
+
### Pipe to build focused diagrams
|
|
148
|
+
|
|
149
|
+
Combine `dlin list`, `jq`, and `dlin graph` to extract exactly the nodes you want:
|
|
150
|
+
|
|
151
|
+
```sh
|
|
152
|
+
# Staging models → 1 hop downstream, models only, grouped by directory
|
|
153
|
+
dlin list -s 'path:models/staging' -o json | jq -r '.[].label' |
|
|
154
|
+
dlin graph -d 1 --node-type model --group-by directory -o mermaid
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
```mermaid
|
|
158
|
+
flowchart LR
|
|
159
|
+
subgraph models_marts["models/marts"]
|
|
160
|
+
model_combined_orders["combined_orders"]
|
|
161
|
+
model_customers["customers"]
|
|
162
|
+
model_order_summary["order_summary"]
|
|
163
|
+
model_orders["orders"]
|
|
164
|
+
end
|
|
165
|
+
subgraph models_staging["models/staging"]
|
|
166
|
+
model_stg_customers["stg_customers"]
|
|
167
|
+
model_stg_online_orders["stg_online_orders"]
|
|
168
|
+
model_stg_orders["stg_orders"]
|
|
169
|
+
model_stg_payments["stg_payments"]
|
|
170
|
+
model_stg_retail_orders["stg_retail_orders"]
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
model_orders -->|ref| model_customers
|
|
174
|
+
model_stg_customers -->|ref| model_customers
|
|
175
|
+
model_stg_online_orders -->|ref| model_combined_orders
|
|
176
|
+
model_stg_orders -->|ref| model_order_summary
|
|
177
|
+
model_stg_orders -->|ref| model_orders
|
|
178
|
+
model_stg_payments -->|ref| model_order_summary
|
|
179
|
+
model_stg_payments -->|ref| model_orders
|
|
180
|
+
model_stg_retail_orders -->|ref| model_combined_orders
|
|
181
|
+
|
|
182
|
+
classDef model fill:#4A90D9,stroke:#333,color:#fff
|
|
183
|
+
class model_combined_orders model
|
|
184
|
+
class model_customers model
|
|
185
|
+
class model_order_summary model
|
|
186
|
+
class model_orders model
|
|
187
|
+
class model_stg_customers model
|
|
188
|
+
class model_stg_online_orders model
|
|
189
|
+
class model_stg_orders model
|
|
190
|
+
class model_stg_payments model
|
|
191
|
+
class model_stg_retail_orders model
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Column names in nodes with `--show-columns`
|
|
195
|
+
|
|
196
|
+
Add `--show-columns` to include column names inside Mermaid node labels — useful for understanding what each model produces at a glance:
|
|
197
|
+
|
|
198
|
+
```sh
|
|
199
|
+
dlin graph orders -u 1 -d 0 --show-columns --node-type model,source -o mermaid
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
```mermaid
|
|
203
|
+
flowchart LR
|
|
204
|
+
model_orders["orders<br/>---<br/>order_id, customer_id, order_date, status, total_amount, payment_method"]
|
|
205
|
+
model_stg_orders["stg_orders<br/>---<br/>order_id, customer_id, order_date, status"]
|
|
206
|
+
model_stg_payments["stg_payments<br/>---<br/>payment_id, order_id, amount, payment_method"]
|
|
207
|
+
|
|
208
|
+
model_stg_orders -->|ref| model_orders
|
|
209
|
+
model_stg_payments -->|ref| model_orders
|
|
210
|
+
|
|
211
|
+
classDef model fill:#4A90D9,stroke:#333,color:#fff
|
|
212
|
+
class model_orders model
|
|
213
|
+
class model_stg_orders model
|
|
214
|
+
class model_stg_payments model
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Combines well with `--collapse` to show rich detail on fewer endpoint nodes.
|
|
218
|
+
|
|
219
|
+
### Other graph options
|
|
220
|
+
|
|
221
|
+
```sh
|
|
222
|
+
dlin graph orders -u 2 -d 1 # focus on specific model
|
|
223
|
+
dlin graph -o mermaid --collapse --show-columns # columns in collapsed nodes
|
|
224
|
+
dlin graph orders --collapse=focal -u 3 -o mermaid # focal: sources + exposures + orders
|
|
225
|
+
dlin graph -o mermaid --group-by directory # group by directory
|
|
226
|
+
dlin graph -o mermaid --direction tb # top-to-bottom layout
|
|
227
|
+
dlin graph --node-type source,exposure # filter by node type
|
|
228
|
+
dlin graph -o dot | dot -Tsvg > out.svg # Graphviz rendering
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Output formats: ASCII (default), JSON, Mermaid, Graphviz DOT, Plain, SVG, HTML.
|
|
232
|
+
|
|
233
|
+
## Key subcommands
|
|
234
|
+
|
|
235
|
+
### `list`
|
|
236
|
+
|
|
237
|
+
```sh
|
|
238
|
+
dlin list # all models and sources
|
|
239
|
+
dlin list orders -o json --json-fields unique_id,file_path # specific model as JSON
|
|
240
|
+
dlin list --node-type source # sources only
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### `impact`
|
|
244
|
+
|
|
245
|
+
```sh
|
|
246
|
+
$ dlin impact orders
|
|
247
|
+
Impact Analysis: orders
|
|
248
|
+
==================================================
|
|
249
|
+
Overall Severity: CRITICAL
|
|
250
|
+
|
|
251
|
+
Summary:
|
|
252
|
+
Affected models: 1
|
|
253
|
+
Affected tests: 1
|
|
254
|
+
Affected exposures: 1
|
|
255
|
+
|
|
256
|
+
Impacted Nodes:
|
|
257
|
+
[critical] weekly_report (exposure, distance: 1)
|
|
258
|
+
[high ] customers (model, distance: 1) [models/marts/customers.sql]
|
|
259
|
+
[low ] assert_orders_positive_amount (test, distance: 1)
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## Filtering
|
|
263
|
+
|
|
264
|
+
```sh
|
|
265
|
+
dlin graph -s tag:finance,path:marts # selector expressions (union)
|
|
266
|
+
dlin graph --node-type model,source # filter by node type
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## Data sources
|
|
270
|
+
|
|
271
|
+
dlin aims to work without `dbt compile`. By default it parses SQL files directly, but it can also leverage a pre-compiled `manifest.json` for additional accuracy when one is available.
|
|
272
|
+
|
|
273
|
+
**SQL parsing (default)**: extracts `ref()` and `source()` from SQL via regex + Jinja template evaluation. No Python or dbt needed. Generic tests (`not_null`, `unique`, `relationships`, etc.) are inferred from YAML schema declarations.
|
|
274
|
+
|
|
275
|
+
**Manifest mode** (`--source manifest`): reads a pre-compiled `manifest.json` for full accuracy with complex Jinja logic.
|
|
276
|
+
|
|
277
|
+
### Limitations of SQL parse mode
|
|
278
|
+
|
|
279
|
+
- `var()` resolves from `dbt_project.yml` only (`--vars` CLI overrides not supported)
|
|
280
|
+
- Runtime context (`target.type`, `env_var()`) is not evaluated
|
|
281
|
+
- Conditional Jinja branches use default values; non-default paths may be missed
|
|
282
|
+
- Generic test IDs are dlin-specific (e.g. `test.not_null.orders.order_id`) and do not match dbt's naming; use manifest mode when exact test IDs matter
|
|
283
|
+
|
|
284
|
+
When these limitations matter, use `--source manifest`.
|
|
285
|
+
|
|
286
|
+
## Credits
|
|
287
|
+
|
|
288
|
+
Hard fork of [dbt-lineage-viewer](https://github.com/sipemu/dbt-lineage-viewer) by Simon Muller (MIT license). The original focused on TUI-based exploration; dlin removes the TUI and targets non-interactive use: scripting, CI, and AI agents.
|
|
289
|
+
|
|
290
|
+
## License
|
|
291
|
+
|
|
292
|
+
MIT
|