srctree

Gregory Mullen parent 14707759 8851f468
resolve code in the default branch

src/endpoints/repos/diffs.zig added: 104, removed: 31, total 73
@@ -6,6 +6,7 @@ const eql = std.mem.eql;
const splitScalar = std.mem.splitScalar;
const indexOf = std.mem.indexOf;
const indexOfAny = std.mem.indexOfAny;
const indexOfScalarPos = std.mem.indexOfScalarPos;
const parseInt = std.fmt.parseInt;
const fmtSliceHexLower = std.fmt.fmtSliceHexLower;
 
@@ -346,6 +347,13 @@ const ParsedHeader = struct {
right: Numbers,
};
 
fn getLineFrom(data: []const u8, target: u32, length: u32) !?[]const u8 {
_ = data;
_ = target;
_ = length;
return null;
}
 
fn getLineAt(data: []const u8, target: u32, length: u32, right_only: bool) !?[]const u8 {
std.debug.assert(length == 1); // Not Implemented
var itr = splitScalar(u8, data, '\n');
@@ -396,12 +404,72 @@ fn parseBlockHeader(string: []const u8) !ParsedHeader {
};
}
 
fn resolveLineRef(
fn resolveLineRefRepo(
a: Allocator,
line: []const u8,
filename: []const u8,
repo: *const Git.Repo,
line_number: u32,
) !?[][]const u8 {
var found_lines = std.ArrayList([]const u8).init(a);
 
const cmt = try repo.headCommit(a);
var files: Git.Tree = try cmt.mkTree(a, repo);
var blob_sha: Git.SHA = undefined;
var itr = splitScalar(u8, filename, '/');
root: while (itr.next()) |dirname| {
for (files.blobs) |obj| {
if (eql(u8, obj.name, dirname)) {
if (obj.isFile()) {
if (itr.peek() != null) return error.InvalidFile;
blob_sha = obj.sha;
break :root;
}
files = try obj.toTree(a, repo);
continue :root;
}
} else {
std.debug.print("unable to resolve file {s} at {s}\n", .{ filename, dirname });
}
}
 
var file = try repo.loadBlob(a, blob_sha);
var start: usize = 0;
var end: usize = 0;
var count: usize = line_number;
while (indexOfScalarPos(u8, file.data.?, start + 1, '\n')) |next| {
if (count > 1) {
start = next;
} else if (count == 1) {
end = next;
break;
}
count -|= 1;
}
if (count > 1) return error.LineNotFound;
const found_line = file.data.?[start..end];
const formatted = if (found_line.len == 0)
" "
else if (Highlighting.Language.guessFromFilename(filename)) |lang| fmt: {
var pre = try Highlighting.highlight(a, lang, found_line[1..]);
break :fmt pre[28..][0 .. pre.len - 41];
} else try Bleach.sanitizeAlloc(a, found_line[1..], .{});
 
const wrapped_line = try allocPrint(
a,
"<div title=\"{s}\" class=\"coderef\">{s}</div>",
.{ try Bleach.sanitizeAlloc(a, line, .{}), formatted },
);
try found_lines.append(wrapped_line);
return try found_lines.toOwnedSlice();
}
 
fn resolveLineRefDiff(
a: Allocator,
line: []const u8,
filename: []const u8,
diff: *Patch.Diff,
h: usize,
line_number: u32,
fpos: usize,
) !?[][]const u8 {
const side: ?Side = if (fpos > 0)
@@ -413,18 +481,14 @@ fn resolveLineRef(
else
null;
var found_lines = std.ArrayList([]const u8).init(a);
var search_end = h + 2;
while (search_end < line.len and std.ascii.isDigit(line[search_end])) search_end += 1;
 
const search = try parseInt(u32, line[h + 1 .. search_end], 10);
const blocks = try diff.blocksAlloc(a);
for (blocks) |block| {
const change = try parseBlockHeader(block);
const in_left = search >= change.left.start and search <= change.left.start + change.left.change;
const in_right = search >= change.right.start and search <= change.right.start + change.right.change;
const in_left = line_number >= change.left.start and line_number <= change.left.start + change.left.change;
const in_right = line_number >= change.right.start and line_number <= change.right.start + change.right.change;
if (in_left or in_right) {
const sided: bool = if (side) |s| if (s == .add) true else false else true;
if (try getLineAt(block, search, 1, sided)) |found_line| {
if (try getLineAt(block, line_number, 1, sided)) |found_line| {
const color = switch (found_line[0]) {
'+' => "green",
'-' => "red",
@@ -444,9 +508,6 @@ fn resolveLineRef(
.{ try Bleach.sanitizeAlloc(a, line, .{}), color, formatted },
);
try found_lines.append(wrapped_line);
if (search_end < line.len) try found_lines.append(
try Bleach.sanitizeAlloc(a, line[search_end..], .{}),
);
}
break;
}
@@ -455,7 +516,7 @@ fn resolveLineRef(
}
 
const Side = enum { del, add };
fn translateComment(a: Allocator, comment: []const u8, patch: Patch) ![]u8 {
fn translateComment(a: Allocator, comment: []const u8, patch: Patch, repo: *const Git.Repo) ![]u8 {
var message_lines = std.ArrayList([]const u8).init(a);
defer message_lines.clearAndFree();
 
@@ -468,7 +529,17 @@ fn translateComment(a: Allocator, comment: []const u8, patch: Patch) ![]u8 {
//std.debug.print("files {s}\n", .{filename});
if (indexOf(u8, line, filename)) |filepos| {
if (indexOfAny(u8, line, "#:@")) |h| {
if (try resolveLineRef(a, line, filename, diff, h, filepos)) |lines| {
var search_end = h + 2;
while (search_end < line.len and std.ascii.isDigit(line[search_end])) search_end += 1;
 
const search = try parseInt(u32, line[h + 1 .. search_end], 10);
 
if (try resolveLineRefDiff(a, line, filename, diff, search, filepos)) |lines| {
try message_lines.appendSlice(lines);
if (search_end < line.len) try message_lines.append(
try Bleach.sanitizeAlloc(a, line[search_end..], .{}),
);
} else if (try resolveLineRefRepo(a, line, filename, repo, search)) |lines| {
try message_lines.appendSlice(lines);
} else {
try message_lines.append(try allocPrint(
@@ -492,6 +563,14 @@ const DiffViewPage = Template.PageData("delta-diff.html");
 
fn view(ctx: *Context) Error!void {
const rd = Repos.RouteData.make(&ctx.uri) orelse return error.Unrouteable;
 
var cwd = std.fs.cwd();
const filename = try allocPrint(ctx.alloc, "./repos/{s}", .{rd.name});
const dir = cwd.openDir(filename, .{}) catch return error.Unknown;
var repo = Git.Repo.init(dir) catch return error.Unknown;
repo.loadData(ctx.alloc) catch return error.Unknown;
defer repo.raze();
 
const delta_id = ctx.uri.next().?;
const index = isHex(delta_id) orelse return error.Unrouteable;
 
@@ -537,12 +616,6 @@ fn view(ctx: *Context) Error!void {
}
f.close();
 
var cwd = std.fs.cwd();
const filename = try allocPrint(ctx.alloc, "./repos/{s}", .{rd.name});
const dir = cwd.openDir(filename, .{}) catch return error.Unknown;
var repo = Git.Repo.init(dir) catch return error.Unknown;
repo.loadData(ctx.alloc) catch return error.Unknown;
defer repo.raze();
var agent = repo.getAgent(ctx.alloc);
const applies = agent.checkPatch(fdata) catch |err| apl: {
std.debug.print("git apply failed {any}\n", .{err});
@@ -560,7 +633,7 @@ fn view(ctx: *Context) Error!void {
c_ctx.* = .{
.author = try Bleach.sanitizeAlloc(ctx.alloc, comment.author, .{}),
.date = try allocPrint(ctx.alloc, "{}", .{Humanize.unix(comment.updated)}),
.message = translateComment(ctx.alloc, comment.message, patch) catch unreachable,
.message = translateComment(ctx.alloc, comment.message, patch, &repo) catch unreachable,
.direct_reply = .{ .uri = try allocPrint(ctx.alloc, "{}/direct_reply/{x}", .{ index, fmtSliceHexLower(comment.hash[0..]) }) },
.sub_thread = null,
};
 
src/types/comment.zig added: 104, removed: 31, total 73
@@ -291,7 +291,7 @@ test Comment {
var c = try Comment.new("author", "message");
 
// LOL, you thought
const mask: i64 = ~@as(i64, 0xfffff);
const mask: i64 = ~@as(i64, 0xffffff);
c.created = std.time.timestamp() & mask;
c.updated = std.time.timestamp() & mask;
 
@@ -303,7 +303,7 @@ test Comment {
const v0: Comment = undefined;
const v0_bin: []const u8 = &[_]u8{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x30, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x67, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x75, 0x74,
0x68, 0x6F, 0x72, 0x00, 0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
};
@@ -315,7 +315,7 @@ test Comment {
 
const v1_bin: []const u8 = &[_]u8{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x30, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x67, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x75, 0x74,
0x68, 0x6F, 0x72, 0x00, 0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
};
 
src/types/delta.zig added: 104, removed: 31, total 73
@@ -419,7 +419,7 @@ test Delta {
var d = try Delta.new("repo_name", "title", "message", "author");
 
// LOL, you thought
const mask: i64 = ~@as(i64, 0xfffff);
const mask: i64 = ~@as(i64, 0xffffff);
d.created = std.time.timestamp() & mask;
d.updated = std.time.timestamp() & mask;
 
@@ -438,7 +438,7 @@ test Delta {
 
const v1_bin: []const u8 = &[_]u8{
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x30, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x67, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x00,
0x72, 0x65, 0x70, 0x6F, 0x5F, 0x6E, 0x61, 0x6D, 0x65, 0x00, 0x74, 0x69, 0x74, 0x6C, 0x65, 0x00,
0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x00, 0x61, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
static/main.css added: 104, removed: 31, total 73
@@ -607,6 +607,7 @@ comment {
border-right: 1px solid #737373;
margin: 0 10px;
padding: 2px 15px;
background: #333;
&.red {
background: #433;
}
@@ -614,7 +615,6 @@ comment {
background: #343;
}
&.yellow {
 
background: #333;
}
}