srctree

build.zig
a5062626  Gregory Mullen const std = @import("std"); a5062626  Gregory Mullen fa39ddb7  Jeremy Hertel pub fn build(b: *std.Build) !void { a5062626  Gregory Mullen const target = b.standardTargetOptions(.{}); a5062626  Gregory Mullen const optimize = b.standardOptimizeOption(.{}); adeb5b70  Gregory Mullen adeb5b70  Gregory Mullen const ver = version(b); adeb5b70  Gregory Mullen const options = b.addOptions(); adeb5b70  Gregory Mullen options.addOption([]const u8, "version", ver); adeb5b70  Gregory Mullen 07908ac4  Gregory Mullen const verse_lib = b.addModule("verse", .{ 61746c43  Jeremy Hertel .root_source_file = b.path("src/verse.zig"), a5062626  Gregory Mullen .target = target, a5062626  Gregory Mullen .optimize = optimize, a5062626  Gregory Mullen }); a5062626  Gregory Mullen adeb5b70  Gregory Mullen verse_lib.addOptions("build_options", options); adeb5b70  Gregory Mullen a5062626  Gregory Mullen const lib_unit_tests = b.addTest(.{ 61746c43  Jeremy Hertel .root_source_file = b.path("src/verse.zig"), a5062626  Gregory Mullen .target = target, a5062626  Gregory Mullen .optimize = optimize, a5062626  Gregory Mullen }); adeb5b70  Gregory Mullen lib_unit_tests.root_module.addOptions("build_options", options); a5062626  Gregory Mullen 96ccdf46  Gregory Mullen var compiler = Compiler.init(b); 96ccdf46  Gregory Mullen 53b3cd68  Gregory Mullen var comptime_structs: ?*std.Build.Module = null; 53b3cd68  Gregory Mullen var comptime_templates: ?*std.Build.Module = null; 53b3cd68  Gregory Mullen 7c8f22bb  Gregory Mullen if (std.fs.cwd().access("src/fallback_html/index.html", .{})) { 96ccdf46  Gregory Mullen compiler.addDir("src/fallback_html/"); 07908ac4  Gregory Mullen compiler.addDir("examples/templates/"); 96ccdf46  Gregory Mullen compiler.collect() catch unreachable; 53b3cd68  Gregory Mullen comptime_templates = compiler.buildTemplates() catch unreachable; 7c8f22bb  Gregory Mullen // Zig build time doesn't expose it's state in a way I know how to check... 7c8f22bb  Gregory Mullen // so we yolo it like python :D 53b3cd68  Gregory Mullen lib_unit_tests.root_module.addImport("comptime_templates", comptime_templates orelse unreachable); 53b3cd68  Gregory Mullen comptime_structs = compiler.buildStructs() catch unreachable; 53b3cd68  Gregory Mullen lib_unit_tests.root_module.addImport("comptime_structs", comptime_structs orelse unreachable); 53b3cd68  Gregory Mullen 53b3cd68  Gregory Mullen verse_lib.addImport("comptime_structs", comptime_structs orelse @panic("structs missing")); 53b3cd68  Gregory Mullen verse_lib.addImport("comptime_templates", comptime_templates orelse @panic("structs missing")); 7c8f22bb  Gregory Mullen } else |_| {} a5062626  Gregory Mullen const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests); a5062626  Gregory Mullen const test_step = b.step("test", "Run unit tests"); a5062626  Gregory Mullen test_step.dependOn(&run_lib_unit_tests.step); fa39ddb7  Jeremy Hertel 31f30882  Gregory Mullen const examples = [_][]const u8{ 2c06156c  Gregory Mullen "basic", "cookies", "template", "endpoint", "auth-cookie", 2c06156c  Gregory Mullen "request-userdata", "api", "websocket", 31f30882  Gregory Mullen }; 2e1a1a62  Gregory Mullen inline for (examples) |example| { fa39ddb7  Jeremy Hertel const example_exe = b.addExecutable(.{ fa39ddb7  Jeremy Hertel .name = example, 2e1a1a62  Gregory Mullen .root_source_file = b.path("examples/" ++ example ++ ".zig"), fa39ddb7  Jeremy Hertel .target = target, fa39ddb7  Jeremy Hertel .optimize = optimize, fa39ddb7  Jeremy Hertel }); 5774d5cc  Gregory Mullen // All Examples should compile for tests to pass 5774d5cc  Gregory Mullen test_step.dependOn(&example_exe.step); fa39ddb7  Jeremy Hertel 07908ac4  Gregory Mullen example_exe.root_module.addImport("verse", verse_lib); 07908ac4  Gregory Mullen fa39ddb7  Jeremy Hertel const run_example = b.addRunArtifact(example_exe); fa39ddb7  Jeremy Hertel run_example.step.dependOn(b.getInstallStep()); fa39ddb7  Jeremy Hertel fa39ddb7  Jeremy Hertel if (b.args) |args| { fa39ddb7  Jeremy Hertel run_example.addArgs(args); fa39ddb7  Jeremy Hertel } fa39ddb7  Jeremy Hertel 2e1a1a62  Gregory Mullen const run_name = "run-" ++ example; 2e1a1a62  Gregory Mullen const run_description = "Run example: " ++ example; fa39ddb7  Jeremy Hertel const run_step = b.step(run_name, run_description); fa39ddb7  Jeremy Hertel run_step.dependOn(&run_example.step); fa39ddb7  Jeremy Hertel } a5062626  Gregory Mullen } a5062626  Gregory Mullen a5062626  Gregory Mullen pub const Compiler = struct { 96ccdf46  Gregory Mullen b: *std.Build, 96ccdf46  Gregory Mullen dirs: std.ArrayList([]const u8), 96ccdf46  Gregory Mullen files: std.ArrayList([]const u8), 96ccdf46  Gregory Mullen collected: std.ArrayList([]const u8), 96ccdf46  Gregory Mullen templates: ?*std.Build.Module = null, 96ccdf46  Gregory Mullen structs: ?*std.Build.Module = null, 07908ac4  Gregory Mullen debugging: bool = false, 96ccdf46  Gregory Mullen 96ccdf46  Gregory Mullen pub fn init(b: *std.Build) Compiler { 96ccdf46  Gregory Mullen return .{ 96ccdf46  Gregory Mullen .b = b, 96ccdf46  Gregory Mullen .dirs = std.ArrayList([]const u8).init(b.allocator), 96ccdf46  Gregory Mullen .files = std.ArrayList([]const u8).init(b.allocator), 96ccdf46  Gregory Mullen .collected = std.ArrayList([]const u8).init(b.allocator), 96ccdf46  Gregory Mullen }; 96ccdf46  Gregory Mullen } 96ccdf46  Gregory Mullen 96ccdf46  Gregory Mullen pub fn raze(self: Compiler) void { 96ccdf46  Gregory Mullen for (self.dirs.items) |each| self.b.allocator.free(each); 96ccdf46  Gregory Mullen self.dirs.deinit(); 96ccdf46  Gregory Mullen for (self.files.items) |each| self.b.allocator.free(each); 96ccdf46  Gregory Mullen self.files.deinit(); 96ccdf46  Gregory Mullen for (self.collected.items) |each| self.b.allocator.free(each); 96ccdf46  Gregory Mullen self.collected.deinit(); 96ccdf46  Gregory Mullen } 96ccdf46  Gregory Mullen 96ccdf46  Gregory Mullen pub fn addDir(self: *Compiler, dir: []const u8) void { 96ccdf46  Gregory Mullen const copy = self.b.allocator.dupe(u8, dir) catch @panic("OOM"); 96ccdf46  Gregory Mullen self.dirs.append(copy) catch @panic("OOM"); 96ccdf46  Gregory Mullen self.templates = null; 96ccdf46  Gregory Mullen self.structs = null; 96ccdf46  Gregory Mullen } 96ccdf46  Gregory Mullen 96ccdf46  Gregory Mullen pub fn addFile(self: *Compiler, file: []const u8) void { 96ccdf46  Gregory Mullen const copy = self.b.allocator.dupe(u8, file) catch @panic("OOM"); 96ccdf46  Gregory Mullen self.files.append(copy) catch @panic("OOM"); 96ccdf46  Gregory Mullen self.templates = null; 96ccdf46  Gregory Mullen self.structs = null; 96ccdf46  Gregory Mullen } 96ccdf46  Gregory Mullen 96ccdf46  Gregory Mullen pub fn buildTemplates(self: *Compiler) !*std.Build.Module { 96ccdf46  Gregory Mullen if (self.templates) |t| return t; 96ccdf46  Gregory Mullen 96ccdf46  Gregory Mullen //std.debug.print("building for {}\n", .{self.collected.items.len}); 96ccdf46  Gregory Mullen a5062626  Gregory Mullen const local_dir = std.fs.path.dirname(@src().file) orelse "."; 96ccdf46  Gregory Mullen const compiled = self.b.createModule(.{ a5062626  Gregory Mullen .root_source_file = .{ 96ccdf46  Gregory Mullen .cwd_relative = self.b.pathJoin(&.{ local_dir, "src/template/comptime.zig" }), a5062626  Gregory Mullen }, a5062626  Gregory Mullen }); a5062626  Gregory Mullen 96ccdf46  Gregory Mullen const found = self.b.addOptions(); 96ccdf46  Gregory Mullen found.addOption([]const []const u8, "names", self.collected.items); a5062626  Gregory Mullen compiled.addOptions("config", found); a5062626  Gregory Mullen 96ccdf46  Gregory Mullen for (self.collected.items) |file| { a5062626  Gregory Mullen _ = compiled.addAnonymousImport(file, .{ 96ccdf46  Gregory Mullen .root_source_file = self.b.path(file), a5062626  Gregory Mullen }); a5062626  Gregory Mullen } a5062626  Gregory Mullen 96ccdf46  Gregory Mullen self.templates = compiled; a5062626  Gregory Mullen return compiled; a5062626  Gregory Mullen } a5062626  Gregory Mullen 96ccdf46  Gregory Mullen pub fn buildStructs(self: *Compiler) !*std.Build.Module { 96ccdf46  Gregory Mullen if (self.structs) |s| return s; 96ccdf46  Gregory Mullen 07908ac4  Gregory Mullen if (self.debugging) std.debug.print("building structs for {}\n", .{self.collected.items.len}); a5062626  Gregory Mullen const local_dir = std.fs.path.dirname(@src().file) orelse "."; 96ccdf46  Gregory Mullen const t_compiler = self.b.addExecutable(.{ a5062626  Gregory Mullen .name = "template-compiler", a5062626  Gregory Mullen .root_source_file = .{ 15c05a2a  Gregory Mullen .cwd_relative = self.b.pathJoin(&.{ local_dir, "src/template/struct-emit.zig" }), a5062626  Gregory Mullen }, 489f6b4b  Gregory Mullen .target = self.b.graph.host, a5062626  Gregory Mullen }); a5062626  Gregory Mullen 96ccdf46  Gregory Mullen const comptime_templates = try self.buildTemplates(); a5062626  Gregory Mullen t_compiler.root_module.addImport("comptime_templates", comptime_templates); 96ccdf46  Gregory Mullen const tc_build_run = self.b.addRunArtifact(t_compiler); a5062626  Gregory Mullen const tc_structs = tc_build_run.addOutputFileArg("compiled-structs.zig"); 96ccdf46  Gregory Mullen const module = self.b.createModule(.{ a5062626  Gregory Mullen .root_source_file = tc_structs, a5062626  Gregory Mullen }); a5062626  Gregory Mullen 96ccdf46  Gregory Mullen self.structs = module; a5062626  Gregory Mullen return module; a5062626  Gregory Mullen } a5062626  Gregory Mullen 96ccdf46  Gregory Mullen pub fn collect(self: *Compiler) !void { a5062626  Gregory Mullen var cwd = std.fs.cwd(); 96ccdf46  Gregory Mullen for (self.dirs.items) |srcdir| { 96ccdf46  Gregory Mullen var idir = cwd.openDir(srcdir, .{ .iterate = true }) catch |err| { 96ccdf46  Gregory Mullen std.debug.print("template build error {} for srcdir {s}\n", .{ err, srcdir }); 96ccdf46  Gregory Mullen return err; 96ccdf46  Gregory Mullen }; 96ccdf46  Gregory Mullen defer idir.close(); 96ccdf46  Gregory Mullen 96ccdf46  Gregory Mullen var itr = idir.iterate(); 96ccdf46  Gregory Mullen while (try itr.next()) |file| { 96ccdf46  Gregory Mullen if (!std.mem.endsWith(u8, file.name, ".html")) continue; 96ccdf46  Gregory Mullen try self.collected.append(self.b.pathJoin(&[2][]const u8{ srcdir, file.name })); 96ccdf46  Gregory Mullen } 96ccdf46  Gregory Mullen } 96ccdf46  Gregory Mullen for (self.files.items) |file| { 96ccdf46  Gregory Mullen try self.collected.append(file); a5062626  Gregory Mullen } a5062626  Gregory Mullen } a5062626  Gregory Mullen }; adeb5b70  Gregory Mullen adeb5b70  Gregory Mullen fn version(b: *std.Build) []const u8 { adeb5b70  Gregory Mullen if (!std.process.can_spawn) { adeb5b70  Gregory Mullen std.debug.print("Can't get a version number\n", .{}); adeb5b70  Gregory Mullen std.process.exit(1); adeb5b70  Gregory Mullen } adeb5b70  Gregory Mullen adeb5b70  Gregory Mullen var code: u8 = undefined; adeb5b70  Gregory Mullen const git_wide = b.runAllowFail( 4ee7c385  Gregory Mullen &[_][]const u8{ 4ee7c385  Gregory Mullen "git", 4ee7c385  Gregory Mullen "-C", 4ee7c385  Gregory Mullen b.build_root.path orelse ".", 4ee7c385  Gregory Mullen "describe", 4ee7c385  Gregory Mullen "--dirty", 4ee7c385  Gregory Mullen "--always", 4ee7c385  Gregory Mullen }, adeb5b70  Gregory Mullen &code, adeb5b70  Gregory Mullen .Ignore, 4ee7c385  Gregory Mullen ) catch @panic("git is having a bad day"); adeb5b70  Gregory Mullen adeb5b70  Gregory Mullen var git = std.mem.trim(u8, git_wide, " \r\n"); adeb5b70  Gregory Mullen if (git[0] == 'v') git = git[1..]; adeb5b70  Gregory Mullen //std.debug.print("version {s}\n", .{git}); adeb5b70  Gregory Mullen adeb5b70  Gregory Mullen // semver is really dumb, so we need to increment this internally adeb5b70  Gregory Mullen var ver = std.SemanticVersion.parse(git) catch return "v0.0.0-dev"; adeb5b70  Gregory Mullen if (ver.pre != null) { adeb5b70  Gregory Mullen ver.minor += 1; adeb5b70  Gregory Mullen ver.pre = std.fmt.allocPrint(b.allocator, "pre-{s}", .{ver.pre.?}) catch @panic("OOM"); adeb5b70  Gregory Mullen } adeb5b70  Gregory Mullen adeb5b70  Gregory Mullen const final = std.fmt.allocPrint(b.allocator, "{}", .{ver}) catch @panic("OOM"); adeb5b70  Gregory Mullen //std.debug.print("version {s}\n", .{final}); adeb5b70  Gregory Mullen return final; adeb5b70  Gregory Mullen }