srctree

Gregory Mullen parent 90b69b2a 3c75d87c
move all endpoints to use Context over response

html is probably broken again... I should write tests for that
src/context.zig added: 413, removed: 445, total 0
@@ -10,6 +10,7 @@ const zWSGIRequest = zWSGI.zWSGIRequest;
pub const Request = @import("request.zig");
pub const Response = @import("response.zig");
pub const UserData = @import("user-data.zig").UserData;
pub const Template = @import("template.zig").Template;
pub const UriIter = @import("endpoint.zig").Router.UriIter;
 
pub const Context = @This();
@@ -33,3 +34,10 @@ pub fn init(a: Allocator, req: Request, res: Response, usr_data: UserData) !Cont
.auth = Auth.init(req.headers),
};
}
 
pub fn sendTemplate(ctx: *Context, t: *Template) !void {
try ctx.response.start();
const page = try t.buildFor(ctx.alloc, ctx);
try ctx.response.send(page);
try ctx.response.finish();
}
 
src/endpoint.zig added: 413, removed: 445, total 0
@@ -2,14 +2,13 @@ const std = @import("std");
 
pub const HTML = @import("html.zig");
pub const DOM = @import("dom.zig");
pub const Response = @import("response.zig");
pub const Request = @import("request.zig");
pub const Context = @import("context.zig");
//pub const Response = @import("response.zig");
//pub const Request = @import("request.zig");
pub const Template = @import("template.zig");
pub const Router = @import("routes.zig");
pub const Types = @import("types.zig");
 
pub const UriIter = Router.UriIter;
 
pub const Error = ServerError || ClientError;
 
pub const ServerError = error{
@@ -31,8 +30,6 @@ pub const ClientError = error{
 
pub const router = Router.router;
 
pub const Endpoint = *const fn (*Response, *Router.UriIter) Error!void;
 
pub const commitFlex = @import("endpoints/commit-flex.zig").commitFlex;
 
pub const TODO = @import("endpoints/todo.zig");
 
src/endpoints/admin.zig added: 413, removed: 445, total 0
@@ -39,9 +39,9 @@ fn createRepo(a: Allocator, reponame: []const u8) !void {
_ = try actions.gitInit(dir, .{});
}
 
fn default(r: *Response, _: *UriIter) Error!void {
try r.request.auth.validOnly();
var dom = DOM.new(r.alloc);
fn default(ctx: *Context) Error!void {
try ctx.response.request.auth.validOnly();
var dom = DOM.new(ctx.alloc);
const action = "/admin/post";
dom = dom.open(HTML.form(null, &[_]HTML.Attr{
HTML.Attr{ .key = "method", .value = "POST" },
@@ -58,17 +58,17 @@ fn default(r: *Response, _: *UriIter) Error!void {
var form = dom.done();
 
var tmpl = Template.find("admin.html");
tmpl.init(r.alloc);
_ = tmpl.addElements(r.alloc, "form", form) catch unreachable;
var page = tmpl.buildFor(r.alloc, r) catch unreachable;
r.start() catch return Error.Unknown;
r.send(page) catch return Error.Unknown;
r.finish() catch return Error.Unknown;
tmpl.init(ctx.alloc);
_ = tmpl.addElements(ctx.alloc, "form", form) catch unreachable;
var page = tmpl.buildFor(ctx.alloc, ctx) catch unreachable;
ctx.response.start() catch return Error.Unknown;
ctx.response.send(page) catch return Error.Unknown;
ctx.response.finish() catch return Error.Unknown;
}
 
fn cloneUpstream(r: *Response, _: *UriIter) Error!void {
try r.request.auth.validOnly();
var dom = DOM.new(r.alloc);
fn cloneUpstream(ctx: *Context) Error!void {
try ctx.response.request.auth.validOnly();
var dom = DOM.new(ctx.alloc);
const action = "/admin/clone-upstream";
dom = dom.open(HTML.form(null, &[_]HTML.Attr{
HTML.Attr{ .key = "method", .value = "POST" },
@@ -82,18 +82,18 @@ fn cloneUpstream(r: *Response, _: *UriIter) Error!void {
var form = dom.done();
 
var tmpl = Template.find("admin.html");
tmpl.init(r.alloc);
_ = tmpl.addElements(r.alloc, "form", form) catch unreachable;
var page = tmpl.buildFor(r.alloc, r) catch unreachable;
r.start() catch return Error.Unknown;
r.send(page) catch return Error.Unknown;
r.finish() catch return Error.Unknown;
tmpl.init(ctx.alloc);
_ = tmpl.addElements(ctx.alloc, "form", form) catch unreachable;
var page = tmpl.buildFor(ctx.alloc, ctx) catch unreachable;
ctx.response.start() catch return Error.Unknown;
ctx.response.send(page) catch return Error.Unknown;
ctx.response.finish() catch return Error.Unknown;
}
 
fn postCloneUpstream(r: *Response, _: *UriIter) Error!void {
try r.request.auth.validOnly();
fn postCloneUpstream(ctx: *Context) Error!void {
try ctx.response.request.auth.validOnly();
 
var valid = r.usr_data.?.post_data.?.validator();
var valid = ctx.response.usr_data.?.post_data.?.validator();
const ruri = valid.require("repo uri") catch return error.Unknown;
std.debug.print("repo uri {s}\n", .{ruri.value});
var nameitr = std.mem.splitBackwards(u8, ruri.value, "/");
@@ -102,14 +102,14 @@ fn postCloneUpstream(r: *Response, _: *UriIter) Error!void {
 
var dir = std.fs.cwd().openDir("repos", .{}) catch return error.Unknown;
var act = git.Actions{
.alloc = r.alloc,
.alloc = ctx.alloc,
.cwd = dir,
};
std.debug.print("fork bare {s}\n", .{
act.forkRemote(ruri.value, name) catch return error.Unknown,
});
 
var dom = DOM.new(r.alloc);
var dom = DOM.new(ctx.alloc);
const action = "/admin/clone-upstream";
dom = dom.open(HTML.form(null, &[_]HTML.Attr{
HTML.Attr{ .key = "method", .value = "POST" },
@@ -123,18 +123,18 @@ fn postCloneUpstream(r: *Response, _: *UriIter) Error!void {
var form = dom.done();
 
var tmpl = Template.find("admin.html");
tmpl.init(r.alloc);
_ = tmpl.addElements(r.alloc, "form", form) catch unreachable;
var page = tmpl.buildFor(r.alloc, r) catch unreachable;
r.start() catch return Error.Unknown;
r.send(page) catch return Error.Unknown;
r.finish() catch return Error.Unknown;
tmpl.init(ctx.alloc);
_ = tmpl.addElements(ctx.alloc, "form", form) catch unreachable;
var page = tmpl.buildFor(ctx.alloc, ctx) catch unreachable;
ctx.response.start() catch return Error.Unknown;
ctx.response.send(page) catch return Error.Unknown;
ctx.response.finish() catch return Error.Unknown;
}
 
fn postNewRepo(r: *Response, _: *UriIter) Error!void {
try r.request.auth.validOnly();
fn postNewRepo(ctx: *Context) Error!void {
try ctx.request.auth.validOnly();
// TODO ini repo dir
var valid = if (r.usr_data) |usr|
var valid = if (ctx.response.usr_data) |usr|
if (usr.post_data) |p|
p.validator()
else
@@ -155,11 +155,11 @@ fn postNewRepo(r: *Response, _: *UriIter) Error!void {
 
if (std.fs.cwd().openDir(dir_name, .{})) |_| return error.Unknown else |_| {}
 
var new_repo = git.Repo.createNew(r.alloc, std.fs.cwd(), dir_name) catch return error.Unknown;
var new_repo = git.Repo.createNew(ctx.alloc, std.fs.cwd(), dir_name) catch return error.Unknown;
 
std.debug.print("creating {any}\n", .{new_repo});
 
var dom = DOM.new(r.alloc);
var dom = DOM.new(ctx.alloc);
const action = "/admin/new-repo";
dom = dom.open(HTML.form(null, &[_]HTML.Attr{
HTML.Attr{ .key = "method", .value = "POST" },
@@ -173,17 +173,17 @@ fn postNewRepo(r: *Response, _: *UriIter) Error!void {
var form = dom.done();
 
var tmpl = Template.find("admin.html");
tmpl.init(r.alloc);
_ = tmpl.addElements(r.alloc, "form", form) catch unreachable;
var page = tmpl.buildFor(r.alloc, r) catch unreachable;
r.start() catch return Error.Unknown;
r.send(page) catch return Error.Unknown;
r.finish() catch return Error.Unknown;
tmpl.init(ctx.alloc);
_ = tmpl.addElements(ctx.alloc, "form", form) catch unreachable;
var page = tmpl.buildFor(ctx.alloc, ctx) catch unreachable;
ctx.response.start() catch return Error.Unknown;
ctx.response.send(page) catch return Error.Unknown;
ctx.response.finish() catch return Error.Unknown;
}
 
fn newRepo(r: *Response, _: *UriIter) Error!void {
try r.request.auth.validOnly();
var dom = DOM.new(r.alloc);
fn newRepo(ctx: *Context) Error!void {
try ctx.request.auth.validOnly();
var dom = DOM.new(ctx.alloc);
const action = "/admin/new-repo";
dom = dom.open(HTML.form(null, &[_]HTML.Attr{
HTML.Attr{ .key = "method", .value = "POST" },
@@ -199,19 +199,19 @@ fn newRepo(r: *Response, _: *UriIter) Error!void {
var form = dom.done();
 
var tmpl = Template.find("admin.html");
tmpl.init(r.alloc);
_ = tmpl.addElements(r.alloc, "form", form) catch unreachable;
var page = tmpl.buildFor(r.alloc, r) catch unreachable;
r.start() catch return Error.Unknown;
r.send(page) catch return Error.Unknown;
r.finish() catch return Error.Unknown;
tmpl.init(ctx.alloc);
_ = tmpl.addElements(ctx.alloc, "form", form) catch unreachable;
var page = tmpl.buildFor(ctx.alloc, ctx) catch unreachable;
ctx.response.start() catch return Error.Unknown;
ctx.response.send(page) catch return Error.Unknown;
ctx.response.finish() catch return Error.Unknown;
}
 
fn view(r: *Response, uri: *UriIter) Error!void {
try r.request.auth.validOnly();
if (r.usr_data) |usr| if (usr.post_data) |pd| {
fn view(ctx: *Context) Error!void {
try ctx.request.auth.validOnly();
if (ctx.response.usr_data) |usr| if (usr.post_data) |pd| {
std.debug.print("{any}\n", .{pd.items});
return newRepo(r, uri);
return newRepo(ctx);
};
return default(r, uri);
return default(ctx);
}
 
src/endpoints/commit-flex.zig added: 413, removed: 445, total 0
@@ -9,7 +9,7 @@ const Ini = @import("../ini.zig");
 
const DOM = Endpoint.DOM;
const HTML = Endpoint.HTML;
const Response = Endpoint.Response;
const Context = Endpoint.Context;
const Template = Endpoint.Template;
 
const Error = Endpoint.Error;
@@ -72,7 +72,7 @@ fn findCommits(a: Allocator, until: i64, gitdir: []const u8) !*HeatMapArray {
const YEAR = 31_536_000;
const DAY = 60 * 60 * 24;
 
pub fn commitFlex(r: *Response, _: *Endpoint.Router.UriIter) Error!void {
pub fn commitFlex(ctx: *Context) Error!void {
const day = HTML.Attr.class("day");
const monthAtt = HTML.Attr.class("month");
 
@@ -87,8 +87,8 @@ pub fn commitFlex(r: *Response, _: *Endpoint.Router.UriIter) Error!void {
var repo_count: usize = 0;
var cwd = std.fs.cwd();
if (cwd.openIterableDir("./repos", .{})) |idir| {
reset_hits(r.alloc);
if (Ini.default(r.alloc)) |ini| {
reset_hits(ctx.alloc);
if (Ini.default(ctx.alloc)) |ini| {
if (ini.get("owner")) |ns| {
if (ns.get("email")) |email| {
owner_email = email;
@@ -108,7 +108,7 @@ pub fn commitFlex(r: *Response, _: *Endpoint.Router.UriIter) Error!void {
switch (file.kind) {
.directory, .sym_link => {
var name = std.fmt.bufPrint(&buf, "./repos/{s}", .{file.name}) catch return Error.Unknown;
_ = findCommits(r.alloc, until, name) catch unreachable;
_ = findCommits(ctx.alloc, until, name) catch unreachable;
repo_count +|= 1;
},
else => {},
@@ -116,7 +116,7 @@ pub fn commitFlex(r: *Response, _: *Endpoint.Router.UriIter) Error!void {
}
} else |_| unreachable;
 
var dom = DOM.new(r.alloc);
var dom = DOM.new(ctx.alloc);
var tcount: u16 = 0;
for (hits) |h| tcount +|= h;
var hit_total_buf: [0x40]u8 = undefined;
@@ -143,7 +143,7 @@ pub fn commitFlex(r: *Response, _: *Endpoint.Router.UriIter) Error!void {
var month_i: usize = date.months - 2;
var day_off: usize = 0;
for (0..53) |_| {
var month: []HTML.Element = try r.alloc.alloc(HTML.Element, 8);
var month: []HTML.Element = try ctx.alloc.alloc(HTML.Element, 8);
if ((month_i % 12) != date.months - 1) {
month_i += 1;
month[0] = HTML.div(DateTime.MONTHS[month_i % 12 + 1][0..3], &monthAtt);
@@ -154,7 +154,7 @@ pub fn commitFlex(r: *Response, _: *Endpoint.Router.UriIter) Error!void {
for (month[1..]) |*m| {
defer date = DateTime.fromEpoch(date.timestamp + DAY) catch unreachable;
defer day_off += 1;
var rows = try r.alloc.alloc(HTML.Attribute, 2);
var rows = try ctx.alloc.alloc(HTML.Attribute, 2);
const class = if (date.timestamp >= nowish.timestamp)
"day-hide"
else switch (16 - @clz(hits[day_off])) {
@@ -171,7 +171,7 @@ pub fn commitFlex(r: *Response, _: *Endpoint.Router.UriIter) Error!void {
HTML.Attr{
.key = "title",
.value = try std.fmt.allocPrint(
r.alloc,
ctx.alloc,
"{} commits on {}",
.{ hits[day_off], date },
),
@@ -186,12 +186,8 @@ pub fn commitFlex(r: *Response, _: *Endpoint.Router.UriIter) Error!void {
const flex = dom.done();
 
var tmpl = Template.find("user_commits.html");
tmpl.init(r.alloc);
tmpl.init(ctx.alloc);
 
_ = tmpl.addElements(r.alloc, "flexes", flex) catch return Error.Unknown;
var page = tmpl.buildFor(r.alloc, r) catch unreachable;
 
r.start() catch return Error.Unknown;
r.send(page) catch return Error.Unknown;
r.finish() catch return Error.Unknown;
_ = tmpl.addElements(ctx.alloc, "flexes", flex) catch return Error.Unknown;
return ctx.sendTemplate(&tmpl) catch unreachable;
}
 
src/endpoints/network.zig added: 413, removed: 445, total 0
@@ -2,7 +2,7 @@ const std = @import("std");
 
const DOM = Endpoint.DOM;
const Endpoint = @import("../endpoint.zig");
const Response = Endpoint.Response;
const Context = Endpoint.Context;
const Template = Endpoint.Template;
const Error = Endpoint.Error;
const UriIter = Endpoint.Router.UriIter;
@@ -18,10 +18,10 @@ pub const endpoints = [_]Endpoint.Router.MatchRouter{
.{ .name = "", .methods = GET, .match = .{ .call = default } },
};
 
fn default(r: *Response, _: *UriIter) Error!void {
var dom = DOM.new(r.alloc);
fn default(ctx: *Context) Error!void {
var dom = DOM.new(ctx.alloc);
 
const list = try Repos.allNames(r.alloc);
const list = try Repos.allNames(ctx.alloc);
const cwd = std.fs.cwd();
for (list) |reponame| {
var b: [0x800]u8 = undefined;
@@ -30,13 +30,13 @@ fn default(r: *Response, _: *UriIter) Error!void {
defer rdir.close();
const cffd = rdir.openFile("config", .{}) catch rdir.openFile(".git/config", .{}) catch continue;
defer cffd.close();
const conf = Ini.init(r.alloc, cffd) catch unreachable;
const conf = Ini.init(ctx.alloc, cffd) catch unreachable;
if (conf.get("remote \"upstream\"")) |ns| {
if (ns.get("url")) |url| {
var purl = try Repos.parseGitRemoteUrl(r.alloc, url);
var purl = try Repos.parseGitRemoteUrl(ctx.alloc, url);
dom = dom.open(HTML.h3(null, &HTML.Attr.class("upstream")));
dom.push(HTML.text("Upstream: "));
dom.push(HTML.anch(purl, try HTML.Attr.create(r.alloc, "href", purl)));
dom.push(HTML.anch(purl, try HTML.Attr.create(ctx.alloc, "href", purl)));
dom = dom.close();
}
}
@@ -45,10 +45,10 @@ fn default(r: *Response, _: *UriIter) Error!void {
var data = dom.done();
 
var tmpl = Template.find("network.html");
tmpl.init(r.alloc);
_ = tmpl.addElements(r.alloc, "netlist", data) catch unreachable;
var page = tmpl.buildFor(r.alloc, r) catch unreachable;
r.start() catch return Error.Unknown;
r.send(page) catch return Error.Unknown;
r.finish() catch return Error.Unknown;
tmpl.init(ctx.alloc);
_ = tmpl.addElements(ctx.alloc, "netlist", data) catch unreachable;
var page = tmpl.buildFor(ctx.alloc, ctx) catch unreachable;
ctx.response.start() catch return Error.Unknown;
ctx.response.send(page) catch return Error.Unknown;
ctx.response.finish() catch return Error.Unknown;
}
 
src/endpoints/repos.zig added: 413, removed: 445, total 0
@@ -79,7 +79,7 @@ pub const RouteData = struct {
}
};
 
pub fn router(ctx: *Context) Error!Endpoint.Endpoint {
pub fn router(ctx: *Context) Error!Endpoint.Router.Endpoint {
const rd = RouteData.make(&ctx.uri) orelse return list;
 
if (rd.exists()) {
@@ -164,36 +164,36 @@ fn htmlRepoBlock(a: Allocator, pre_dom: *DOM, name: []const u8, repo: git.Repo)
return dom.close();
}
 
fn list(r: *Response, _: *UriIter) Error!void {
fn list(ctx: *Context) Error!void {
var cwd = std.fs.cwd();
if (cwd.openIterableDir("./repos", .{})) |idir| {
var repos = std.ArrayList(git.Repo).init(r.alloc);
var repos = std.ArrayList(git.Repo).init(ctx.alloc);
var itr = idir.iterate();
while (itr.next() catch return Error.Unknown) |file| {
if (file.kind != .directory and file.kind != .sym_link) continue;
if (file.name[0] == '.') continue;
var rdir = idir.dir.openDir(file.name, .{}) catch continue;
var rpo = git.Repo.init(rdir) catch continue;
rpo.loadData(r.alloc) catch return error.Unknown;
rpo.repo_name = r.alloc.dupe(u8, file.name) catch null;
rpo.loadData(ctx.alloc) catch return error.Unknown;
rpo.repo_name = ctx.alloc.dupe(u8, file.name) catch null;
try repos.append(rpo);
}
std.sort.heap(git.Repo, repos.items, repoctx{ .alloc = r.alloc }, repoSorterNew);
std.sort.heap(git.Repo, repos.items, repoctx{ .alloc = ctx.alloc }, repoSorterNew);
 
var dom = DOM.new(r.alloc);
var dom = DOM.new(ctx.alloc);
 
if (r.request.auth.valid()) {
if (ctx.response.request.auth.valid()) {
dom = dom.open(HTML.div(null, &HTML.Attr.class("act-btns")));
dom.dupe(try HTML.linkBtnAlloc(r.alloc, "New Upstream", "/admin/clone-upstream"));
dom.dupe(try HTML.linkBtnAlloc(ctx.alloc, "New Upstream", "/admin/clone-upstream"));
dom = dom.close();
}
 
dom = dom.open(HTML.element("repos", null, null));
 
for (repos.items) |*repo| {
defer repo.raze(r.alloc);
defer repo.raze(ctx.alloc);
dom = htmlRepoBlock(
r.alloc,
ctx.alloc,
dom,
repo.repo_name orelse "unknown",
repo.*,
@@ -202,13 +202,13 @@ fn list(r: *Response, _: *UriIter) Error!void {
dom = dom.close();
var data = dom.done();
var tmpl = Template.find("repos.html");
tmpl.init(r.alloc);
_ = tmpl.addElements(r.alloc, "repos", data) catch return Error.Unknown;
tmpl.init(ctx.alloc);
_ = tmpl.addElements(ctx.alloc, "repos", data) catch return Error.Unknown;
 
var page = tmpl.buildFor(r.alloc, r) catch unreachable;
r.start() catch return Error.Unknown;
r.send(page) catch return Error.Unknown;
r.finish() catch return Error.Unknown;
var page = tmpl.buildFor(ctx.alloc, ctx) catch unreachable;
ctx.response.start() catch return Error.Unknown;
ctx.response.send(page) catch return Error.Unknown;
ctx.response.finish() catch return Error.Unknown;
} else |err| {
std.debug.print("unable to open given dir {}\n", .{err});
return;
@@ -222,69 +222,69 @@ fn dupeDir(a: Allocator, name: []const u8) ![]u8 {
return out;
}
 
fn newRepo(r: *Response, _: *UriIter) Error!void {
fn newRepo(ctx: *Context) Error!void {
var tmpl = Template.find("repo.html");
tmpl.init(r.alloc);
tmpl.init(ctx.alloc);
 
tmpl.addVar("files", "<h3>New Repo!</h3><p>Todo, add content here</p>") catch return error.Unknown;
var page = tmpl.buildFor(r.alloc, r) catch unreachable;
var page = tmpl.buildFor(ctx.alloc, ctx) catch unreachable;
 
r.status = .ok;
r.start() catch return Error.Unknown;
r.send(page) catch return Error.Unknown;
r.finish() catch return Error.Unknown;
ctx.response.status = .ok;
ctx.response.start() catch return Error.Unknown;
ctx.response.send(page) catch return Error.Unknown;
ctx.response.finish() catch return Error.Unknown;
}
 
fn treeBlob(r: *Response, uri: *UriIter) Error!void {
const rd = RouteData.make(uri) orelse return error.Unrouteable;
_ = uri.next();
fn treeBlob(ctx: *Context) Error!void {
const rd = RouteData.make(&ctx.uri) orelse return error.Unrouteable;
_ = ctx.uri.next();
 
var cwd = std.fs.cwd();
var filename = try aPrint(r.alloc, "./repos/{s}", .{rd.name});
var filename = try aPrint(ctx.alloc, "./repos/{s}", .{rd.name});
var dir = cwd.openDir(filename, .{}) catch return error.Unknown;
var repo = git.Repo.init(dir) catch return error.Unknown;
repo.loadData(r.alloc) catch return error.Unknown;
repo.loadData(ctx.alloc) catch return error.Unknown;
 
const cmt = repo.commit(r.alloc) catch return newRepo(r, uri);
var files: git.Tree = cmt.mkTree(r.alloc) catch return error.Unknown;
const cmt = repo.commit(ctx.alloc) catch return newRepo(ctx);
var files: git.Tree = cmt.mkTree(ctx.alloc) catch return error.Unknown;
if (rd.verb) |blb| {
if (std.mem.eql(u8, blb, "blob")) {
return blob(r, uri, &repo, files);
return blob(ctx, &repo, files);
} else if (std.mem.eql(u8, blb, "tree")) {
files = mkTree(r.alloc, repo, uri, files) catch return error.Unknown;
return tree(r, uri, &repo, &files);
files = mkTree(ctx.alloc, repo, &ctx.uri, files) catch return error.Unknown;
return tree(ctx, &repo, &files);
} else return error.InvalidURI;
} else files = cmt.mkTree(r.alloc) catch return error.Unknown;
return tree(r, uri, &repo, &files);
} else files = cmt.mkTree(ctx.alloc) catch return error.Unknown;
return tree(ctx, &repo, &files);
}
 
fn blob(r: *Response, uri: *UriIter, repo: *git.Repo, pfiles: git.Tree) Error!void {
fn blob(ctx: *Context, repo: *git.Repo, pfiles: git.Tree) Error!void {
var tmpl = Template.find("blob.html");
tmpl.init(r.alloc);
tmpl.init(ctx.alloc);
 
var blb: git.Blob = undefined;
 
var files = pfiles;
search: while (uri.next()) |bname| {
search: while (ctx.uri.next()) |bname| {
for (files.objects) |obj| {
if (std.mem.eql(u8, bname, obj.name)) {
blb = obj;
if (obj.isFile()) {
if (uri.next()) |_| return error.InvalidURI;
if (ctx.uri.next()) |_| return error.InvalidURI;
break :search;
}
files = git.Tree.fromRepo(r.alloc, repo.*, &obj.hash) catch return error.Unknown;
files = git.Tree.fromRepo(ctx.alloc, repo.*, &obj.hash) catch return error.Unknown;
continue :search;
}
} else return error.InvalidURI;
}
 
var dom = DOM.new(r.alloc);
var dom = DOM.new(ctx.alloc);
 
var resolve = repo.blob(r.alloc, &blb.hash) catch return error.Unknown;
var resolve = repo.blob(ctx.alloc, &blb.hash) catch return error.Unknown;
var reader = resolve.reader();
 
var d2 = reader.readAllAlloc(r.alloc, 0xffffff) catch unreachable;
var d2 = reader.readAllAlloc(ctx.alloc, 0xffffff) catch unreachable;
const count = std.mem.count(u8, d2, "\n");
dom = dom.open(HTML.element("code", null, null));
var litr = std.mem.split(u8, d2, "\n");
@@ -292,7 +292,7 @@ fn blob(r: *Response, uri: *UriIter, repo: *git.Repo, pfiles: git.Tree) Error!vo
for (0..count + 1) |i| {
var buf: [12]u8 = undefined;
const b = std.fmt.bufPrint(&buf, "#L{}", .{i + 1}) catch unreachable;
const attrs = try HTML.Attribute.alloc(r.alloc, &[_][]const u8{
const attrs = try HTML.Attribute.alloc(ctx.alloc, &[_][]const u8{
"num",
"id",
"href",
@@ -302,7 +302,7 @@ fn blob(r: *Response, uri: *UriIter, repo: *git.Repo, pfiles: git.Tree) Error!vo
b,
});
const dirty = litr.next().?;
var clean = try r.alloc.alloc(u8, dirty.len * 2);
var clean = try ctx.alloc.alloc(u8, dirty.len * 2);
clean = Bleach.sanitize(dirty, clean, .{}) catch return error.Unknown;
dom.push(HTML.element("ln", clean, attrs));
}
@@ -310,17 +310,17 @@ fn blob(r: *Response, uri: *UriIter, repo: *git.Repo, pfiles: git.Tree) Error!vo
dom = dom.close();
var data = dom.done();
const filestr = try aPrint(
r.alloc,
ctx.alloc,
"{pretty}",
.{HTML.div(data, &HTML.Attr.class("code-block"))},
);
tmpl.addVar("files", filestr) catch return error.Unknown;
var page = tmpl.buildFor(r.alloc, r) catch unreachable;
var page = tmpl.buildFor(ctx.alloc, ctx) catch unreachable;
 
r.status = .ok;
r.start() catch return Error.Unknown;
r.send(page) catch return Error.Unknown;
r.finish() catch return Error.Unknown;
ctx.response.status = .ok;
ctx.response.start() catch return Error.Unknown;
ctx.response.send(page) catch return Error.Unknown;
ctx.response.finish() catch return Error.Unknown;
}
 
fn mkTree(a: Allocator, repo: git.Repo, uri: *UriIter, pfiles: git.Tree) !git.Tree {
@@ -358,9 +358,9 @@ fn isReadme(name: []const u8) bool {
return false;
}
 
fn tree(r: *Response, uri: *UriIter, repo: *git.Repo, files: *git.Tree) Error!void {
fn tree(ctx: *Context, repo: *git.Repo, files: *git.Tree) Error!void {
var tmpl = Template.find("repo.html");
tmpl.init(r.alloc);
tmpl.init(ctx.alloc);
 
var head = if (repo.head) |h| switch (h) {
.sha => |s| s,
@@ -369,39 +369,39 @@ fn tree(r: *Response, uri: *UriIter, repo: *git.Repo, files: *git.Tree) Error!vo
} else "unknown";
tmpl.addVar("branch.default", head) catch return error.Unknown;
 
const rd = RouteData.make(uri) orelse return error.Unrouteable;
uri.reset();
_ = uri.next();
_ = uri.next();
_ = uri.next();
const file_uri_name = uri.rest();
const rd = RouteData.make(&ctx.uri) orelse return error.Unrouteable;
ctx.uri.reset();
_ = ctx.uri.next();
_ = ctx.uri.next();
_ = ctx.uri.next();
const file_uri_name = ctx.uri.rest();
 
//if (std.mem.eql(u8, repo_name, "srctree")) {
//var acts = repo.getActions(r.alloc);
//var acts = repo.getActions(ctx.alloc);
//acts.update() catch unreachable;
//}
 
var dom = DOM.new(r.alloc);
var dom = DOM.new(ctx.alloc);
 
dom = dom.open(HTML.div(null, &HTML.Attr.class("act-btns")));
const diff_link = try aPrint(r.alloc, "{s}/diffs/new", .{rd.name});
dom.push(try HTML.linkBtnAlloc(r.alloc, "Add Diff", diff_link));
const diff_link = try aPrint(ctx.alloc, "{s}/diffs/new", .{rd.name});
dom.push(try HTML.linkBtnAlloc(ctx.alloc, "Add Diff", diff_link));
dom = dom.close();
 
dom = dom.open(HTML.element("repo", null, &HTML.Attr.class("landing")));
 
dom = dom.open(HTML.element("intro", null, null));
dom.push(HTML.h3(rd.name, null));
const branches = try aPrint(r.alloc, "{} branches", .{repo.refs.len});
const branches = try aPrint(ctx.alloc, "{} branches", .{repo.refs.len});
dom.push(HTML.span(branches, null));
 
const c = repo.commit(r.alloc) catch return error.Unknown;
const c = repo.commit(ctx.alloc) catch return error.Unknown;
dom.push(HTML.span(c.message[0..@min(c.message.len, 58)], null));
const commit_time = try aPrint(r.alloc, " {}", .{Humanize.unix(c.committer.timestamp)});
const commit_time = try aPrint(ctx.alloc, " {}", .{Humanize.unix(c.committer.timestamp)});
dom = dom.open(HTML.span(null, &HTML.Attr.class("muted")));
const commit_href = try aPrint(r.alloc, "/repo/{s}/commit/{s}", .{ rd.name, c.sha[0..8] });
const commit_href = try aPrint(ctx.alloc, "/repo/{s}/commit/{s}", .{ rd.name, c.sha[0..8] });
dom.push(HTML.text(commit_time));
dom.push(try HTML.aHrefAlloc(r.alloc, c.sha[0..8], commit_href));
dom.push(try HTML.aHrefAlloc(ctx.alloc, c.sha[0..8], commit_href));
dom = dom.close();
dom = dom.close();
 
@@ -412,7 +412,7 @@ fn tree(r: *Response, uri: *UriIter, repo: *git.Repo, files: *git.Tree) Error!vo
const dd_href = &[_]HTML.Attribute{.{
.key = "href",
.value = try aPrint(
r.alloc,
ctx.alloc,
"/repo/{s}/tree/{s}",
.{ rd.name, file_uri_name[0..end] },
),
@@ -420,13 +420,13 @@ fn tree(r: *Response, uri: *UriIter, repo: *git.Repo, files: *git.Tree) Error!vo
dom.dupe(HTML.anch("..", dd_href));
dom = dom.close();
}
try files.pushPath(r.alloc, file_uri_name);
if (files.changedSet(r.alloc, repo)) |changed| {
try files.pushPath(ctx.alloc, file_uri_name);
if (files.changedSet(ctx.alloc, repo)) |changed| {
std.sort.pdq(git.Blob, files.objects, {}, typeSorter);
for (files.objects) |obj| {
var href = &[_]HTML.Attribute{.{
.key = "href",
.value = try aPrint(r.alloc, "/repo/{s}/{s}/{s}{s}{s}", .{
.value = try aPrint(ctx.alloc, "/repo/{s}/{s}/{s}{s}{s}", .{
rd.name,
if (obj.isFile()) "blob" else "tree",
file_uri_name,
@@ -439,7 +439,7 @@ fn tree(r: *Response, uri: *UriIter, repo: *git.Repo, files: *git.Tree) Error!vo
dom.dupe(HTML.anch(obj.name, href));
} else {
dom = dom.open(HTML.element("tree", null, null));
dom.dupe(HTML.anch(try dupeDir(r.alloc, obj.name), href));
dom.dupe(HTML.anch(try dupeDir(ctx.alloc, obj.name), href));
}
//HTML.element("file", link, null);
// I know... I KNOW!!!
@@ -450,7 +450,7 @@ fn tree(r: *Response, uri: *UriIter, repo: *git.Repo, files: *git.Tree) Error!vo
ch.commit[0..i]
else
ch.commit, null));
dom.dupe(HTML.span(try aPrint(r.alloc, "{}", .{Humanize.unix(ch.timestamp)}), null));
dom.dupe(HTML.span(try aPrint(ctx.alloc, "{}", .{Humanize.unix(ch.timestamp)}), null));
dom = dom.close();
break;
}
@@ -467,21 +467,21 @@ fn tree(r: *Response, uri: *UriIter, repo: *git.Repo, files: *git.Tree) Error!vo
 
dom = dom.close();
const data = dom.done();
_ = tmpl.addElements(r.alloc, "repo", data) catch return error.Unknown;
_ = tmpl.addElements(ctx.alloc, "repo", data) catch return error.Unknown;
 
for (files.objects) |obj| {
if (isReadme(obj.name)) {
var resolve = repo.blob(r.alloc, &obj.hash) catch return error.Unknown;
var resolve = repo.blob(ctx.alloc, &obj.hash) catch return error.Unknown;
var reader = resolve.reader();
const readme_txt = reader.readAllAlloc(r.alloc, 0xffffff) catch unreachable;
const readme = htmlReadme(r.alloc, readme_txt) catch unreachable;
_ = tmpl.addElementsFmt(r.alloc, "{pretty}", "readme", readme) catch return error.Unknown;
const readme_txt = reader.readAllAlloc(ctx.alloc, 0xffffff) catch unreachable;
const readme = htmlReadme(ctx.alloc, readme_txt) catch unreachable;
_ = tmpl.addElementsFmt(ctx.alloc, "{pretty}", "readme", readme) catch return error.Unknown;
break;
}
}
 
const diffurl = try std.fmt.allocPrint(r.alloc, "/repos/{s}/diffs/", .{rd.name});
const diffurl = try std.fmt.allocPrint(ctx.alloc, "/repos/{s}/diffs/", .{rd.name});
_ = tmpl.addString("diffurl", diffurl) catch return error.Unknown;
 
r.sendTemplate(&tmpl) catch return error.Unknown;
ctx.sendTemplate(&tmpl) catch return error.Unknown;
}
 
src/endpoints/repos/commits.zig added: 413, removed: 445, total 0
@@ -6,6 +6,7 @@ const Repos = @import("../repos.zig");
const Endpoint = @import("../../endpoint.zig");
 
const Response = Endpoint.Response;
const Context = Endpoint.Context;
const HTML = Endpoint.HTML;
const DOM = Endpoint.DOM;
const Template = Endpoint.Template;
@@ -17,77 +18,77 @@ const git = @import("../../git.zig");
const Bleach = @import("../../bleach.zig");
const Patch = @import("../../patch.zig");
 
fn commitHtml(r: *Response, sha: []const u8, repo_name: []const u8, repo: git.Repo) Error!void {
fn commitHtml(ctx: *Context, sha: []const u8, repo_name: []const u8, repo: git.Repo) Error!void {
var tmpl = Template.find("commit.html");
tmpl.init(r.alloc);
tmpl.init(ctx.alloc);
 
if (!git.commitish(sha)) {
std.debug.print("Abusive ''{s}''\n", .{sha});
return error.Abusive;
}
 
var dom = DOM.new(r.alloc);
var current: git.Commit = repo.commit(r.alloc) catch return error.Unknown;
var dom = DOM.new(ctx.alloc);
var current: git.Commit = repo.commit(ctx.alloc) catch return error.Unknown;
while (!std.mem.startsWith(u8, current.sha, sha)) {
current = current.toParent(r.alloc, 0) catch return error.Unknown;
current = current.toParent(ctx.alloc, 0) catch return error.Unknown;
}
dom.pushSlice(try htmlCommit(r.alloc, current, repo_name, true));
dom.pushSlice(try htmlCommit(ctx.alloc, current, repo_name, true));
 
var acts = repo.getActions(r.alloc);
var acts = repo.getActions(ctx.alloc);
var diff = acts.show(sha) catch return error.Unknown;
if (std.mem.indexOf(u8, diff, "diff")) |i| {
diff = diff[i..];
}
_ = tmpl.addElements(r.alloc, "commits", dom.done()) catch return error.Unknown;
_ = tmpl.addElements(ctx.alloc, "commits", dom.done()) catch return error.Unknown;
 
var diff_dom = DOM.new(r.alloc);
var diff_dom = DOM.new(ctx.alloc);
diff_dom = diff_dom.open(HTML.element("diff", null, null));
diff_dom = diff_dom.open(HTML.element("patch", null, null));
diff_dom.pushSlice(Patch.diffLine(r.alloc, diff));
diff_dom.pushSlice(Patch.diffLine(ctx.alloc, diff));
diff_dom = diff_dom.close();
diff_dom = diff_dom.close();
_ = tmpl.addElementsFmt(r.alloc, "{pretty}", "diff", diff_dom.done()) catch return error.Unknown;
_ = tmpl.addElementsFmt(ctx.alloc, "{pretty}", "diff", diff_dom.done()) catch return error.Unknown;
 
r.status = .ok;
return r.sendTemplate(&tmpl) catch unreachable;
ctx.response.status = .ok;
return ctx.sendTemplate(&tmpl) catch unreachable;
}
 
pub fn commitPatch(r: *Response, sha: []const u8, repo: git.Repo) Error!void {
var current: git.Commit = repo.commit(r.alloc) catch return error.Unknown;
var acts = repo.getActions(r.alloc);
pub fn commitPatch(ctx: *Context, sha: []const u8, repo: git.Repo) Error!void {
var current: git.Commit = repo.commit(ctx.alloc) catch return error.Unknown;
var acts = repo.getActions(ctx.alloc);
if (std.mem.indexOf(u8, sha, ".patch")) |tail| {
while (!std.mem.startsWith(u8, current.sha, sha[0..tail])) {
current = current.toParent(r.alloc, 0) catch return error.Unknown;
current = current.toParent(ctx.alloc, 0) catch return error.Unknown;
}
 
var diff = acts.show(sha[0..tail]) catch return error.Unknown;
if (std.mem.indexOf(u8, diff, "diff")) |i| {
diff = diff[i..];
}
r.status = .ok;
r.headersAdd("Content-Type", "text/x-patch") catch unreachable; // Firefox is trash
r.start() catch return Error.Unknown;
r.send(diff) catch return Error.Unknown;
r.finish() catch return Error.Unknown;
ctx.response.status = .ok;
ctx.response.headersAdd("Content-Type", "text/x-patch") catch unreachable; // Firefox is trash
ctx.response.start() catch return Error.Unknown;
ctx.response.send(diff) catch return Error.Unknown;
ctx.response.finish() catch return Error.Unknown;
}
}
 
pub fn commit(r: *Response, uri: *UriIter) Error!void {
const rd = RouteData.make(uri) orelse return error.Unrouteable;
if (rd.verb == null) return commits(r, uri);
pub fn commit(ctx: *Context) Error!void {
const rd = RouteData.make(&ctx.uri) orelse return error.Unrouteable;
if (rd.verb == null) return commits(ctx);
 
const sha = rd.noun orelse return error.Unrouteable;
var cwd = std.fs.cwd();
// FIXME user data flows into system
var filename = try std.fmt.allocPrint(r.alloc, "./repos/{s}", .{rd.name});
var filename = try std.fmt.allocPrint(ctx.alloc, "./repos/{s}", .{rd.name});
var dir = cwd.openDir(filename, .{}) catch return error.Unknown;
var repo = git.Repo.init(dir) catch return error.Unknown;
repo.loadData(r.alloc) catch return error.Unknown;
repo.loadData(ctx.alloc) catch return error.Unknown;
 
if (std.mem.endsWith(u8, sha, ".patch"))
return commitPatch(r, sha, repo)
return commitPatch(ctx, sha, repo)
else
return commitHtml(r, sha, rd.name, repo);
return commitHtml(ctx, sha, rd.name, repo);
return error.Unrouteable;
}
 
@@ -130,37 +131,37 @@ pub fn htmlCommit(a: Allocator, c: git.Commit, repo: []const u8, comptime top: b
return dom.done();
}
 
pub fn commits(r: *Response, uri: *UriIter) Error!void {
const rd = RouteData.make(uri) orelse return error.Unrouteable;
pub fn commits(ctx: *Context) Error!void {
const rd = RouteData.make(&ctx.uri) orelse return error.Unrouteable;
 
var filename = try std.fmt.allocPrint(r.alloc, "./repos/{s}", .{rd.name});
var filename = try std.fmt.allocPrint(ctx.alloc, "./repos/{s}", .{rd.name});
var cwd = std.fs.cwd();
var dir = cwd.openDir(filename, .{}) catch return error.Unknown;
var repo = git.Repo.init(dir) catch return error.Unknown;
repo.loadData(r.alloc) catch return error.Unknown;
repo.loadData(ctx.alloc) catch return error.Unknown;
 
var lcommits = try r.alloc.alloc(HTML.E, 50);
var current: git.Commit = repo.commit(r.alloc) catch return error.Unknown;
var lcommits = try ctx.alloc.alloc(HTML.E, 50);
var current: git.Commit = repo.commit(ctx.alloc) catch return error.Unknown;
for (lcommits, 0..) |*c, i| {
c.* = (try htmlCommit(r.alloc, current, rd.name, false))[0];
current = current.toParent(r.alloc, 0) catch {
c.* = (try htmlCommit(ctx.alloc, current, rd.name, false))[0];
current = current.toParent(ctx.alloc, 0) catch {
lcommits.len = i;
break;
};
}
 
const htmlstr = try std.fmt.allocPrint(r.alloc, "{}", .{
const htmlstr = try std.fmt.allocPrint(ctx.alloc, "{}", .{
HTML.div(lcommits, null),
});
 
var tmpl = Template.find("commits.html");
tmpl.init(r.alloc);
tmpl.init(ctx.alloc);
tmpl.addVar("commits", htmlstr) catch return error.Unknown;
 
var page = tmpl.buildFor(r.alloc, r) catch unreachable;
var page = tmpl.buildFor(ctx.alloc, ctx) catch unreachable;
 
r.status = .ok;
r.start() catch return Error.Unknown;
r.send(page) catch return Error.Unknown;
r.finish() catch return Error.Unknown;
ctx.response.status = .ok;
ctx.response.start() catch return Error.Unknown;
ctx.response.send(page) catch return Error.Unknown;
ctx.response.finish() catch return Error.Unknown;
}
 
src/endpoints/repos/diffs.zig added: 413, removed: 445, total 0
@@ -42,7 +42,7 @@ fn diffValidForRepo(repo: []const u8, diff: usize) bool {
return diff > 0;
}
 
pub fn router(ctx: *Context) Error!Endpoint.Endpoint {
pub fn router(ctx: *Context) Error!Endpoint.Router.Endpoint {
std.debug.assert(std.mem.eql(u8, "diffs", ctx.uri.next().?));
const verb = ctx.uri.peek() orelse return Endpoint.Router.router(ctx, &routes);
 
@@ -55,13 +55,13 @@ pub fn router(ctx: *Context) Error!Endpoint.Endpoint {
return Endpoint.Router.router(ctx, &routes);
}
 
fn new(r: *Response, _: *UriIter) Error!void {
const a = r.alloc;
fn new(ctx: *Context) Error!void {
const a = ctx.alloc;
var tmpl = Template.find("diffs.html");
tmpl.init(r.alloc);
tmpl.init(ctx.alloc);
 
var dom = DOM.new(r.alloc);
var fattr = try r.alloc.dupe(HTML.Attr, &[_]HTML.Attr{
var dom = DOM.new(ctx.alloc);
var fattr = try ctx.alloc.dupe(HTML.Attr, &[_]HTML.Attr{
.{ .key = "action", .value = "new" },
.{ .key = "method", .value = "POST" },
});
@@ -76,8 +76,8 @@ fn new(r: *Response, _: *UriIter) Error!void {
dom = dom.close();
dom = dom.close();
 
_ = try tmpl.addElements(r.alloc, "diff", dom.done());
r.sendTemplate(&tmpl) catch unreachable;
_ = try tmpl.addElements(ctx.alloc, "diff", dom.done());
ctx.sendTemplate(&tmpl) catch unreachable;
}
 
fn inNetwork(str: []const u8) bool {
@@ -86,9 +86,9 @@ fn inNetwork(str: []const u8) bool {
return true;
}
 
fn newPost(r: *Response, uri: *UriIter) Error!void {
const rd = Repo.RouteData.make(uri) orelse return error.Unrouteable;
if (r.usr_data) |usrdata| if (usrdata.post_data) |post| {
fn newPost(ctx: *Context) Error!void {
const rd = Repo.RouteData.make(&ctx.uri) orelse return error.Unrouteable;
if (ctx.response.usr_data) |usrdata| if (usrdata.post_data) |post| {
var valid = post.validator();
const src = try valid.require("diff source");
const title = try valid.require("title");
@@ -103,9 +103,9 @@ fn newPost(r: *Response, uri: *UriIter) Error!void {
desc.value,
action.name,
});
var data = Patch.loadRemote(r.alloc, src.value) catch unreachable;
var data = Patch.loadRemote(ctx.alloc, src.value) catch unreachable;
var filename = std.fmt.allocPrint(
r.alloc,
ctx.alloc,
"data/patch/{s}.{x}.patch",
.{ rd.name, diff.index },
) catch unreachable;
@@ -116,29 +116,29 @@ fn newPost(r: *Response, uri: *UriIter) Error!void {
};
 
var tmpl = Template.find("diffs.html");
tmpl.init(r.alloc);
tmpl.init(ctx.alloc);
try tmpl.addVar("diff", "new data attempting");
r.sendTemplate(&tmpl) catch unreachable;
ctx.sendTemplate(&tmpl) catch unreachable;
}
 
fn newComment(r: *Response, uri: *UriIter) Error!void {
const rd = Repo.RouteData.make(uri) orelse return error.Unrouteable;
fn newComment(ctx: *Context) Error!void {
const rd = Repo.RouteData.make(&ctx.uri) orelse return error.Unrouteable;
var buf: [2048]u8 = undefined;
if (r.usr_data) |usrdata| if (usrdata.post_data) |post| {
if (ctx.response.usr_data) |usrdata| if (usrdata.post_data) |post| {
var valid = post.validator();
const diff_id = try valid.require("diff-id");
const diff_index = isHex(diff_id.value) orelse return error.Unrouteable;
const loc = try std.fmt.bufPrint(&buf, "/repo/{s}/diffs/{x}", .{ rd.name, diff_index });
 
const msg = try valid.require("comment");
if (msg.value.len < 2) return r.redirect(loc, true) catch unreachable;
if (msg.value.len < 2) return ctx.response.redirect(loc, true) catch unreachable;
 
var diff = Diffs.open(r.alloc, diff_index) catch unreachable orelse return error.Unrouteable;
var diff = Diffs.open(ctx.alloc, diff_index) catch unreachable orelse return error.Unrouteable;
var c = Comments.new("name", msg.value) catch unreachable;
 
diff.addComment(r.alloc, c) catch {};
diff.addComment(ctx.alloc, c) catch {};
diff.writeOut() catch unreachable;
return r.redirect(loc, true) catch unreachable;
return ctx.response.redirect(loc, true) catch unreachable;
};
return error.Unknown;
}
@@ -164,30 +164,30 @@ fn addComment(a: Allocator, c: Comment) ![]HTML.Element {
return dom.done();
}
 
fn view(r: *Response, uri: *UriIter) Error!void {
const rd = Repo.RouteData.make(uri) orelse return error.Unrouteable;
const diff_target = uri.next().?;
fn view(ctx: *Context) Error!void {
const rd = Repo.RouteData.make(&ctx.uri) orelse return error.Unrouteable;
const diff_target = ctx.uri.next().?;
const index = isHex(diff_target) orelse return error.Unrouteable;
 
var tmpl = Template.find("diff-review.html");
tmpl.init(r.alloc);
tmpl.init(ctx.alloc);
 
var dom = DOM.new(r.alloc);
var dom = DOM.new(ctx.alloc);
 
var diff = (Diffs.open(r.alloc, index) catch return error.Unrouteable) orelse return error.Unrouteable;
var diff = (Diffs.open(ctx.alloc, index) catch return error.Unrouteable) orelse return error.Unrouteable;
dom = dom.open(HTML.element("context", null, null));
dom.push(HTML.text(rd.name));
dom = dom.open(HTML.p(null, null));
dom.push(HTML.text(Bleach.sanitizeAlloc(r.alloc, diff.title, .{}) catch unreachable));
dom.push(HTML.text(Bleach.sanitizeAlloc(ctx.alloc, diff.title, .{}) catch unreachable));
dom = dom.close();
dom = dom.open(HTML.p(null, null));
dom.push(HTML.text(Bleach.sanitizeAlloc(r.alloc, diff.desc, .{}) catch unreachable));
dom.push(HTML.text(Bleach.sanitizeAlloc(ctx.alloc, diff.desc, .{}) catch unreachable));
dom = dom.close();
dom = dom.close();
 
_ = try tmpl.addElements(r.alloc, "patch_header", dom.done());
_ = try tmpl.addElements(ctx.alloc, "patch_header", dom.done());
 
var comments = DOM.new(r.alloc);
var comments = DOM.new(ctx.alloc);
for ([_]Comment{ .{
.author = "grayhatter",
.message = "Wow, srctree's Diff view looks really good!",
@@ -195,13 +195,13 @@ fn view(r: *Response, uri: *UriIter) Error!void {
.author = "robinli",
.message = "I know, it's clearly the best I've even seen. Soon it'll even look good in Hastur!",
} }) |cm| {
comments.pushSlice(addComment(r.alloc, cm) catch unreachable);
comments.pushSlice(addComment(ctx.alloc, cm) catch unreachable);
}
for (diff.getComments(r.alloc) catch unreachable) |cm| {
comments.pushSlice(addComment(r.alloc, cm) catch unreachable);
for (diff.getComments(ctx.alloc) catch unreachable) |cm| {
comments.pushSlice(addComment(ctx.alloc, cm) catch unreachable);
}
 
_ = try tmpl.addElements(r.alloc, "comments", comments.done());
_ = try tmpl.addElements(ctx.alloc, "comments", comments.done());
 
const hidden = [_]HTML.Attr{
.{ .key = "type", .value = "hidden" },
@@ -213,18 +213,18 @@ fn view(r: *Response, uri: *UriIter) Error!void {
HTML.input(&hidden),
};
 
_ = try tmpl.addElements(r.alloc, "form-data", &form_data);
_ = try tmpl.addElements(ctx.alloc, "form-data", &form_data);
 
const filename = try std.fmt.allocPrint(r.alloc, "data/patch/{s}.{x}.patch", .{ rd.name, diff.index });
const filename = try std.fmt.allocPrint(ctx.alloc, "data/patch/{s}.{x}.patch", .{ rd.name, diff.index });
var file: ?std.fs.File = std.fs.cwd().openFile(filename, .{}) catch null;
if (file) |f| {
const fdata = f.readToEndAlloc(r.alloc, 0xFFFFF) catch return error.Unknown;
const patch = try Patch.patchHtml(r.alloc, fdata);
_ = try tmpl.addElementsFmt(r.alloc, "{pretty}", "patch", patch);
const fdata = f.readToEndAlloc(ctx.alloc, 0xFFFFF) catch return error.Unknown;
const patch = try Patch.patchHtml(ctx.alloc, fdata);
_ = try tmpl.addElementsFmt(ctx.alloc, "{pretty}", "patch", patch);
f.close();
} else try tmpl.addString("patch", "Patch not found");
 
r.sendTemplate(&tmpl) catch unreachable;
ctx.sendTemplate(&tmpl) catch unreachable;
}
 
fn diffRow(a: Allocator, diff: Diffs.Diff) ![]HTML.Element {
@@ -242,25 +242,25 @@ fn diffRow(a: Allocator, diff: Diffs.Diff) ![]HTML.Element {
return dom.done();
}
 
fn list(r: *Response, uri: *UriIter) Error!void {
const rd = Repo.RouteData.make(uri) orelse return error.Unrouteable;
var dom = DOM.new(r.alloc);
fn list(ctx: *Context) Error!void {
const rd = Repo.RouteData.make(&ctx.uri) orelse return error.Unrouteable;
var dom = DOM.new(ctx.alloc);
dom.push(HTML.element("search", null, null));
dom = dom.open(HTML.element("actionable", null, null));
 
for (0..Diffs.last() + 1) |i| {
var d = Diffs.open(r.alloc, i) catch continue orelse continue;
defer d.raze(r.alloc);
var d = Diffs.open(ctx.alloc, i) catch continue orelse continue;
defer d.raze(ctx.alloc);
if (!std.mem.eql(u8, d.repo, rd.name)) continue;
dom.pushSlice(diffRow(r.alloc, d) catch continue);
dom.pushSlice(diffRow(ctx.alloc, d) catch continue);
}
dom = dom.close();
const diffs = dom.done();
var tmpl = Template.find("diffs.html");
tmpl.init(r.alloc);
_ = try tmpl.addElements(r.alloc, "diff", diffs);
var page = tmpl.buildFor(r.alloc, r) catch unreachable;
r.start() catch return Error.Unknown;
r.send(page) catch return Error.Unknown;
r.finish() catch return Error.Unknown;
tmpl.init(ctx.alloc);
_ = try tmpl.addElements(ctx.alloc, "diff", diffs);
var page = tmpl.buildFor(ctx.alloc, ctx) catch unreachable;
ctx.response.start() catch return Error.Unknown;
ctx.response.send(page) catch return Error.Unknown;
ctx.response.finish() catch return Error.Unknown;
}
 
src/endpoints/repos/issues.zig added: 413, removed: 445, total 0
@@ -6,7 +6,6 @@ const DOM = Endpoint.DOM;
const HTML = Endpoint.HTML;
const Endpoint = @import("../../endpoint.zig");
const Context = @import("../../context.zig");
const Response = Endpoint.Response;
const Template = Endpoint.Template;
const Error = Endpoint.Error;
const UriIter = Endpoint.Router.UriIter;
@@ -41,7 +40,7 @@ fn issueValidForRepo(repo: []const u8, issue: usize) bool {
return issue > 0;
}
 
pub fn router(ctx: *Context) Error!Endpoint.Endpoint {
pub fn router(ctx: *Context) Error!Endpoint.Router.Endpoint {
std.debug.assert(std.mem.eql(u8, "issues", ctx.uri.next().?));
const verb = ctx.uri.peek() orelse return Endpoint.Router.router(ctx, &routes);
 
@@ -54,16 +53,16 @@ pub fn router(ctx: *Context) Error!Endpoint.Endpoint {
return Endpoint.Router.router(ctx, &routes);
}
 
fn new(r: *Response, _: *UriIter) Error!void {
const a = r.alloc;
fn new(ctx: *Context) Error!void {
const a = ctx.alloc;
var tmpl = Template.find("issues.html");
tmpl.init(r.alloc);
tmpl.init(ctx.alloc);
 
var dom = DOM.new(r.alloc);
var dom = DOM.new(ctx.alloc);
dom = dom.open(HTML.element("intro", null, null));
dom.push(HTML.text("New Pull Request"));
dom = dom.close();
var fattr = try r.alloc.dupe(HTML.Attr, &[_]HTML.Attr{
var fattr = try ctx.alloc.dupe(HTML.Attr, &[_]HTML.Attr{
.{ .key = "action", .value = "new" },
.{ .key = "method", .value = "POST" },
});
@@ -76,8 +75,8 @@ fn new(r: *Response, _: *UriIter) Error!void {
dom.dupe(HTML.btnDupe("Preview", "preview"));
dom = dom.close();
 
_ = try tmpl.addElements(r.alloc, "issue", dom.done());
r.sendTemplate(&tmpl) catch unreachable;
_ = try tmpl.addElements(ctx.alloc, "issue", dom.done());
ctx.sendTemplate(&tmpl) catch unreachable;
}
 
fn inNetwork(str: []const u8) bool {
@@ -86,36 +85,9 @@ fn inNetwork(str: []const u8) bool {
return true;
}
 
fn fetch(a: Allocator, uri: []const u8) ![]const u8 {
var client = std.http.Client{
.allocator = a,
};
defer client.deinit();
 
var request = client.fetch(a, .{
.location = .{ .url = uri },
});
if (request) |*req| {
defer req.deinit();
std.debug.print("request code {}\n", .{req.status});
if (req.body) |b| {
std.debug.print("request body {s}\n", .{b});
return a.dupe(u8, b);
}
} else |err| {
std.debug.print("stdlib request failed with error {}\n", .{err});
}
 
var curl = try CURL.curlRequest(a, uri);
if (curl.code != 200) return error.UnexpectedResponseCode;
 
if (curl.body) |b| return b;
return error.EpmtyReponse;
}
 
fn newPost(r: *Response, uri: *UriIter) Error!void {
const rd = Repo.RouteData.make(uri) orelse return error.Unrouteable;
if (r.usr_data) |usrdata| if (usrdata.post_data) |post| {
fn newPost(ctx: *Context) Error!void {
const rd = Repo.RouteData.make(&ctx.uri) orelse return error.Unrouteable;
if (ctx.response.usr_data) |usrdata| if (usrdata.post_data) |post| {
var valid = post.validator();
const title = try valid.require("title");
const msg = try valid.require("message");
@@ -124,27 +96,27 @@ fn newPost(r: *Response, uri: *UriIter) Error!void {
};
 
var tmpl = Template.find("issues.html");
tmpl.init(r.alloc);
tmpl.init(ctx.alloc);
try tmpl.addVar("issue", "new data attempting");
r.sendTemplate(&tmpl) catch unreachable;
ctx.sendTemplate(&tmpl) catch unreachable;
}
 
fn newComment(r: *Response, uri: *UriIter) Error!void {
const rd = Repo.RouteData.make(uri) orelse return error.Unrouteable;
if (r.usr_data) |usrdata| if (usrdata.post_data) |post| {
fn newComment(ctx: *Context) Error!void {
const rd = Repo.RouteData.make(&ctx.uri) orelse return error.Unrouteable;
if (ctx.response.usr_data) |usrdata| if (usrdata.post_data) |post| {
var valid = post.validator();
const issue_id = try valid.require("issue-id");
const msg = try valid.require("comment");
const issue_index = isHex(issue_id.value) orelse return error.Unrouteable;
 
var issue = Issues.open(r.alloc, issue_index) catch unreachable orelse return error.Unrouteable;
var issue = Issues.open(ctx.alloc, issue_index) catch unreachable orelse return error.Unrouteable;
var c = Comments.new("name", msg.value) catch unreachable;
 
issue.addComment(r.alloc, c) catch {};
issue.addComment(ctx.alloc, c) catch {};
issue.writeOut() catch unreachable;
var buf: [2048]u8 = undefined;
const loc = try std.fmt.bufPrint(&buf, "/repo/{s}/issues/{x}", .{ rd.name, issue_index });
r.redirect(loc, true) catch unreachable;
ctx.response.redirect(loc, true) catch unreachable;
return;
};
return error.Unknown;
@@ -171,23 +143,23 @@ fn addComment(a: Allocator, c: Comment) ![]HTML.Element {
return dom.done();
}
 
fn view(r: *Response, uri: *UriIter) Error!void {
const rd = Repo.RouteData.make(uri) orelse return error.Unrouteable;
const issue_target = uri.next().?;
fn view(ctx: *Context) Error!void {
const rd = Repo.RouteData.make(&ctx.uri) orelse return error.Unrouteable;
const issue_target = ctx.uri.next().?;
const index = isHex(issue_target) orelse return error.Unrouteable;
 
var tmpl = Template.find("patch.html");
tmpl.init(r.alloc);
tmpl.init(ctx.alloc);
 
var dom = DOM.new(r.alloc);
var dom = DOM.new(ctx.alloc);
 
var issue = (Issues.open(r.alloc, index) catch return error.Unrouteable) orelse return error.Unrouteable;
var issue = (Issues.open(ctx.alloc, index) catch return error.Unrouteable) orelse return error.Unrouteable;
dom.push(HTML.text(rd.name));
dom.push(HTML.text(issue.repo));
dom.push(HTML.text(Bleach.sanitizeAlloc(r.alloc, issue.title, .{}) catch unreachable));
dom.push(HTML.text(Bleach.sanitizeAlloc(r.alloc, issue.desc, .{}) catch unreachable));
dom.push(HTML.text(Bleach.sanitizeAlloc(ctx.alloc, issue.title, .{}) catch unreachable));
dom.push(HTML.text(Bleach.sanitizeAlloc(ctx.alloc, issue.desc, .{}) catch unreachable));
 
var comments = DOM.new(r.alloc);
var comments = DOM.new(ctx.alloc);
for ([_]Comment{ .{
.author = "grayhatter",
.message = "Wow, srctree's issue view looks really good!",
@@ -195,15 +167,15 @@ fn view(r: *Response, uri: *UriIter) Error!void {
.author = "robinli",
.message = "I know, it's clearly the best I've even seen. Soon It'll even look good in Hastur!",
} }) |cm| {
comments.pushSlice(addComment(r.alloc, cm) catch unreachable);
comments.pushSlice(addComment(ctx.alloc, cm) catch unreachable);
}
for (issue.getComments(r.alloc) catch unreachable) |cm| {
comments.pushSlice(addComment(r.alloc, cm) catch unreachable);
for (issue.getComments(ctx.alloc) catch unreachable) |cm| {
comments.pushSlice(addComment(ctx.alloc, cm) catch unreachable);
}
 
_ = try tmpl.addElements(r.alloc, "comments", comments.done());
_ = try tmpl.addElements(ctx.alloc, "comments", comments.done());
 
_ = try tmpl.addElements(r.alloc, "patch_header", dom.done());
_ = try tmpl.addElements(ctx.alloc, "patch_header", dom.done());
 
const hidden = [_]HTML.Attr{
.{ .key = "type", .value = "hidden" },
@@ -215,9 +187,9 @@ fn view(r: *Response, uri: *UriIter) Error!void {
HTML.input(&hidden),
};
 
_ = try tmpl.addElements(r.alloc, "form-data", &form_data);
_ = try tmpl.addElements(ctx.alloc, "form-data", &form_data);
 
r.sendTemplate(&tmpl) catch unreachable;
ctx.sendTemplate(&tmpl) catch unreachable;
}
 
fn issueRow(a: Allocator, issue: Issues.Issue) ![]HTML.Element {
@@ -235,25 +207,25 @@ fn issueRow(a: Allocator, issue: Issues.Issue) ![]HTML.Element {
return dom.done();
}
 
fn list(r: *Response, uri: *UriIter) Error!void {
const rd = Repo.RouteData.make(uri) orelse return error.Unrouteable;
var dom = DOM.new(r.alloc);
fn list(ctx: *Context) Error!void {
const rd = Repo.RouteData.make(&ctx.uri) orelse return error.Unrouteable;
var dom = DOM.new(ctx.alloc);
dom.push(HTML.element("search", null, null));
dom = dom.open(HTML.element("actionable", null, null));
 
for (0..Issues.last() catch return error.Unknown) |i| {
var d = Issues.open(r.alloc, i) catch continue orelse continue;
defer d.raze(r.alloc);
var d = Issues.open(ctx.alloc, i) catch continue orelse continue;
defer d.raze(ctx.alloc);
if (!std.mem.eql(u8, d.repo, rd.name)) continue;
dom.pushSlice(issueRow(r.alloc, d) catch continue);
dom.pushSlice(issueRow(ctx.alloc, d) catch continue);
}
dom = dom.close();
const issues = dom.done();
var tmpl = Template.find("issues.html");
tmpl.init(r.alloc);
_ = try tmpl.addElements(r.alloc, "issue", issues);
var page = tmpl.buildFor(r.alloc, r) catch unreachable;
r.start() catch return Error.Unknown;
r.send(page) catch return Error.Unknown;
r.finish() catch return Error.Unknown;
tmpl.init(ctx.alloc);
_ = try tmpl.addElements(ctx.alloc, "issue", issues);
var page = tmpl.buildFor(ctx.alloc, ctx) catch unreachable;
ctx.response.start() catch return Error.Unknown;
ctx.response.send(page) catch return Error.Unknown;
ctx.response.finish() catch return Error.Unknown;
}
 
src/endpoints/todo.zig added: 413, removed: 445, total 0
@@ -3,7 +3,7 @@ const std = @import("std");
const DOM = Endpoint.DOM;
const HTML = Endpoint.HTML;
const Endpoint = @import("../endpoint.zig");
const Response = Endpoint.Response;
const Context = Endpoint.Context;
const Template = Endpoint.Template;
const Error = Endpoint.Error;
const UriIter = Endpoint.Router.UriIter;
@@ -15,8 +15,8 @@ pub const endpoints = [_]Endpoint.Router.MatchRouter{
.{ .name = "", .methods = GET, .match = .{ .call = default } },
};
 
fn default(r: *Response, _: *UriIter) Error!void {
var dom = DOM.new(r.alloc);
fn default(ctx: *Context) Error!void {
var dom = DOM.new(ctx.alloc);
dom.push(HTML.element("search", null, null));
 
dom = dom.open(HTML.element("actionable", null, null));
@@ -32,10 +32,10 @@ fn default(r: *Response, _: *UriIter) Error!void {
var data = dom.done();
 
var tmpl = Template.find("todo.html");
tmpl.init(r.alloc);
_ = tmpl.addElements(r.alloc, "todos", data) catch unreachable;
var page = tmpl.buildFor(r.alloc, r) catch unreachable;
r.start() catch return Error.Unknown;
r.send(page) catch return Error.Unknown;
r.finish() catch return Error.Unknown;
tmpl.init(ctx.alloc);
_ = tmpl.addElements(ctx.alloc, "todos", data) catch unreachable;
var page = tmpl.buildFor(ctx.alloc, ctx) catch unreachable;
ctx.response.start() catch return Error.Unknown;
ctx.response.send(page) catch return Error.Unknown;
ctx.response.finish() catch return Error.Unknown;
}
 
src/gitweb.zig added: 413, removed: 445, total 0
@@ -31,15 +31,15 @@ pub const endpoints = [_]Endpoint.Router.MatchRouter{
};
 
pub fn router(ctx: *Context) Error!Endpoint.Endpoint {
std.debug.print("gitweb router {s}\n{any}, {any} \n", .{ ctx.uri.peek().?, ctx.uri, ctx.request.method });
std.debug.print("gitweb router {s}\n{any}, {any} \n", .{ ctx.ctx.uri.peek().?, ctx.ctx.uri, ctx.request.method });
return Endpoint.Router.router(ctx, &endpoints);
}
 
fn gitUploadPack(r: *Response, uri: *UriIter) Error!void {
uri.reset();
_ = uri.first();
const name = uri.next() orelse return error.Unknown;
const target = uri.rest();
fn gitUploadPack(ctx: *Context) Error!void {
ctx.uri.reset();
_ = ctx.uri.first();
const name = ctx.uri.next() orelse return error.Unknown;
const target = ctx.uri.rest();
if (!std.mem.eql(u8, target, "info/refs") and !std.mem.eql(u8, target, "git-upload-pack")) {
return error.Abusive;
}
@@ -48,11 +48,11 @@ fn gitUploadPack(r: *Response, uri: *UriIter) Error!void {
const path_tr = std.fmt.bufPrint(&path_buf, "repos/{s}/{s}", .{ name, target }) catch unreachable;
std.debug.print("pathtr {s}\n", .{path_tr});
 
var map = std.process.EnvMap.init(r.alloc);
var map = std.process.EnvMap.init(ctx.alloc);
defer map.deinit();
 
//(if GIT_PROJECT_ROOT is set, otherwise PATH_TRANSLATED)
if (r.usr_data != null and r.usr_data.?.post_data == null) {
if (ctx.response.usr_data != null and ctx.response.usr_data.?.post_data == null) {
try map.put("PATH_TRANSLATED", path_tr);
try map.put("QUERY_STRING", "service=git-upload-pack");
try map.put("REQUEST_METHOD", "GET");
@@ -67,15 +67,15 @@ fn gitUploadPack(r: *Response, uri: *UriIter) Error!void {
try map.put("GIT_PROTOCOL", "version=2");
try map.put("GIT_HTTP_EXPORT_ALL", "true");
 
var child = std.ChildProcess.init(&[_][]const u8{ "git", "http-backend" }, r.alloc);
var child = std.ChildProcess.init(&[_][]const u8{ "git", "http-backend" }, ctx.alloc);
child.stdin_behavior = .Pipe;
child.stdout_behavior = .Pipe;
child.stderr_behavior = .Ignore;
child.env_map = &map;
child.expand_arg0 = .no_expand;
 
r.status = .ok;
r.phase = .headers;
ctx.response.status = .ok;
ctx.response.phase = .headers;
 
child.spawn() catch unreachable;
 
@@ -87,14 +87,14 @@ fn gitUploadPack(r: *Response, uri: *UriIter) Error!void {
.revents = undefined,
},
};
if (r.usr_data) |usr| {
if (ctx.response.usr_data) |usr| {
if (usr.post_data) |pd| {
_ = std.os.write(child.stdin.?.handle, pd.rawpost) catch unreachable;
std.os.close(child.stdin.?.handle);
child.stdin = null;
}
}
var buf = try r.alloc.alloc(u8, 0xffffff);
var buf = try ctx.alloc.alloc(u8, 0xffffff);
var headers_required = true;
while (true) {
const events_len = std.os.poll(&poll_fd, std.math.maxInt(i32)) catch unreachable;
@@ -103,10 +103,10 @@ fn gitUploadPack(r: *Response, uri: *UriIter) Error!void {
const amt = std.os.read(poll_fd[0].fd, buf) catch unreachable;
if (amt == 0) break;
if (headers_required) {
_ = r.write("HTTP/1.1 200 OK\r\n") catch unreachable;
_ = ctx.response.write("HTTP/1.1 200 OK\r\n") catch unreachable;
headers_required = false;
}
r.writeAll(buf[0..amt]) catch unreachable;
ctx.response.writeAll(buf[0..amt]) catch unreachable;
} else if (poll_fd[0].revents & err_mask != 0) {
break;
}
@@ -114,52 +114,52 @@ fn gitUploadPack(r: *Response, uri: *UriIter) Error!void {
_ = child.wait() catch unreachable;
}
 
fn __objects(r: *Response, uri: *UriIter) Error!void {
fn __objects(ctx: *Context) Error!void {
std.debug.print("gitweb objects\n", .{});
 
const rd = Endpoint.REPO.RouteData.make(uri) orelse return error.Unrouteable;
const rd = Endpoint.REPO.RouteData.make(ctx.uri) orelse return error.Unrouteable;
 
var cwd = std.fs.cwd();
var filename = try std.fmt.allocPrint(r.alloc, "./repos/{s}", .{rd.name});
var filename = try std.fmt.allocPrint(ctx.alloc, "./repos/{s}", .{rd.name});
var dir = cwd.openDir(filename, .{}) catch return error.Unknown;
var repo = git.Repo.init(dir) catch return error.Unknown;
repo.loadData(r.alloc) catch return error.Unknown;
repo.loadData(ctx.alloc) catch return error.Unknown;
 
uri.reset();
_ = uri.first();
_ = uri.next();
_ = uri.next();
const o2 = uri.next().?;
const o38 = uri.next().?;
ctx.uri.reset();
_ = ctx.uri.first();
_ = ctx.uri.next();
_ = ctx.uri.next();
const o2 = ctx.uri.next().?;
const o38 = ctx.uri.next().?;
 
filename = try std.fmt.allocPrint(r.alloc, "./repos/{s}/objects/{s}/{s}", .{ rd.name, o2, o38 });
filename = try std.fmt.allocPrint(ctx.alloc, "./repos/{s}/objects/{s}/{s}", .{ rd.name, o2, o38 });
var file = cwd.openFile(filename, .{}) catch unreachable;
var data = file.readToEndAlloc(r.alloc, 0xffffff) catch unreachable;
var data = file.readToEndAlloc(ctx.alloc, 0xffffff) catch unreachable;
 
//var sha: [40]u8 = undefined;
//@memcpy(sha[0..2], o2[0..2]);
//@memcpy(sha[2..40], o38[0..38]);
 
//var data = repo.findBlob(r.alloc, &sha) catch unreachable;
//var data = repo.findBlob(ctx.alloc, &sha) catch unreachable;
 
r.status = .ok;
r.start() catch return Error.Unknown;
r.write(data) catch return Error.Unknown;
r.finish() catch return Error.Unknown;
ctx.response.status = .ok;
ctx.response.start() catch return Error.Unknown;
ctx.response.write(data) catch return Error.Unknown;
ctx.response.finish() catch return Error.Unknown;
}
 
fn __info(r: *Response, uri: *UriIter) Error!void {
fn __info(ctx: *Context) Error!void {
std.debug.print("gitweb info\n", .{});
 
const rd = Endpoint.REPO.RouteData.make(uri) orelse return error.Unrouteable;
const rd = Endpoint.REPO.RouteData.make(ctx.uri) orelse return error.Unrouteable;
 
var cwd = std.fs.cwd();
var filename = try std.fmt.allocPrint(r.alloc, "./repos/{s}", .{rd.name});
var filename = try std.fmt.allocPrint(ctx.alloc, "./repos/{s}", .{rd.name});
var dir = cwd.openDir(filename, .{}) catch return error.Unknown;
var repo = git.Repo.init(dir) catch return error.Unknown;
repo.loadData(r.alloc) catch return error.Unknown;
repo.loadData(ctx.alloc) catch return error.Unknown;
 
var adata = std.ArrayList(u8).init(r.alloc);
var adata = std.ArrayList(u8).init(ctx.alloc);
 
for (repo.refs) |ref| {
std.debug.print("{}\n", .{ref});
@@ -178,8 +178,8 @@ fn __info(r: *Response, uri: *UriIter) Error!void {
 
var data = try adata.toOwnedSlice();
 
r.status = .ok;
r.start() catch return Error.Unknown;
r.write(data) catch return Error.Unknown;
r.finish() catch return Error.Unknown;
ctx.response.status = .ok;
ctx.response.start() catch return Error.Unknown;
ctx.response.write(data) catch return Error.Unknown;
ctx.response.finish() catch return Error.Unknown;
}
 
src/patch.zig added: 413, removed: 445, total 0
@@ -18,8 +18,9 @@ pub const Patch = struct {
}
 
pub fn filesSlice(self: Patch, a: Allocator) ![][]const u8 {
const count = mem.count(u8, self.patch, "\ndiff --git a/") + 1;
if (count == 1 and mem.count(u8, self.patch, "diff --git a/") != 1) return error.PatchInvalid;
const count = mem.count(u8, self.patch, "\ndiff --git a/") +
@as(usize, if (mem.startsWith(u8, self.patch, "diff --git a/")) 1 else 0);
if (count == 0) return error.PatchInvalid;
var files = try a.alloc([]const u8, count);
errdefer a.free(files);
var fidx: usize = 0;
@@ -51,7 +52,7 @@ pub const Header = struct {
const left_s = 7 + (mem.indexOf(u8, d, "\n--- a/") orelse return error.PatchInvalid);
const left_e = mem.indexOfPos(u8, d, left_s, "\n") orelse return error.PatchInvalid;
self.filename.left = d[left_s..left_e];
const right_s = 7 + (mem.indexOf(u8, d, "\n+++ b/") orelse return error.PatchInvalid);
const right_s = 7 + (mem.indexOfPos(u8, d, left_e, "\n+++ b/") orelse return error.PatchInvalid);
const right_e = mem.indexOfPos(u8, d, right_s, "\n") orelse return error.PatchInvalid;
self.filename.right = d[right_s..right_e];
// Block headers
 
src/response.zig added: 413, removed: 445, total 0
@@ -44,7 +44,7 @@ const Error = error{
 
pub const Writer = std.io.Writer(*Response, Error, write);
 
alloc: Allocator,
//alloc: Allocator,
request: *Request,
headers: Headers,
phase: Phase = .created,
@@ -61,7 +61,7 @@ usr_data: ?UserData.UserData = null,
 
pub fn init(a: Allocator, req: *Request) Response {
var res = Response{
.alloc = a,
//.alloc = a,
.request = req,
.headers = Headers.init(a),
.downstream = switch (req.raw_request) {
@@ -147,13 +147,6 @@ pub fn send(res: *Response, data: []const u8) !void {
try res.writeAll(data);
}
 
pub fn sendTemplate(res: *Response, t: *Template) !void {
try res.start();
const page = try t.buildFor(res.alloc, res);
try res.send(page);
try res.finish();
}
 
pub fn writer(res: *Response) Writer {
return .{ .context = res };
}
 
src/routes.zig added: 413, removed: 445, total 0
@@ -9,7 +9,6 @@ const Request = @import("request.zig");
const endpoint = @import("endpoint.zig");
const HTML = @import("html.zig");
 
const Endpoint = endpoint.Endpoint;
const Error = endpoint.Error;
pub const UriIter = std.mem.SplitIterator(u8, .sequence);
 
@@ -17,6 +16,7 @@ const div = HTML.div;
const span = HTML.span;
 
pub const Router = *const fn (*Context) Error!Endpoint;
pub const Endpoint = *const fn (*Context) Error!void;
 
pub const Methods = struct {
pub const GET = 1;
@@ -48,39 +48,39 @@ const root = [_]MatchRouter{
.{ .name = "user", .match = .{ .call = endpoint.commitFlex } },
};
 
fn sendMsg(r: *Response, msg: []const u8) !void {
//r.transfer_encoding = .{ .content_length = msg.len };
try r.start();
try r.send(msg);
try r.finish();
fn sendMsg(ctx: *Context, msg: []const u8) !void {
//ctx.response.transfer_encoding = .{ .content_length = msg.len };
try ctx.response.start();
try ctx.response.send(msg);
try ctx.response.finish();
}
 
fn notfound(r: *Response, _: *UriIter) Error!void {
r.status = .not_found;
fn notfound(ctx: *Context) Error!void {
ctx.response.status = .not_found;
const MSG = Template.find("4XX.html").blob;
sendMsg(r, MSG) catch |e| {
sendMsg(ctx, MSG) catch |e| {
std.log.err("Unexpected error while responding [{}]\n", .{e});
return Error.AndExit;
};
}
 
fn _respond(r: *Response, _: *UriIter) Error!void {
r.headersAdd("connection", "keep-alive") catch return Error.ReqResInvalid;
r.headersAdd("content-type", "text/plain") catch return Error.ReqResInvalid;
fn _respond(ctx: *Context) Error!void {
ctx.response.headersAdd("connection", "keep-alive") catch return Error.ReqResInvalid;
ctx.response.headersAdd("content-type", "text/plain") catch return Error.ReqResInvalid;
const MSG = "Hi, mom!\n";
sendMsg(r, MSG) catch |e| {
sendMsg(ctx, MSG) catch |e| {
std.log.err("Unexpected error while responding [{}]\n", .{e});
return Error.AndExit;
};
}
 
fn default(r: *Response, _: *UriIter) Error!void {
fn default(ctx: *Context) Error!void {
var tmpl = Template.find("index.html");
tmpl.init(r.alloc);
var page = tmpl.buildFor(r.alloc, r) catch unreachable;
r.start() catch return Error.Unknown;
r.send(page) catch return Error.Unknown;
r.finish() catch return Error.Unknown;
tmpl.init(ctx.alloc);
var page = tmpl.buildFor(ctx.alloc, ctx) catch unreachable;
ctx.response.start() catch return Error.Unknown;
ctx.response.send(page) catch return Error.Unknown;
ctx.response.finish() catch return Error.Unknown;
}
 
fn eql(a: []const u8, b: []const u8) bool {
@@ -121,8 +121,8 @@ pub fn baseRouter(ctx: *Context) Error!void {
if (ctx.uri.peek()) |first| {
if (first.len > 0) {
const route: Endpoint = router(ctx, &root);
return route(&ctx.response, &ctx.uri);
return route(ctx);
}
}
return default(&ctx.response, &ctx.uri);
return default(ctx);
}
 
src/template.zig added: 413, removed: 445, total 0
@@ -4,7 +4,7 @@ const bldtmpls = @import("templates");
const Allocator = std.mem.Allocator;
 
const HTML = @import("html.zig");
const Response = @import("response.zig");
const Context = @import("context.zig");
 
const MAX_BYTES = 2 <<| 15;
const TEMPLATE_PATH = "templates/";
@@ -103,8 +103,8 @@ pub const Template = struct {
return std.fmt.allocPrint(a, "{}", .{self});
}
 
pub fn buildFor(self: *Template, a: ?Allocator, r: *const Response) ![]u8 {
const loggedin = if (r.request.auth.valid()) "<a href=\"#\">Logged In</a>" else "Public";
pub fn buildFor(self: *Template, a: ?Allocator, ctx: *const Context) ![]u8 {
const loggedin = if (ctx.request.auth.valid()) "<a href=\"#\">Logged In</a>" else "Public";
try self.addVar("header.auth", loggedin);
return try self.build(a);
}