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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ compatibility.
- Root-project `selectors.yml` scalar string aliases for selector-backed
commands through `--selector <name>`, lowering supported alias definitions to
the existing Zig selector engine.
- `state:new` selectors now read prior Manifest v12 `manifest.json` resource
IDs from `--state`, select current supported resources absent from that prior
manifest, and compose through existing graph expansion and `--exclude`
behavior.
- Supported built-in DuckDB generic tests now parse and emit `where`, `limit`,
`severity`, `warn_if`, and `error_if` configs for model, seed, and source
tests, apply `where`/`limit` to failure-row SQL, and classify warning results
Expand Down
9 changes: 5 additions & 4 deletions PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -460,10 +460,11 @@ support root-project `selectors.yml` entries whose `definition` is a scalar
string or a narrow composition of supported selector leaves through `union`,
`intersection`, and `exclude`, then lower `--selector <name>` to the existing
Zig selector and exclude expressions for commands sharing the selector engine.
They do not implement method: selector references, default selectors,
indirect-selection overrides, package/config YAML method broadening,
state/result/source-status matching, state artifact loading, or deferral
semantics.
They also support artifact-backed `result:*`, `source_status:*`, and first-slice
`state:new` matching through the common Zig selector engine. They do not
implement method: selector references, default selectors, indirect-selection
overrides, package/config YAML method broadening, broader state comparison, or
deferral semantics.

Current `ls` output formats source note:
`.agent/research/m2-ls-output-formats.md` maps dbt Core v1 `ListTask` output
Expand Down
8 changes: 5 additions & 3 deletions docs/COMPATIBILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ behavior, with DuckDB as the first deterministic execution adapter.
| Command | Status | Current support | Planned gaps |
| --- | --- | --- | --- |
| `dxt parse` | Partial | Loads supported project files and writes a deterministic Manifest v12-shaped slice, including analysis SQL resources, disabled SQL models from YAML properties, literal inline model `config(enabled=false)`, inline and YAML-disabled singular tests, and supported singular YAML patch/config fields. | Full dbt parser parity, saved queries, semantic resources, full package behavior. |
| `dxt ls` | Partial | Lists selected graph resources in text or JSON for supported selector syntax, including root-project `selectors.yml` scalar string aliases through `--selector <name>`, `source_status:pass` / `source_status:warn` / `source_status:error` from a `--state` directory containing Sources v3 `sources.json`, and `result:error` / `result:fail` / `result:success` / `result:skipped` from Run Results v6 `run_results.json`. | Broader YAML selector composition, remaining state/result/defer selectors, full indirect-selection parity. |
| `dxt ls` | Partial | Lists selected graph resources in text or JSON for supported selector syntax, including root-project `selectors.yml` scalar string aliases through `--selector <name>`, `state:new` from a `--state` directory containing Manifest v12 `manifest.json`, `source_status:pass` / `source_status:warn` / `source_status:error` from Sources v3 `sources.json`, and `result:error` / `result:fail` / `result:success` / `result:skipped` from Run Results v6 `run_results.json`. | Broader YAML selector composition, remaining state/result/defer selectors, full indirect-selection parity. |
| `dxt clean` | Partial | Deletes configured project-relative `clean-targets`, defaulting to the effective target path; protects source directories, rejects outside-project deletion, skips missing paths and plain files, and does not require a profile. | `--no-clean-project-files-only`, Fusion positional file args, symlink/canonical-path parity, richer dbt event output. |
| `dxt compile` | Partial | Compiles selected enabled SQL models, selected analyses, selected supported built-in generic tests, root-project model/source/seed column custom generic tests, installed-package model/source/seed column custom generic tests selected through `package.test_name`, and selected singular SQL tests through the supported render-only Jinja subset and writes compiled SQL plus manifest fields without opening DuckDB. | Non-column and table-level custom generic tests, full Jinja, general macro execution, adapter dispatch execution, arbitrary expressions, filters, hooks. |
| `dxt run` | Partial | Executes selected enabled DuckDB SQL models with `table` and `view` materializations; writes completed prior rows plus a sanitized `error` run-result row when a selected model fails during DuckDB execution, records `skipped` rows for selected blocked model descendants, and continues later selected independent models. | Seeds, tests, snapshots, incremental, ephemeral, hooks, grants, full materialization macros. |
Expand All @@ -30,7 +30,7 @@ behavior, with DuckDB as the first deterministic execution adapter.
| `--target-path` | Supported | Overrides project target path for artifacts and default DuckDB file. |
| `--vars` | Partial | Scalar CLI vars for narrow `ref()` / `source()` argument resolution, accepting strict JSON objects with stringified scalar values and the existing loose inline YAML-style scalar maps. |
| `--select`, `--selector`, `--exclude` | Partial | Supported selector subset with graph expansion. `--selector <name>` reads root-project `selectors.yml` entries whose `definition` is a scalar string and lowers them to existing selector expressions. |
| `--state` | Partial | Read-only selector input for `source_status:pass` / `source_status:warn` / `source_status:error`; the path must contain dbt Sources v3 `sources.json`. It does not enable `state:`, `result:`, defer, or manifest comparison. |
| `--state` | Partial | Read-only selector input for `state:new` from dbt Manifest v12 `manifest.json`, `result:*` from Run Results v6 `run_results.json`, and `source_status:pass` / `source_status:warn` / `source_status:error` from Sources v3 `sources.json`. It does not enable `state:modified`, defer, or manifest diffing beyond prior unique-id membership. |
| `--threads`, `--full-refresh` | Accepted/planned | Product semantics are not complete yet. |
| `--output`, `--output-keys` | Partial | `ls` supports legacy `text`, compact `json`, dbt-style `name`, `path`, and `selector` formats. `--output-keys` filters compact JSON to `unique_id`, `resource_type`, `name`, `package_name`, `source_name`, `alias`, source-only `identifier`, `path`, `original_file_path`, `tags`, `config.materialized`, `config.tags`, `config.enabled`, `config.docs.show`, `depends_on.nodes`, `depends_on.macros`, and dxt's compact `selector` extension; full dbt node JSON and arbitrary nested-key traversal are not implemented. |
| `--host`, `--port`, `--no-browser`, `--browser`, `--no-open` | Partial | `docs serve` parses these dbt Core/Fusion-shaped flags. Browser opening is intentionally unsupported in this slice; use `--no-browser`. |
Expand Down Expand Up @@ -76,10 +76,12 @@ behavior, with DuckDB as the first deterministic execution adapter.
| `--exclude` | Partial |
| `tag:`, `path:`, `file:`, `package:`, `resource_type:`, `test_type:`, `config.materialized:` | Partial; wildcard matching includes `*`, `?`, and fnmatch-style bracket character classes in the supported selector methods. |
| `source:`, `exposure:`, selected generic test names | Partial |
| `state:new` | Partial; reads prior Manifest v12 resource IDs from `--state/manifest.json` and participates in graph expansion such as `state:new+` and `+state:new`. |
| `source_status:pass`, `source_status:warn`, `source_status:error` | Partial; reads prior Sources v3 status rows from `--state/sources.json` and participates in graph expansion such as `source_status:warn+`. |
| `result:success`, `result:error`, `result:fail`, `result:skipped` | Partial; reads prior Run Results v6 status rows from `--state/run_results.json` and participates in graph expansion such as `result:error+`. |
| Wildcards | Partial; pinned to observed dbt Core behavior where tested. |
| Root `selectors.yml` scalar string aliases | Partial; `--selector <name>` resolves root-project selector entries with scalar string `definition` values into existing selector expressions. |
| YAML selector composition, state/result/defer/access/group/version selectors | Planned |
| YAML selector composition, remaining state/defer/access/group/version selectors | Planned |

## Artifacts

Expand Down
9 changes: 8 additions & 1 deletion src/project.zig
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const manifest = @import("project/manifest.zig");
const run_results = @import("project/run_results.zig");
const selector = @import("project/selector.zig");
const source_freshness = @import("project/source_freshness.zig");
const state_artifacts = @import("project/state.zig");
const types = @import("project/types.zig");
const util = @import("project/util.zig");

Expand Down Expand Up @@ -830,33 +831,39 @@ fn resolveSelection(runtime: Runtime, options: Options) !selector_config.Resolve
const SelectionState = struct {
source_status_index: ?source_freshness.SourceStatusIndex = null,
result_status_index: ?run_results.ResultStatusIndex = null,
prior_manifest_index: ?state_artifacts.PriorManifestIndex = null,

fn deinit(self: *SelectionState, allocator: std.mem.Allocator) void {
if (self.source_status_index) |*index| index.deinit(allocator);
if (self.result_status_index) |*index| index.deinit(allocator);
if (self.prior_manifest_index) |*index| index.deinit(allocator);
self.* = .{};
}

fn context(self: *const SelectionState) selector.SelectionContext {
var ctx: selector.SelectionContext = .{};
if (self.source_status_index) |*index| ctx.source_status_index = index;
if (self.result_status_index) |*index| ctx.result_status_index = index;
if (self.prior_manifest_index) |*index| ctx.prior_manifest_index = index;
return ctx;
}
};

fn loadSelectionState(runtime: Runtime, options: Options, selection: selector_config.ResolvedSelection) !SelectionState {
const needs_source_status = selector.usesSourceStatusSelector(selection.select, selection.exclude);
const needs_result = selector.usesResultSelector(selection.select, selection.exclude);
if (!needs_source_status and !needs_result) return .{};
const needs_state = selector.usesStateSelector(selection.select, selection.exclude);
if (!needs_source_status and !needs_result and !needs_state) return .{};

const state_dir = options.state orelse {
if (needs_state) return error.MissingStateManifestState;
if (needs_result) return error.MissingResultState;
return error.MissingSourceStatusState;
};

var state: SelectionState = .{};
errdefer state.deinit(runtime.allocator);
if (needs_state) state.prior_manifest_index = try state_artifacts.loadPriorManifestIndex(runtime, state_dir);
if (needs_source_status) state.source_status_index = try source_freshness.loadSourceStatusIndex(runtime, state_dir);
if (needs_result) state.result_status_index = try run_results.loadResultStatusIndex(runtime, state_dir);
return state;
Expand Down
Loading
Loading