dlin-cli 0.2.1rc1__tar.gz → 0.2.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.2.1rc1 → dlin_cli-0.2.2}/Cargo.lock +9 -8
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/Cargo.toml +4 -4
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/PKG-INFO +60 -32
- {dlin_cli-0.2.1rc1/crates/dlin → dlin_cli-0.2.2}/README.md +59 -31
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin/Cargo.toml +1 -0
- {dlin_cli-0.2.1rc1/crates/dlin-core → dlin_cli-0.2.2/crates/dlin}/README.md +59 -31
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin/src/cli.rs +51 -6
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin/src/main.rs +47 -5
- dlin_cli-0.2.2/crates/dlin/src/mcp.rs +1374 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin/tests/integration_test.rs +245 -1
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2/crates/dlin-core}/README.md +59 -31
- dlin_cli-0.2.2/crates/dlin-core/src/graph/builder/mod.rs +1254 -0
- dlin_cli-0.2.2/crates/dlin-core/src/graph/builder/tests/build_graph.rs +1077 -0
- dlin_cli-0.2.2/crates/dlin-core/src/graph/builder/tests/generic_tests.rs +184 -0
- dlin_cli-0.2.2/crates/dlin-core/src/graph/builder/tests/mod.rs +49 -0
- dlin_cli-0.2.2/crates/dlin-core/src/graph/builder/tests/ref_parsing.rs +97 -0
- dlin_cli-0.2.2/crates/dlin-core/src/graph/builder/tests/versioned.rs +589 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/graph/column_lineage/single_model.rs +3 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/graph/column_lineage/tests/core.rs +62 -0
- dlin_cli-0.2.2/crates/dlin-core/src/graph/filter/mod.rs +598 -0
- dlin_cli-0.2.2/crates/dlin-core/src/graph/filter/tests/collapse.rs +721 -0
- dlin_cli-0.2.2/crates/dlin-core/src/graph/filter/tests/filter_graph.rs +190 -0
- dlin_cli-0.2.2/crates/dlin-core/src/graph/filter/tests/mod.rs +188 -0
- dlin_cli-0.2.2/crates/dlin-core/src/graph/filter/tests/output.rs +161 -0
- dlin_cli-0.2.2/crates/dlin-core/src/graph/filter/tests/search.rs +95 -0
- dlin_cli-0.2.2/crates/dlin-core/src/graph/filter/tests/selector.rs +323 -0
- dlin_cli-0.2.1rc1/crates/dlin-core/src/graph/snapshots/dlin_core__graph__filter__tests__collapse_snapshot.snap → dlin_cli-0.2.2/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot.snap +2 -1
- dlin_cli-0.2.1rc1/crates/dlin-core/src/graph/snapshots/dlin_core__graph__filter__tests__collapse_snapshot_bfs_pseudoendpoint.snap → dlin_cli-0.2.2/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot_bfs_pseudoendpoint.snap +2 -1
- dlin_cli-0.2.1rc1/crates/dlin-core/src/graph/snapshots/dlin_core__graph__filter__tests__collapse_snapshot_endpoints_fan_out.snap → dlin_cli-0.2.2/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot_endpoints_fan_out.snap +2 -1
- dlin_cli-0.2.1rc1/crates/dlin-core/src/graph/snapshots/dlin_core__graph__filter__tests__collapse_snapshot_endpoints_leaf_model.snap → dlin_cli-0.2.2/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot_endpoints_leaf_model.snap +2 -1
- dlin_cli-0.2.1rc1/crates/dlin-core/src/graph/snapshots/dlin_core__graph__filter__tests__collapse_snapshot_multiple_focus_models.snap → dlin_cli-0.2.2/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot_multiple_focus_models.snap +2 -1
- dlin_cli-0.2.1rc1/crates/dlin-core/src/graph/snapshots/dlin_core__graph__filter__tests__collapse_snapshot_no_source_exposure.snap → dlin_cli-0.2.2/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot_no_source_exposure.snap +2 -1
- dlin_cli-0.2.1rc1/crates/dlin-core/src/graph/snapshots/dlin_core__graph__filter__tests__collapse_snapshot_preserve_focus.snap → dlin_cli-0.2.2/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__collapse_snapshot_preserve_focus.snap +2 -1
- dlin_cli-0.2.1rc1/crates/dlin-core/src/graph/snapshots/dlin_core__graph__filter__tests__snapshot_transitive_node_type_filter.snap → dlin_cli-0.2.2/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__snapshot_transitive_node_type_filter.snap +2 -1
- dlin_cli-0.2.1rc1/crates/dlin-core/src/graph/snapshots/dlin_core__graph__filter__tests__snapshot_transitive_select_filter.snap → dlin_cli-0.2.2/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__snapshot_transitive_select_filter.snap +2 -1
- dlin_cli-0.2.1rc1/crates/dlin-core/src/graph/snapshots/dlin_core__graph__filter__tests__snapshot_transitive_select_with_node_type.snap → dlin_cli-0.2.2/crates/dlin-core/src/graph/filter/tests/snapshots/dlin_core__graph__filter__tests__collapse__snapshot_transitive_select_with_node_type.snap +2 -1
- dlin_cli-0.2.2/crates/dlin-core/src/graph/filter/tests/transitive.rs +177 -0
- dlin_cli-0.2.2/crates/dlin-core/src/graph/filter/tests/versioned.rs +128 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/graph/impact.rs +1 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/graph/types.rs +16 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/input.rs +49 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/parser/cache.rs +2 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/parser/jinja.rs +105 -8
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/parser/manifest.rs +377 -4
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/parser/sql.rs +195 -5
- dlin_cli-0.2.2/crates/dlin-core/src/parser/yaml_schema.rs +982 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/ascii.rs +23 -2
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/column_graph.rs +1 -16
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/dot.rs +54 -5
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/html.rs +1 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/json.rs +10 -1
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/list.rs +1 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/mermaid.rs +6 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/mod.rs +50 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__summary__tests__snapshot_summary_json.snap +4 -1
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/summary.rs +28 -1
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/svg.rs +77 -14
- dlin_cli-0.2.1rc1/crates/dlin-core/src/graph/builder.rs +0 -1614
- dlin_cli-0.2.1rc1/crates/dlin-core/src/graph/filter.rs +0 -2396
- dlin_cli-0.2.1rc1/crates/dlin-core/src/parser/yaml_schema.rs +0 -350
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/LICENSE +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/Cargo.toml +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/error.rs +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/graph/column_lineage/cache.rs +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/graph/column_lineage/cross_model.rs +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/graph/column_lineage/impact.rs +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/graph/column_lineage/mod.rs +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/graph/column_lineage/schema.rs +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/graph/column_lineage/tests/cache.rs +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/graph/column_lineage/tests/impact.rs +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/graph/column_lineage/tests/mod.rs +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/graph/column_lineage/types.rs +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/graph/mod.rs +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/lib.rs +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/parser/columns.rs +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/parser/discovery.rs +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/parser/manifest_cache.rs +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/parser/mod.rs +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/parser/project.rs +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/impact.rs +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/layout.rs +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/plain.rs +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_all_transformation_types.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_escapes_special_chars.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_id_collision_avoided.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_impact_indirect.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_impact_single.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_single_model.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__dot_via_path.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__impact_mermaid.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__impact_mermaid_indirect_edge_label.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__impact_plain.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__impact_plain_multi_hop.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__impact_plain_non_direct_intermediate.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__mermaid_dotted_table_name.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__mermaid_id_collision_avoided.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__mermaid_label_escaping.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__mermaid_single_model.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__plain_model_path_non_direct_annotation.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__plain_no_sources.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__column_graph__tests__plain_single_model.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__group_by_node_type.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_all_edge_types.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_direction_tb.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_direction_tb_grouped.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_group_by_directory.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_lineage.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__dot__tests__snapshot_transitive_edges.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__html__tests__snapshot_html_json.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__impact__tests__snapshot_impact_json.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__impact__tests__snapshot_impact_json_with_sql.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__impact__tests__snapshot_impact_text.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__impact__tests__snapshot_impact_text_with_sql.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__json__tests__snapshot_json_with_sql.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__json__tests__snapshot_lineage.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__json__tests__snapshot_node_metadata.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__list__tests__snapshot_list_json.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__list__tests__snapshot_list_plain.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__group_by_node_type.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__mixed_direct_and_transitive_edges.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_escapes_quotes.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_lineage.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_single_model.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_with_collapse.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__show_columns_with_grouping.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__snapshot_direction_tb.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__snapshot_direction_tb_grouped.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__snapshot_group_by_directory.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__snapshot_lineage.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__mermaid__tests__transitive_edge_rendering.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__plain__tests__snapshot_plain.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/src/render/snapshots/dlin_core__render__summary__tests__snapshot_summary_text.snap +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/crates/dlin-core/tests/column_lineage_test.rs +0 -0
- {dlin_cli-0.2.1rc1 → dlin_cli-0.2.2}/pyproject.toml +0 -0
|
@@ -230,7 +230,7 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
|
|
230
230
|
|
|
231
231
|
[[package]]
|
|
232
232
|
name = "dlin"
|
|
233
|
-
version = "0.2.
|
|
233
|
+
version = "0.2.2"
|
|
234
234
|
dependencies = [
|
|
235
235
|
"anyhow",
|
|
236
236
|
"clap",
|
|
@@ -239,6 +239,7 @@ dependencies = [
|
|
|
239
239
|
"path-slash",
|
|
240
240
|
"polyglot-sql",
|
|
241
241
|
"regex",
|
|
242
|
+
"serde",
|
|
242
243
|
"serde-saphyr",
|
|
243
244
|
"serde_json",
|
|
244
245
|
"tempfile",
|
|
@@ -246,7 +247,7 @@ dependencies = [
|
|
|
246
247
|
|
|
247
248
|
[[package]]
|
|
248
249
|
name = "dlin-core"
|
|
249
|
-
version = "0.2.
|
|
250
|
+
version = "0.2.2"
|
|
250
251
|
dependencies = [
|
|
251
252
|
"anyhow",
|
|
252
253
|
"clap",
|
|
@@ -397,9 +398,9 @@ dependencies = [
|
|
|
397
398
|
|
|
398
399
|
[[package]]
|
|
399
400
|
name = "granit-parser"
|
|
400
|
-
version = "0.0.
|
|
401
|
+
version = "0.0.3"
|
|
401
402
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
402
|
-
checksum = "
|
|
403
|
+
checksum = "f50ba32164f9e098d5da618776a32afbb32270adcbe3d3d006107dae11e37c91"
|
|
403
404
|
dependencies = [
|
|
404
405
|
"arraydeque",
|
|
405
406
|
"smallvec",
|
|
@@ -596,9 +597,9 @@ checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
|
|
596
597
|
|
|
597
598
|
[[package]]
|
|
598
599
|
name = "polyglot-sql"
|
|
599
|
-
version = "0.4.
|
|
600
|
+
version = "0.4.4"
|
|
600
601
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
601
|
-
checksum = "
|
|
602
|
+
checksum = "b0d5ea9283f03d3b6c32a230e60e7c6bc854e5bec83c399c75cad02bf46e9622"
|
|
602
603
|
dependencies = [
|
|
603
604
|
"serde",
|
|
604
605
|
"serde_json",
|
|
@@ -749,9 +750,9 @@ dependencies = [
|
|
|
749
750
|
|
|
750
751
|
[[package]]
|
|
751
752
|
name = "serde-saphyr"
|
|
752
|
-
version = "0.0.
|
|
753
|
+
version = "0.0.27"
|
|
753
754
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
754
|
-
checksum = "
|
|
755
|
+
checksum = "5897b4c3faadadd35fdb6689f015641f3bc481d5adaaac56231ea15aeb243db3"
|
|
755
756
|
dependencies = [
|
|
756
757
|
"ahash",
|
|
757
758
|
"annotate-snippets",
|
|
@@ -3,7 +3,7 @@ members = ["crates/*"]
|
|
|
3
3
|
resolver = "3"
|
|
4
4
|
|
|
5
5
|
[workspace.package]
|
|
6
|
-
version = "0.2.
|
|
6
|
+
version = "0.2.2"
|
|
7
7
|
edition = "2024"
|
|
8
8
|
license = "MIT"
|
|
9
9
|
repository = "https://github.com/eitsupi/dlin"
|
|
@@ -13,7 +13,7 @@ homepage = "https://github.com/eitsupi/dlin"
|
|
|
13
13
|
petgraph = { version = "0.8", features = ["serde-1"] }
|
|
14
14
|
serde = { version = "1", features = ["derive"] }
|
|
15
15
|
serde_json = "1"
|
|
16
|
-
serde-saphyr = "0.0.
|
|
16
|
+
serde-saphyr = "0.0.27"
|
|
17
17
|
regex = "1"
|
|
18
18
|
walkdir = "2"
|
|
19
19
|
colored = "3"
|
|
@@ -23,7 +23,7 @@ indexmap = "2"
|
|
|
23
23
|
minijinja = "2"
|
|
24
24
|
rayon = "1"
|
|
25
25
|
globset = "0.4"
|
|
26
|
-
polyglot-sql = { version = "0.4.
|
|
26
|
+
polyglot-sql = { version = "0.4.4", default-features = false, features = ["all-dialects", "semantic"] }
|
|
27
27
|
path-slash = "0.2.1"
|
|
28
28
|
clap = { version = "4", features = ["derive", "env"] }
|
|
29
29
|
libc = "0.2"
|
|
@@ -34,7 +34,7 @@ insta = "1"
|
|
|
34
34
|
serial_test = "3.4.0"
|
|
35
35
|
|
|
36
36
|
# internal
|
|
37
|
-
dlin-core = { version = "0.2.
|
|
37
|
+
dlin-core = { version = "0.2.2", path = "crates/dlin-core" }
|
|
38
38
|
|
|
39
39
|
[workspace.lints.rust]
|
|
40
40
|
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tarpaulin_include)'] }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dlin-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Classifier: Development Status :: 4 - Beta
|
|
5
5
|
Classifier: Environment :: Console
|
|
6
6
|
Classifier: Intended Audience :: Developers
|
|
@@ -26,11 +26,11 @@ Project-URL: Repository, https://github.com/eitsupi/dlin
|
|
|
26
26
|
[](https://pypi.org/project/dlin-cli/)
|
|
27
27
|
[](https://deepwiki.com/eitsupi/dlin)
|
|
28
28
|
|
|
29
|
-
dbt model lineage CLI
|
|
29
|
+
dbt model lineage CLI. Parses SQL files directly or reads a compiled `manifest.json`. No Python required.
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
Works for developers navigating live SQL files, analysts exploring a shared manifest, AI agents via CLI prompt or MCP server, and CI pipelines.
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
Column-level lineage (`dlin column upstream` / `dlin column downstream`) is also available. It requires `manifest.json`.
|
|
34
34
|
|
|
35
35
|
## Motivation
|
|
36
36
|
|
|
@@ -90,10 +90,41 @@ dlin list -o json --json-fields unique_id,file_path
|
|
|
90
90
|
git diff --name-only main | dlin graph -o json
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
+
## Source modes
|
|
94
|
+
|
|
95
|
+
dlin supports two source modes for model-level commands.
|
|
96
|
+
|
|
97
|
+
**SQL parse mode (default)** is for developers working with a live dbt project. dlin reads `ref()` and `source()` calls directly from SQL files without running `dbt compile`. It works immediately as you edit models, with no compilation step needed.
|
|
98
|
+
|
|
99
|
+
**Manifest mode** (`--source manifest`) is for analysts or agents who have access only to a compiled `manifest.json`. A developer runs `dbt compile` once and distributes the result; anyone with that file can then explore the full project structure with dlin without needing SQL files or a Python environment.
|
|
100
|
+
|
|
101
|
+
```sh
|
|
102
|
+
# SQL parse mode: reads SQL files directly (default)
|
|
103
|
+
dlin graph orders
|
|
104
|
+
|
|
105
|
+
# Manifest mode: reads manifest.json only
|
|
106
|
+
dlin graph orders --source manifest
|
|
107
|
+
dlin summary --source manifest
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
For model-name inputs, `manifest.json` is the only file needed in manifest mode. File-path inputs (e.g. `models/foo.sql`) fall back to standard dbt directory layout when `dbt_project.yml` is absent, which may not match projects with custom path configuration. (`check-manifest` always requires a full project.)
|
|
111
|
+
|
|
112
|
+
### Limitations of SQL parse mode
|
|
113
|
+
|
|
114
|
+
- `var()` resolves from `dbt_project.yml` only (`--vars` CLI overrides not supported)
|
|
115
|
+
- Runtime context (`target.type`, `env_var()`) is not evaluated
|
|
116
|
+
- Conditional Jinja branches use default values; non-default paths may be missed
|
|
117
|
+
- 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
|
|
118
|
+
|
|
119
|
+
When these limitations matter, use `--source manifest`.
|
|
120
|
+
|
|
93
121
|
## AI agent integration
|
|
94
122
|
|
|
95
|
-
|
|
96
|
-
|
|
123
|
+
### CLI approach
|
|
124
|
+
|
|
125
|
+
Recommended for developers with access to a live dbt project. Works with SQL parse mode (no `dbt compile` needed) as well as manifest mode.
|
|
126
|
+
|
|
127
|
+
Install dlin and add the following to your `AGENTS.md`, `CLAUDE.md`, or system prompt:
|
|
97
128
|
|
|
98
129
|
````md
|
|
99
130
|
## dbt project structure analysis
|
|
@@ -112,16 +143,32 @@ git diff --name-only main | dlin graph -q # Lineage of changed file
|
|
|
112
143
|
For full option reference: `dlin --help`, `dlin graph --help`, etc.
|
|
113
144
|
````
|
|
114
145
|
|
|
115
|
-
The key line is **"Do NOT grep/cat/find through SQL files"
|
|
146
|
+
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.
|
|
147
|
+
|
|
148
|
+
### MCP server (experimental)
|
|
149
|
+
|
|
150
|
+
For analysts and agents who work from a distributed `manifest.json` without access to the full project. Runs in manifest mode only.
|
|
151
|
+
|
|
152
|
+
`dlin mcp` exposes a stdio MCP server that AI assistants supporting MCP can connect to directly.
|
|
153
|
+
|
|
154
|
+
```sh
|
|
155
|
+
dlin mcp --dialect bigquery path/to/manifest.json
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Available MCP tools: project summary, model search, lineage, impact analysis, and column-level lineage.
|
|
159
|
+
|
|
160
|
+
Pass `--dialect` to match your project's SQL dialect for accurate column lineage. Requires a compiled `manifest.json` (`dbt compile`).
|
|
116
161
|
|
|
117
162
|
## Features
|
|
118
163
|
|
|
119
|
-
- **
|
|
164
|
+
- **SQL parse mode**: single binary, no Python, no `manifest.json` needed for model-level lineage
|
|
165
|
+
- **Manifest mode**: works from `manifest.json` alone; useful for analysts or agents without a full project checkout
|
|
166
|
+
- **MCP server** (experimental): `dlin mcp` serves lineage data via stdio MCP for direct AI assistant integration
|
|
120
167
|
- **Recursive upstream / downstream**: `-u N` / `-d N` to control traversal depth
|
|
121
168
|
- **Impact analysis with severity**: `dlin impact` scores downstream nodes and flags exposure reachability
|
|
122
169
|
- **Composable**: stdin accepts model names or file paths; pipe with `jq`, `dlin list`, `git diff`, etc.
|
|
123
170
|
- **Agent-friendly**: `--error-format json` emits structured `{"level","what","why","hint"}` on stderr; `--help` is designed for tool discovery
|
|
124
|
-
- **Column-level lineage** (experimental): traces columns across models with transformation classification; requires `
|
|
171
|
+
- **Column-level lineage** (experimental): traces columns across models with transformation classification; requires `manifest.json`
|
|
125
172
|
|
|
126
173
|
## Mermaid diagrams
|
|
127
174
|
|
|
@@ -132,11 +179,11 @@ dlin outputs Mermaid flowcharts that render natively on GitHub, GitLab, Notion,
|
|
|
132
179
|
Automatically remove intermediate nodes to see just the endpoints (nodes with no predecessors or no successors); everything in between becomes transitive "(via N)" edges:
|
|
133
180
|
|
|
134
181
|
```sh
|
|
135
|
-
# Collapse intermediate models
|
|
182
|
+
# Collapse intermediate models; only endpoints remain
|
|
136
183
|
dlin graph --collapse -o mermaid
|
|
137
184
|
|
|
138
185
|
# Focal mode: keep only sources, exposures, and specified focus models
|
|
139
|
-
# (ignores BFS window pseudo-endpoints
|
|
186
|
+
# (ignores BFS window pseudo-endpoints; works best with -u/-d limits)
|
|
140
187
|
dlin graph orders --collapse=focal -u 3 -o mermaid
|
|
141
188
|
```
|
|
142
189
|
|
|
@@ -218,7 +265,7 @@ flowchart LR
|
|
|
218
265
|
|
|
219
266
|
### Column names in nodes with `--show-columns`
|
|
220
267
|
|
|
221
|
-
Add `--show-columns` to include column names inside Mermaid node labels
|
|
268
|
+
Add `--show-columns` to include column names inside Mermaid node labels, useful for understanding what each model produces at a glance:
|
|
222
269
|
|
|
223
270
|
```sh
|
|
224
271
|
dlin graph orders -u 1 -d 0 --show-columns --node-type model,source -o mermaid
|
|
@@ -343,7 +390,7 @@ flowchart LR
|
|
|
343
390
|
n1_0 -->|"aggregation"|n0_5
|
|
344
391
|
```
|
|
345
392
|
|
|
346
|
-
`customer_id`, `email`, etc. pass through `stg_customers` unchanged from `raw.customers` (all `direct`). `lifetime_value` and `order_count` are aggregated at the `customers` model
|
|
393
|
+
`customer_id`, `email`, etc. pass through `stg_customers` unchanged from `raw.customers` (all `direct`). `lifetime_value` and `order_count` are aggregated at the `customers` model. The final edge to `customers` is labeled `aggregation`, while all upstream hops carry their actual transformation type (here `direct`, since staging and mart models pass columns through unchanged).
|
|
347
394
|
|
|
348
395
|
Transformation types shown on edges: `direct`, `aggregation`, `expression`, `cast`, `conditional`, `unknown`.
|
|
349
396
|
|
|
@@ -420,25 +467,6 @@ dlin graph -s tag:finance,path:marts # selector expressions (union)
|
|
|
420
467
|
dlin graph --node-type model,source # filter by node type
|
|
421
468
|
```
|
|
422
469
|
|
|
423
|
-
## Data sources
|
|
424
|
-
|
|
425
|
-
dlin aims to work without `dbt compile` (except for column-level lineage, which always requires `manifest.json`). By default it parses SQL files directly, but it can also leverage a pre-compiled `manifest.json` for additional accuracy when one is available.
|
|
426
|
-
|
|
427
|
-
**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.
|
|
428
|
-
|
|
429
|
-
**Manifest mode** (`--source manifest`): reads a pre-compiled `manifest.json` for full accuracy with complex Jinja logic.
|
|
430
|
-
|
|
431
|
-
For graph, list, impact, summary, and column commands, manifest mode requires only `manifest.json`; SQL files are not needed. When inputs are model names (not file paths), `dbt_project.yml` is also not needed; file-path inputs (e.g. `models/foo.sql`) fall back to standard dbt directory layout when `dbt_project.yml` is absent, which may not match projects with custom path configuration. A developer can run `dbt compile` once and distribute the resulting `manifest.json` to analysts or AI agents who then query it with dlin without access to the full project. (`check-manifest` always requires a full project.)
|
|
432
|
-
|
|
433
|
-
### Limitations of SQL parse mode
|
|
434
|
-
|
|
435
|
-
- `var()` resolves from `dbt_project.yml` only (`--vars` CLI overrides not supported)
|
|
436
|
-
- Runtime context (`target.type`, `env_var()`) is not evaluated
|
|
437
|
-
- Conditional Jinja branches use default values; non-default paths may be missed
|
|
438
|
-
- 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
|
|
439
|
-
|
|
440
|
-
When these limitations matter, use `--source manifest`.
|
|
441
|
-
|
|
442
470
|
## Credits
|
|
443
471
|
|
|
444
472
|
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.
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
[](https://pypi.org/project/dlin-cli/)
|
|
5
5
|
[](https://deepwiki.com/eitsupi/dlin)
|
|
6
6
|
|
|
7
|
-
dbt model lineage CLI
|
|
7
|
+
dbt model lineage CLI. Parses SQL files directly or reads a compiled `manifest.json`. No Python required.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Works for developers navigating live SQL files, analysts exploring a shared manifest, AI agents via CLI prompt or MCP server, and CI pipelines.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Column-level lineage (`dlin column upstream` / `dlin column downstream`) is also available. It requires `manifest.json`.
|
|
12
12
|
|
|
13
13
|
## Motivation
|
|
14
14
|
|
|
@@ -68,10 +68,41 @@ dlin list -o json --json-fields unique_id,file_path
|
|
|
68
68
|
git diff --name-only main | dlin graph -o json
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
+
## Source modes
|
|
72
|
+
|
|
73
|
+
dlin supports two source modes for model-level commands.
|
|
74
|
+
|
|
75
|
+
**SQL parse mode (default)** is for developers working with a live dbt project. dlin reads `ref()` and `source()` calls directly from SQL files without running `dbt compile`. It works immediately as you edit models, with no compilation step needed.
|
|
76
|
+
|
|
77
|
+
**Manifest mode** (`--source manifest`) is for analysts or agents who have access only to a compiled `manifest.json`. A developer runs `dbt compile` once and distributes the result; anyone with that file can then explore the full project structure with dlin without needing SQL files or a Python environment.
|
|
78
|
+
|
|
79
|
+
```sh
|
|
80
|
+
# SQL parse mode: reads SQL files directly (default)
|
|
81
|
+
dlin graph orders
|
|
82
|
+
|
|
83
|
+
# Manifest mode: reads manifest.json only
|
|
84
|
+
dlin graph orders --source manifest
|
|
85
|
+
dlin summary --source manifest
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
For model-name inputs, `manifest.json` is the only file needed in manifest mode. File-path inputs (e.g. `models/foo.sql`) fall back to standard dbt directory layout when `dbt_project.yml` is absent, which may not match projects with custom path configuration. (`check-manifest` always requires a full project.)
|
|
89
|
+
|
|
90
|
+
### Limitations of SQL parse mode
|
|
91
|
+
|
|
92
|
+
- `var()` resolves from `dbt_project.yml` only (`--vars` CLI overrides not supported)
|
|
93
|
+
- Runtime context (`target.type`, `env_var()`) is not evaluated
|
|
94
|
+
- Conditional Jinja branches use default values; non-default paths may be missed
|
|
95
|
+
- 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
|
|
96
|
+
|
|
97
|
+
When these limitations matter, use `--source manifest`.
|
|
98
|
+
|
|
71
99
|
## AI agent integration
|
|
72
100
|
|
|
73
|
-
|
|
74
|
-
|
|
101
|
+
### CLI approach
|
|
102
|
+
|
|
103
|
+
Recommended for developers with access to a live dbt project. Works with SQL parse mode (no `dbt compile` needed) as well as manifest mode.
|
|
104
|
+
|
|
105
|
+
Install dlin and add the following to your `AGENTS.md`, `CLAUDE.md`, or system prompt:
|
|
75
106
|
|
|
76
107
|
````md
|
|
77
108
|
## dbt project structure analysis
|
|
@@ -90,16 +121,32 @@ git diff --name-only main | dlin graph -q # Lineage of changed file
|
|
|
90
121
|
For full option reference: `dlin --help`, `dlin graph --help`, etc.
|
|
91
122
|
````
|
|
92
123
|
|
|
93
|
-
The key line is **"Do NOT grep/cat/find through SQL files"
|
|
124
|
+
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.
|
|
125
|
+
|
|
126
|
+
### MCP server (experimental)
|
|
127
|
+
|
|
128
|
+
For analysts and agents who work from a distributed `manifest.json` without access to the full project. Runs in manifest mode only.
|
|
129
|
+
|
|
130
|
+
`dlin mcp` exposes a stdio MCP server that AI assistants supporting MCP can connect to directly.
|
|
131
|
+
|
|
132
|
+
```sh
|
|
133
|
+
dlin mcp --dialect bigquery path/to/manifest.json
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Available MCP tools: project summary, model search, lineage, impact analysis, and column-level lineage.
|
|
137
|
+
|
|
138
|
+
Pass `--dialect` to match your project's SQL dialect for accurate column lineage. Requires a compiled `manifest.json` (`dbt compile`).
|
|
94
139
|
|
|
95
140
|
## Features
|
|
96
141
|
|
|
97
|
-
- **
|
|
142
|
+
- **SQL parse mode**: single binary, no Python, no `manifest.json` needed for model-level lineage
|
|
143
|
+
- **Manifest mode**: works from `manifest.json` alone; useful for analysts or agents without a full project checkout
|
|
144
|
+
- **MCP server** (experimental): `dlin mcp` serves lineage data via stdio MCP for direct AI assistant integration
|
|
98
145
|
- **Recursive upstream / downstream**: `-u N` / `-d N` to control traversal depth
|
|
99
146
|
- **Impact analysis with severity**: `dlin impact` scores downstream nodes and flags exposure reachability
|
|
100
147
|
- **Composable**: stdin accepts model names or file paths; pipe with `jq`, `dlin list`, `git diff`, etc.
|
|
101
148
|
- **Agent-friendly**: `--error-format json` emits structured `{"level","what","why","hint"}` on stderr; `--help` is designed for tool discovery
|
|
102
|
-
- **Column-level lineage** (experimental): traces columns across models with transformation classification; requires `
|
|
149
|
+
- **Column-level lineage** (experimental): traces columns across models with transformation classification; requires `manifest.json`
|
|
103
150
|
|
|
104
151
|
## Mermaid diagrams
|
|
105
152
|
|
|
@@ -110,11 +157,11 @@ dlin outputs Mermaid flowcharts that render natively on GitHub, GitLab, Notion,
|
|
|
110
157
|
Automatically remove intermediate nodes to see just the endpoints (nodes with no predecessors or no successors); everything in between becomes transitive "(via N)" edges:
|
|
111
158
|
|
|
112
159
|
```sh
|
|
113
|
-
# Collapse intermediate models
|
|
160
|
+
# Collapse intermediate models; only endpoints remain
|
|
114
161
|
dlin graph --collapse -o mermaid
|
|
115
162
|
|
|
116
163
|
# Focal mode: keep only sources, exposures, and specified focus models
|
|
117
|
-
# (ignores BFS window pseudo-endpoints
|
|
164
|
+
# (ignores BFS window pseudo-endpoints; works best with -u/-d limits)
|
|
118
165
|
dlin graph orders --collapse=focal -u 3 -o mermaid
|
|
119
166
|
```
|
|
120
167
|
|
|
@@ -196,7 +243,7 @@ flowchart LR
|
|
|
196
243
|
|
|
197
244
|
### Column names in nodes with `--show-columns`
|
|
198
245
|
|
|
199
|
-
Add `--show-columns` to include column names inside Mermaid node labels
|
|
246
|
+
Add `--show-columns` to include column names inside Mermaid node labels, useful for understanding what each model produces at a glance:
|
|
200
247
|
|
|
201
248
|
```sh
|
|
202
249
|
dlin graph orders -u 1 -d 0 --show-columns --node-type model,source -o mermaid
|
|
@@ -321,7 +368,7 @@ flowchart LR
|
|
|
321
368
|
n1_0 -->|"aggregation"|n0_5
|
|
322
369
|
```
|
|
323
370
|
|
|
324
|
-
`customer_id`, `email`, etc. pass through `stg_customers` unchanged from `raw.customers` (all `direct`). `lifetime_value` and `order_count` are aggregated at the `customers` model
|
|
371
|
+
`customer_id`, `email`, etc. pass through `stg_customers` unchanged from `raw.customers` (all `direct`). `lifetime_value` and `order_count` are aggregated at the `customers` model. The final edge to `customers` is labeled `aggregation`, while all upstream hops carry their actual transformation type (here `direct`, since staging and mart models pass columns through unchanged).
|
|
325
372
|
|
|
326
373
|
Transformation types shown on edges: `direct`, `aggregation`, `expression`, `cast`, `conditional`, `unknown`.
|
|
327
374
|
|
|
@@ -398,25 +445,6 @@ dlin graph -s tag:finance,path:marts # selector expressions (union)
|
|
|
398
445
|
dlin graph --node-type model,source # filter by node type
|
|
399
446
|
```
|
|
400
447
|
|
|
401
|
-
## Data sources
|
|
402
|
-
|
|
403
|
-
dlin aims to work without `dbt compile` (except for column-level lineage, which always requires `manifest.json`). By default it parses SQL files directly, but it can also leverage a pre-compiled `manifest.json` for additional accuracy when one is available.
|
|
404
|
-
|
|
405
|
-
**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.
|
|
406
|
-
|
|
407
|
-
**Manifest mode** (`--source manifest`): reads a pre-compiled `manifest.json` for full accuracy with complex Jinja logic.
|
|
408
|
-
|
|
409
|
-
For graph, list, impact, summary, and column commands, manifest mode requires only `manifest.json`; SQL files are not needed. When inputs are model names (not file paths), `dbt_project.yml` is also not needed; file-path inputs (e.g. `models/foo.sql`) fall back to standard dbt directory layout when `dbt_project.yml` is absent, which may not match projects with custom path configuration. A developer can run `dbt compile` once and distribute the resulting `manifest.json` to analysts or AI agents who then query it with dlin without access to the full project. (`check-manifest` always requires a full project.)
|
|
410
|
-
|
|
411
|
-
### Limitations of SQL parse mode
|
|
412
|
-
|
|
413
|
-
- `var()` resolves from `dbt_project.yml` only (`--vars` CLI overrides not supported)
|
|
414
|
-
- Runtime context (`target.type`, `env_var()`) is not evaluated
|
|
415
|
-
- Conditional Jinja branches use default values; non-default paths may be missed
|
|
416
|
-
- 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
|
|
417
|
-
|
|
418
|
-
When these limitations matter, use `--source manifest`.
|
|
419
|
-
|
|
420
448
|
## Credits
|
|
421
449
|
|
|
422
450
|
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.
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
[](https://pypi.org/project/dlin-cli/)
|
|
5
5
|
[](https://deepwiki.com/eitsupi/dlin)
|
|
6
6
|
|
|
7
|
-
dbt model lineage CLI
|
|
7
|
+
dbt model lineage CLI. Parses SQL files directly or reads a compiled `manifest.json`. No Python required.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Works for developers navigating live SQL files, analysts exploring a shared manifest, AI agents via CLI prompt or MCP server, and CI pipelines.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Column-level lineage (`dlin column upstream` / `dlin column downstream`) is also available. It requires `manifest.json`.
|
|
12
12
|
|
|
13
13
|
## Motivation
|
|
14
14
|
|
|
@@ -68,10 +68,41 @@ dlin list -o json --json-fields unique_id,file_path
|
|
|
68
68
|
git diff --name-only main | dlin graph -o json
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
+
## Source modes
|
|
72
|
+
|
|
73
|
+
dlin supports two source modes for model-level commands.
|
|
74
|
+
|
|
75
|
+
**SQL parse mode (default)** is for developers working with a live dbt project. dlin reads `ref()` and `source()` calls directly from SQL files without running `dbt compile`. It works immediately as you edit models, with no compilation step needed.
|
|
76
|
+
|
|
77
|
+
**Manifest mode** (`--source manifest`) is for analysts or agents who have access only to a compiled `manifest.json`. A developer runs `dbt compile` once and distributes the result; anyone with that file can then explore the full project structure with dlin without needing SQL files or a Python environment.
|
|
78
|
+
|
|
79
|
+
```sh
|
|
80
|
+
# SQL parse mode: reads SQL files directly (default)
|
|
81
|
+
dlin graph orders
|
|
82
|
+
|
|
83
|
+
# Manifest mode: reads manifest.json only
|
|
84
|
+
dlin graph orders --source manifest
|
|
85
|
+
dlin summary --source manifest
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
For model-name inputs, `manifest.json` is the only file needed in manifest mode. File-path inputs (e.g. `models/foo.sql`) fall back to standard dbt directory layout when `dbt_project.yml` is absent, which may not match projects with custom path configuration. (`check-manifest` always requires a full project.)
|
|
89
|
+
|
|
90
|
+
### Limitations of SQL parse mode
|
|
91
|
+
|
|
92
|
+
- `var()` resolves from `dbt_project.yml` only (`--vars` CLI overrides not supported)
|
|
93
|
+
- Runtime context (`target.type`, `env_var()`) is not evaluated
|
|
94
|
+
- Conditional Jinja branches use default values; non-default paths may be missed
|
|
95
|
+
- 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
|
|
96
|
+
|
|
97
|
+
When these limitations matter, use `--source manifest`.
|
|
98
|
+
|
|
71
99
|
## AI agent integration
|
|
72
100
|
|
|
73
|
-
|
|
74
|
-
|
|
101
|
+
### CLI approach
|
|
102
|
+
|
|
103
|
+
Recommended for developers with access to a live dbt project. Works with SQL parse mode (no `dbt compile` needed) as well as manifest mode.
|
|
104
|
+
|
|
105
|
+
Install dlin and add the following to your `AGENTS.md`, `CLAUDE.md`, or system prompt:
|
|
75
106
|
|
|
76
107
|
````md
|
|
77
108
|
## dbt project structure analysis
|
|
@@ -90,16 +121,32 @@ git diff --name-only main | dlin graph -q # Lineage of changed file
|
|
|
90
121
|
For full option reference: `dlin --help`, `dlin graph --help`, etc.
|
|
91
122
|
````
|
|
92
123
|
|
|
93
|
-
The key line is **"Do NOT grep/cat/find through SQL files"
|
|
124
|
+
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.
|
|
125
|
+
|
|
126
|
+
### MCP server (experimental)
|
|
127
|
+
|
|
128
|
+
For analysts and agents who work from a distributed `manifest.json` without access to the full project. Runs in manifest mode only.
|
|
129
|
+
|
|
130
|
+
`dlin mcp` exposes a stdio MCP server that AI assistants supporting MCP can connect to directly.
|
|
131
|
+
|
|
132
|
+
```sh
|
|
133
|
+
dlin mcp --dialect bigquery path/to/manifest.json
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Available MCP tools: project summary, model search, lineage, impact analysis, and column-level lineage.
|
|
137
|
+
|
|
138
|
+
Pass `--dialect` to match your project's SQL dialect for accurate column lineage. Requires a compiled `manifest.json` (`dbt compile`).
|
|
94
139
|
|
|
95
140
|
## Features
|
|
96
141
|
|
|
97
|
-
- **
|
|
142
|
+
- **SQL parse mode**: single binary, no Python, no `manifest.json` needed for model-level lineage
|
|
143
|
+
- **Manifest mode**: works from `manifest.json` alone; useful for analysts or agents without a full project checkout
|
|
144
|
+
- **MCP server** (experimental): `dlin mcp` serves lineage data via stdio MCP for direct AI assistant integration
|
|
98
145
|
- **Recursive upstream / downstream**: `-u N` / `-d N` to control traversal depth
|
|
99
146
|
- **Impact analysis with severity**: `dlin impact` scores downstream nodes and flags exposure reachability
|
|
100
147
|
- **Composable**: stdin accepts model names or file paths; pipe with `jq`, `dlin list`, `git diff`, etc.
|
|
101
148
|
- **Agent-friendly**: `--error-format json` emits structured `{"level","what","why","hint"}` on stderr; `--help` is designed for tool discovery
|
|
102
|
-
- **Column-level lineage** (experimental): traces columns across models with transformation classification; requires `
|
|
149
|
+
- **Column-level lineage** (experimental): traces columns across models with transformation classification; requires `manifest.json`
|
|
103
150
|
|
|
104
151
|
## Mermaid diagrams
|
|
105
152
|
|
|
@@ -110,11 +157,11 @@ dlin outputs Mermaid flowcharts that render natively on GitHub, GitLab, Notion,
|
|
|
110
157
|
Automatically remove intermediate nodes to see just the endpoints (nodes with no predecessors or no successors); everything in between becomes transitive "(via N)" edges:
|
|
111
158
|
|
|
112
159
|
```sh
|
|
113
|
-
# Collapse intermediate models
|
|
160
|
+
# Collapse intermediate models; only endpoints remain
|
|
114
161
|
dlin graph --collapse -o mermaid
|
|
115
162
|
|
|
116
163
|
# Focal mode: keep only sources, exposures, and specified focus models
|
|
117
|
-
# (ignores BFS window pseudo-endpoints
|
|
164
|
+
# (ignores BFS window pseudo-endpoints; works best with -u/-d limits)
|
|
118
165
|
dlin graph orders --collapse=focal -u 3 -o mermaid
|
|
119
166
|
```
|
|
120
167
|
|
|
@@ -196,7 +243,7 @@ flowchart LR
|
|
|
196
243
|
|
|
197
244
|
### Column names in nodes with `--show-columns`
|
|
198
245
|
|
|
199
|
-
Add `--show-columns` to include column names inside Mermaid node labels
|
|
246
|
+
Add `--show-columns` to include column names inside Mermaid node labels, useful for understanding what each model produces at a glance:
|
|
200
247
|
|
|
201
248
|
```sh
|
|
202
249
|
dlin graph orders -u 1 -d 0 --show-columns --node-type model,source -o mermaid
|
|
@@ -321,7 +368,7 @@ flowchart LR
|
|
|
321
368
|
n1_0 -->|"aggregation"|n0_5
|
|
322
369
|
```
|
|
323
370
|
|
|
324
|
-
`customer_id`, `email`, etc. pass through `stg_customers` unchanged from `raw.customers` (all `direct`). `lifetime_value` and `order_count` are aggregated at the `customers` model
|
|
371
|
+
`customer_id`, `email`, etc. pass through `stg_customers` unchanged from `raw.customers` (all `direct`). `lifetime_value` and `order_count` are aggregated at the `customers` model. The final edge to `customers` is labeled `aggregation`, while all upstream hops carry their actual transformation type (here `direct`, since staging and mart models pass columns through unchanged).
|
|
325
372
|
|
|
326
373
|
Transformation types shown on edges: `direct`, `aggregation`, `expression`, `cast`, `conditional`, `unknown`.
|
|
327
374
|
|
|
@@ -398,25 +445,6 @@ dlin graph -s tag:finance,path:marts # selector expressions (union)
|
|
|
398
445
|
dlin graph --node-type model,source # filter by node type
|
|
399
446
|
```
|
|
400
447
|
|
|
401
|
-
## Data sources
|
|
402
|
-
|
|
403
|
-
dlin aims to work without `dbt compile` (except for column-level lineage, which always requires `manifest.json`). By default it parses SQL files directly, but it can also leverage a pre-compiled `manifest.json` for additional accuracy when one is available.
|
|
404
|
-
|
|
405
|
-
**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.
|
|
406
|
-
|
|
407
|
-
**Manifest mode** (`--source manifest`): reads a pre-compiled `manifest.json` for full accuracy with complex Jinja logic.
|
|
408
|
-
|
|
409
|
-
For graph, list, impact, summary, and column commands, manifest mode requires only `manifest.json`; SQL files are not needed. When inputs are model names (not file paths), `dbt_project.yml` is also not needed; file-path inputs (e.g. `models/foo.sql`) fall back to standard dbt directory layout when `dbt_project.yml` is absent, which may not match projects with custom path configuration. A developer can run `dbt compile` once and distribute the resulting `manifest.json` to analysts or AI agents who then query it with dlin without access to the full project. (`check-manifest` always requires a full project.)
|
|
410
|
-
|
|
411
|
-
### Limitations of SQL parse mode
|
|
412
|
-
|
|
413
|
-
- `var()` resolves from `dbt_project.yml` only (`--vars` CLI overrides not supported)
|
|
414
|
-
- Runtime context (`target.type`, `env_var()`) is not evaluated
|
|
415
|
-
- Conditional Jinja branches use default values; non-default paths may be missed
|
|
416
|
-
- 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
|
|
417
|
-
|
|
418
|
-
When these limitations matter, use `--source manifest`.
|
|
419
|
-
|
|
420
448
|
## Credits
|
|
421
449
|
|
|
422
450
|
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.
|