dlin-cli 0.1.0__py3-none-win_amd64.whl
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.
|
Binary file
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dlin-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Classifier: Development Status :: 4 - Beta
|
|
5
|
+
Classifier: Environment :: Console
|
|
6
|
+
Classifier: Intended Audience :: Developers
|
|
7
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
+
Classifier: Operating System :: OS Independent
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Rust
|
|
11
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Summary: A fast CLI tool for dbt model lineage analysis
|
|
14
|
+
Keywords: dbt,lineage,dag,sql,cli
|
|
15
|
+
Home-Page: https://github.com/eitsupi/dlin
|
|
16
|
+
Author: eitsupi
|
|
17
|
+
License-Expression: MIT
|
|
18
|
+
Requires-Python: >=3.9
|
|
19
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
20
|
+
Project-URL: Homepage, https://github.com/eitsupi/dlin
|
|
21
|
+
Project-URL: Repository, https://github.com/eitsupi/dlin
|
|
22
|
+
|
|
23
|
+
# dlin
|
|
24
|
+
|
|
25
|
+
[](https://crates.io/crates/dlin)
|
|
26
|
+
[](https://pypi.org/project/dlin-cli/)
|
|
27
|
+
|
|
28
|
+
dbt lineage analysis CLI that parses SQL files directly. No `dbt compile`, no Python, no `manifest.json`.
|
|
29
|
+
|
|
30
|
+
Builds a dependency graph from `ref()` and `source()` calls in SQL. Designed for AI agents and CI pipelines.
|
|
31
|
+
|
|
32
|
+
## Motivation
|
|
33
|
+
|
|
34
|
+
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.
|
|
35
|
+
|
|
36
|
+
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.
|
|
37
|
+
|
|
38
|
+
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.
|
|
39
|
+
|
|
40
|
+
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.
|
|
41
|
+
|
|
42
|
+
## Install
|
|
43
|
+
|
|
44
|
+
### Cargo (Rust)
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
cargo install dlin
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### pip / uv (Python)
|
|
51
|
+
|
|
52
|
+
For convenience, dlin is also available as a Python package. The installed binary is native and does not require Python at runtime.
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
pip install dlin-cli # or: uv tool install dlin-cli
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### GitHub Releases
|
|
59
|
+
|
|
60
|
+
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:
|
|
61
|
+
|
|
62
|
+
macOS / Linux:
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/eitsupi/dlin/releases/latest/download/dlin-installer.sh | sh
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Windows (PowerShell):
|
|
69
|
+
|
|
70
|
+
```powershell
|
|
71
|
+
powershell -ExecutionPolicy Bypass -c "irm https://github.com/eitsupi/dlin/releases/latest/download/dlin-installer.ps1 | iex"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Quick start
|
|
75
|
+
|
|
76
|
+
```sh
|
|
77
|
+
# Full lineage graph
|
|
78
|
+
dlin graph -p path/to/dbt/project
|
|
79
|
+
|
|
80
|
+
# Downstream impact analysis
|
|
81
|
+
dlin impact orders
|
|
82
|
+
|
|
83
|
+
# List models as JSON
|
|
84
|
+
dlin list -o json --json-fields unique_id,file_path
|
|
85
|
+
|
|
86
|
+
# Pipe changed files into lineage
|
|
87
|
+
git diff --name-only main | dlin graph -o json
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Features
|
|
91
|
+
|
|
92
|
+
- **No dependencies**: single binary, no Python, no `manifest.json`
|
|
93
|
+
- **Recursive upstream / downstream**: `-u N` / `-d N` to control traversal depth
|
|
94
|
+
- **Impact analysis with severity**: `dlin impact` scores downstream nodes and flags exposure reachability
|
|
95
|
+
- **Composable**: stdin accepts model names or file paths; pipe with `jq`, `dlin list`, `git diff`, etc.
|
|
96
|
+
- **Agent-friendly**: `--error-format json` emits structured `{"level","what","why","hint"}` on stderr; `--help` is designed for tool discovery
|
|
97
|
+
|
|
98
|
+
## Mermaid diagrams
|
|
99
|
+
|
|
100
|
+
dlin outputs Mermaid flowcharts that render natively on GitHub, GitLab, Notion, and other Markdown environments.
|
|
101
|
+
|
|
102
|
+
### Simplified graphs with `--collapse`
|
|
103
|
+
|
|
104
|
+
Automatically remove intermediate nodes to see just the endpoints — sources, leaf models, and exposures are kept; everything in between becomes transitive "(via N)" edges:
|
|
105
|
+
|
|
106
|
+
```sh
|
|
107
|
+
# Collapse intermediate models — only endpoints remain
|
|
108
|
+
dlin graph --collapse -o mermaid
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
```mermaid
|
|
112
|
+
flowchart LR
|
|
113
|
+
exposure_weekly_report>"weekly_report"]
|
|
114
|
+
model_combined_orders["combined_orders"]
|
|
115
|
+
model_order_summary["order_summary"]
|
|
116
|
+
source_raw_customers(["raw.customers"])
|
|
117
|
+
source_raw_orders(["raw.orders"])
|
|
118
|
+
source_raw_payments(["raw.payments"])
|
|
119
|
+
|
|
120
|
+
source_raw_customers ==>|"exposure (via 2)"| exposure_weekly_report
|
|
121
|
+
source_raw_orders ==>|"exposure (via 3)"| exposure_weekly_report
|
|
122
|
+
source_raw_orders -.->|"source (via 1)"| model_combined_orders
|
|
123
|
+
source_raw_orders -.->|"source (via 1)"| model_order_summary
|
|
124
|
+
source_raw_payments ==>|"exposure (via 3)"| exposure_weekly_report
|
|
125
|
+
source_raw_payments -.->|"source (via 1)"| model_order_summary
|
|
126
|
+
|
|
127
|
+
classDef model fill:#4A90D9,stroke:#333,color:#fff
|
|
128
|
+
classDef source fill:#27AE60,stroke:#333,color:#fff
|
|
129
|
+
classDef exposure fill:#E74C3C,stroke:#333,color:#fff
|
|
130
|
+
class exposure_weekly_report exposure
|
|
131
|
+
class model_combined_orders model
|
|
132
|
+
class model_order_summary model
|
|
133
|
+
class source_raw_customers source
|
|
134
|
+
class source_raw_orders source
|
|
135
|
+
class source_raw_payments source
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Combine with `--group-by` to collapse per group instead of globally — for example, `--collapse --group-by directory` keeps the entry/exit models of each directory.
|
|
139
|
+
|
|
140
|
+
### Pipe to build focused diagrams
|
|
141
|
+
|
|
142
|
+
Combine `dlin list`, `jq`, and `dlin graph` to extract exactly the nodes you want:
|
|
143
|
+
|
|
144
|
+
```sh
|
|
145
|
+
# Staging models → 1 hop downstream, models only, grouped by directory
|
|
146
|
+
dlin list -s 'path:models/staging' -o json | jq -r '.[].label' |
|
|
147
|
+
dlin graph -d 1 --node-type model --group-by directory -o mermaid
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
```mermaid
|
|
151
|
+
flowchart LR
|
|
152
|
+
subgraph models_marts["models/marts"]
|
|
153
|
+
model_combined_orders["combined_orders"]
|
|
154
|
+
model_customers["customers"]
|
|
155
|
+
model_order_summary["order_summary"]
|
|
156
|
+
model_orders["orders"]
|
|
157
|
+
end
|
|
158
|
+
subgraph models_staging["models/staging"]
|
|
159
|
+
model_stg_customers["stg_customers"]
|
|
160
|
+
model_stg_online_orders["stg_online_orders"]
|
|
161
|
+
model_stg_orders["stg_orders"]
|
|
162
|
+
model_stg_payments["stg_payments"]
|
|
163
|
+
model_stg_retail_orders["stg_retail_orders"]
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
model_orders -->|ref| model_customers
|
|
167
|
+
model_stg_customers -->|ref| model_customers
|
|
168
|
+
model_stg_online_orders -->|ref| model_combined_orders
|
|
169
|
+
model_stg_orders -->|ref| model_order_summary
|
|
170
|
+
model_stg_orders -->|ref| model_orders
|
|
171
|
+
model_stg_payments -->|ref| model_order_summary
|
|
172
|
+
model_stg_payments -->|ref| model_orders
|
|
173
|
+
model_stg_retail_orders -->|ref| model_combined_orders
|
|
174
|
+
|
|
175
|
+
classDef model fill:#4A90D9,stroke:#333,color:#fff
|
|
176
|
+
class model_combined_orders model
|
|
177
|
+
class model_customers model
|
|
178
|
+
class model_order_summary model
|
|
179
|
+
class model_orders model
|
|
180
|
+
class model_stg_customers model
|
|
181
|
+
class model_stg_online_orders model
|
|
182
|
+
class model_stg_orders model
|
|
183
|
+
class model_stg_payments model
|
|
184
|
+
class model_stg_retail_orders model
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Column names in nodes with `--show-columns`
|
|
188
|
+
|
|
189
|
+
Add `--show-columns` to include column names inside Mermaid node labels — useful for understanding what each model produces at a glance:
|
|
190
|
+
|
|
191
|
+
```sh
|
|
192
|
+
dlin graph orders -u 1 -d 0 --show-columns --node-type model,source -o mermaid
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
```mermaid
|
|
196
|
+
flowchart LR
|
|
197
|
+
model_orders["orders<br/>---<br/>order_id, customer_id, order_date, status, total_amount, payment_method"]
|
|
198
|
+
model_stg_orders["stg_orders<br/>---<br/>order_id, customer_id, order_date, status"]
|
|
199
|
+
model_stg_payments["stg_payments<br/>---<br/>payment_id, order_id, amount, payment_method"]
|
|
200
|
+
|
|
201
|
+
model_stg_orders -->|ref| model_orders
|
|
202
|
+
model_stg_payments -->|ref| model_orders
|
|
203
|
+
|
|
204
|
+
classDef model fill:#4A90D9,stroke:#333,color:#fff
|
|
205
|
+
class model_orders model
|
|
206
|
+
class model_stg_orders model
|
|
207
|
+
class model_stg_payments model
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Combines well with `--collapse` to show rich detail on fewer endpoint nodes.
|
|
211
|
+
|
|
212
|
+
### Other graph options
|
|
213
|
+
|
|
214
|
+
```sh
|
|
215
|
+
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
|
+
dlin graph -o mermaid --collapse --show-columns # columns in collapsed nodes
|
|
218
|
+
dlin graph -o mermaid --group-by directory # group by directory
|
|
219
|
+
dlin graph -o mermaid --direction tb # top-to-bottom layout
|
|
220
|
+
dlin graph --node-type source,exposure # filter by node type
|
|
221
|
+
dlin graph -o dot | dot -Tsvg > out.svg # Graphviz rendering
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Output formats: ASCII (default), JSON, Mermaid, Graphviz DOT, Plain, SVG, HTML.
|
|
225
|
+
|
|
226
|
+
## Key subcommands
|
|
227
|
+
|
|
228
|
+
### `list`
|
|
229
|
+
|
|
230
|
+
```sh
|
|
231
|
+
dlin list # all models and sources
|
|
232
|
+
dlin list orders -o json --json-fields unique_id,file_path # specific model as JSON
|
|
233
|
+
dlin list --node-type source # sources only
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### `impact`
|
|
237
|
+
|
|
238
|
+
```sh
|
|
239
|
+
$ dlin impact orders
|
|
240
|
+
Impact Analysis: orders
|
|
241
|
+
==================================================
|
|
242
|
+
Overall Severity: CRITICAL
|
|
243
|
+
|
|
244
|
+
Summary:
|
|
245
|
+
Affected models: 1
|
|
246
|
+
Affected tests: 1
|
|
247
|
+
Affected exposures: 1
|
|
248
|
+
|
|
249
|
+
Impacted Nodes:
|
|
250
|
+
[critical] weekly_report (exposure, distance: 1)
|
|
251
|
+
[high ] customers (model, distance: 1) [models/marts/customers.sql]
|
|
252
|
+
[low ] assert_orders_positive_amount (test, distance: 1)
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Filtering
|
|
256
|
+
|
|
257
|
+
```sh
|
|
258
|
+
dlin graph -s tag:finance,path:marts # selector expressions (union)
|
|
259
|
+
dlin graph --node-type model,source # filter by node type
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## Data sources
|
|
263
|
+
|
|
264
|
+
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.
|
|
265
|
+
|
|
266
|
+
**SQL parsing (default)**: extracts `ref()` and `source()` from SQL via regex + Jinja template evaluation. No Python or dbt needed.
|
|
267
|
+
|
|
268
|
+
**Manifest mode** (`--source manifest`): reads a pre-compiled `manifest.json` for full accuracy with complex Jinja logic.
|
|
269
|
+
|
|
270
|
+
### Limitations of SQL parse mode
|
|
271
|
+
|
|
272
|
+
- `var()` resolves from `dbt_project.yml` only (`--vars` CLI overrides not supported)
|
|
273
|
+
- Runtime context (`target.type`, `env_var()`) is not evaluated
|
|
274
|
+
- Conditional Jinja branches use default values; non-default paths may be missed
|
|
275
|
+
|
|
276
|
+
When these limitations matter, use `--source manifest`.
|
|
277
|
+
|
|
278
|
+
## Credits
|
|
279
|
+
|
|
280
|
+
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.
|
|
281
|
+
|
|
282
|
+
## License
|
|
283
|
+
|
|
284
|
+
MIT
|
|
285
|
+
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
dlin_cli-0.1.0.data/scripts/dlin.exe,sha256=Q2IPa0VJ-toPLEwdBSiMrJdkXLC7aa4o7TSpMBe-WfM,6072320
|
|
2
|
+
dlin_cli-0.1.0.dist-info/METADATA,sha256=Fq2Rnh5kvwXJcv-BILORBEhgJ7uJvd0SysdY0rxujRI,11213
|
|
3
|
+
dlin_cli-0.1.0.dist-info/WHEEL,sha256=uJOc2U-Q1x95AlblQcqMRb3iR4QnPtdI7X2ycPN99rM,94
|
|
4
|
+
dlin_cli-0.1.0.dist-info/licenses/LICENSE,sha256=oTEbuwBnRN5jcwIiJcctcKBftc_AbiPjwnPjBzfmZFE,1124
|
|
5
|
+
dlin_cli-0.1.0.dist-info/sboms/dlin.cyclonedx.json,sha256=zpaQhE0kDShHuo0JaV0r9LdiLA3oEW4TxW-RH4yAEIU,88245
|
|
6
|
+
dlin_cli-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Simon Müller
|
|
4
|
+
Copyright (c) 2026 dlin authors
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|