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
20 changes: 15 additions & 5 deletions drift.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = 1
doc = ".claude/skills/drift/SKILL.md"
target = "src/main.zig"
origin = "github:fiberplane/drift"
sig = "0e63465cf6539ff3"
sig = "3faa73e2bb344a79"

[[bindings]]
doc = ".claude/skills/drift/SKILL.md"
Expand All @@ -20,12 +20,12 @@ sig = "2dccb33f6b790afa"
[[bindings]]
doc = "CLAUDE.md"
target = "src/main.zig"
sig = "0e63465cf6539ff3"
sig = "3faa73e2bb344a79"

[[bindings]]
doc = "docs/CLI.md"
target = "src/commands/link.zig"
sig = "7bd7f824afc30e0b"
sig = "3ae8f4ee2c85d8d8"

[[bindings]]
doc = "docs/CLI.md"
Expand Down Expand Up @@ -60,18 +60,28 @@ sig = "55bc77a2853cb654"
[[bindings]]
doc = "docs/DESIGN.md"
target = "src/main.zig"
sig = "0e63465cf6539ff3"
sig = "3faa73e2bb344a79"

[[bindings]]
doc = "docs/DESIGN.md"
target = "src/symbols.zig"
sig = "bbe250d43609daa1"
sig = "772dd9e7e974468e"

[[bindings]]
doc = "docs/DESIGN.md"
target = "src/vcs.zig"
sig = "84da70be235ca9d4"

[[bindings]]
doc = "docs/DESIGN.md"
target = "src/vcs.zig#GitCatFile"
sig = "c61b49f799a878de"

[[bindings]]
doc = "docs/DESIGN.md"
target = "src/vcs.zig#getRepoIdentity"
sig = "7d0fe37e5eff5e30"

[[bindings]]
doc = "docs/RELEASING.md"
target = ".github/workflows/ci.yml"
Expand Down
16 changes: 14 additions & 2 deletions src/commands/link.zig
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,13 @@ pub fn run(
const existing_binding = findBinding(lf.bindings.items, normalized_doc_path, normalized_target);
const old_sig = if (existing_binding) |b| b.fieldValue("sig") else null;

try upsertBinding(ctx, &lf, cwd_path, normalized_doc_path, normalized_target);
upsertBinding(ctx, &lf, cwd_path, normalized_doc_path, normalized_target) catch |err| switch (err) {
error.CannotComputeFingerprint => {
stderr_w.print("error: cannot compute fingerprint for target: {s}\n", .{raw_anchor}) catch {};
return err;
},
else => return err,
};

const binding = findBinding(lf.bindings.items, normalized_doc_path, normalized_target).?;
if (isDocGateBlocked(binding, old_sig, doc_is_still_accurate)) {
Expand All @@ -73,7 +79,13 @@ pub fn run(
for (lf.bindings.items) |*binding| {
if (!std.mem.eql(u8, binding.doc_path, normalized_doc_path)) continue;
const old_sig = binding.fieldValue("sig");
try refreshBindingSig(ctx, cwd_path, lf.root_path, binding);
refreshBindingSig(ctx, cwd_path, lf.root_path, binding) catch |err| switch (err) {
error.CannotComputeFingerprint => {
stderr_w.print("error: cannot compute fingerprint for target: {s}\n", .{binding.target}) catch {};
return err;
},
else => return err,
};

if (isDocGateBlocked(binding, old_sig, doc_is_still_accurate)) {
refused_count += 1;
Expand Down
2 changes: 1 addition & 1 deletion src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ pub fn main(init: std.process.Init) !void {
fatal(&stderr_w.interface, "", .{});
},
error.CannotComputeFingerprint => {
fatal(&stderr_w.interface, "error: cannot compute fingerprint for anchor in '{s}'\n", .{doc_path});
fatal(&stderr_w.interface, "", .{});
},
error.DocUnchanged => {
fatal(&stderr_w.interface, "", .{});
Expand Down
11 changes: 5 additions & 6 deletions src/queries/zig.scm
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
; Symbol declarations in Zig
; Symbol declarations in Zig (tree-sitter-grammars/tree-sitter-zig node names)
[
(TopLevelDecl
(FnDecl
(IDENTIFIER) @name)) @definition
(VarDecl
(IDENTIFIER) @name) @definition
(function_declaration
name: (identifier) @name) @definition
(variable_declaration
. (identifier) @name) @definition
]
42 changes: 42 additions & 0 deletions src/symbols.zig
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,48 @@ test "fingerprintFileSyntax works for zig source" {
try std.testing.expect(fp != null);
}

test "symbol queries compile for every supported language" {
const extensions = [_][]const u8{ ".ts", ".py", ".rs", ".go", ".zig", ".java" };
for (extensions) |ext| {
const lang_query = languageForExtension(ext) orelse return error.TestUnexpectedResult;
var error_offset: u32 = 0;
const query = ts.Query.create(lang_query.language, lang_query.query_source, &error_offset) catch {
std.debug.print("symbol query for '{s}' failed to compile at byte offset {d}\n", .{ ext, error_offset });
return error.TestUnexpectedResult;
};
query.destroy();
}
}

test "fingerprintSymbolSyntax resolves zig fn and const declarations" {
const source =
\\const std = @import("std");
\\
\\pub const RepoMap = struct {
\\ entries: u32,
\\};
\\
\\pub fn parseSpec(spec: []const u8) void {
\\ _ = spec;
\\}
\\
;
const lang_query = languageForExtension(".zig") orelse return error.TestUnexpectedResult;
try std.testing.expect(fingerprintSymbolSyntax(source, lang_query, "parseSpec") != null);
try std.testing.expect(fingerprintSymbolSyntax(source, lang_query, "RepoMap") != null);
try std.testing.expect(fingerprintSymbolSyntax(source, lang_query, "missing") == null);
}

test "zig variable_declaration query matches only the declared name, not the initializer" {
const source =
\\const alias = imported_name;
\\
;
const lang_query = languageForExtension(".zig") orelse return error.TestUnexpectedResult;
try std.testing.expect(fingerprintSymbolSyntax(source, lang_query, "alias") != null);
try std.testing.expect(fingerprintSymbolSyntax(source, lang_query, "imported_name") == null);
}

test "computeFingerprint matches for real zig files" {
const allocator = std.testing.allocator;

Expand Down
Loading