Repository navigation
Expand file tree
/
Copy pathbuild.zig
More file actions
138 lines (123 loc) · 4.72 KB
/
Copy pathbuild.zig
File metadata and controls
138 lines (123 loc) · 4.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const release = readRelease(b);
const options = b.addOptions();
options.addOption([]const u8, "version", release.version);
options.addOption([]const u8, "git_sha", readGitSha(b));
options.addOption([]const u8, "build_label", "Oct-2026");
_ = release.stable;
const exe = b.addExecutable(.{
.name = "authdog",
.version = std.SemanticVersion.parse(release.version) catch @panic("release.toml version is not semver"),
.root_module = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
.strip = optimize != .Debug,
}),
});
exe.root_module.addOptions("build_options", options);
const callback_page = callbackPageModule(b);
exe.root_module.addImport("callback_page", callback_page);
b.installArtifact(exe);
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| run_cmd.addArgs(args);
const run_step = b.step("run", "Run the Authdog CLI");
run_step.dependOn(&run_cmd.step);
const unit_mod = b.createModule(.{
.root_source_file = b.path("src/cli.zig"),
.target = target,
.optimize = optimize,
});
unit_mod.addOptions("build_options", options);
unit_mod.addImport("callback_page", callback_page);
const unit_tests = b.addTest(.{
.root_module = unit_mod,
});
const run_unit_tests = b.addRunArtifact(unit_tests);
const checks = b.addExecutable(.{
.name = "cli-checks",
.root_module = b.createModule(.{
.root_source_file = b.path("src/cli_checks.zig"),
.target = target,
.optimize = optimize,
}),
});
const run_checks = b.addRunArtifact(checks);
run_checks.addFileArg(exe.getEmittedBin());
const test_step = b.step("test", "Run unit tests and CLI checks");
test_step.dependOn(&run_unit_tests.step);
test_step.dependOn(&run_checks.step);
}
const ReleaseInfo = struct {
version: []const u8,
stable: bool,
};
fn callbackPageModule(b: *std.Build) *std.Build.Module {
const files = b.addWriteFiles();
_ = files.addCopyFile(b.path("assets/oauth_callback_success.html"), "oauth_callback_success.html");
return b.createModule(.{
.root_source_file = files.add("callback.zig",
\\pub const html = @embedFile("oauth_callback_success.html");
\\
),
});
}
fn readRelease(b: *std.Build) ReleaseInfo {
const text = b.build_root.handle.readFileAlloc(
b.graph.io,
"release.toml",
b.allocator,
.limited(16 * 1024),
) catch @panic("failed to read release.toml");
var version: ?[]const u8 = null;
var stable = false;
var lines = std.mem.splitScalar(u8, text, '\n');
while (lines.next()) |raw| {
const line = std.mem.trim(u8, raw, " \t\r");
if (line.len == 0 or line[0] == '#') continue;
if (std.mem.startsWith(u8, line, "version")) {
version = parseTomlString(b, line);
} else if (std.mem.startsWith(u8, line, "stable")) {
stable = std.mem.indexOf(u8, line, "true") != null;
}
}
return .{
.version = version orelse @panic("release.toml is missing version"),
.stable = stable,
};
}
fn readGitSha(b: *std.Build) []const u8 {
const head = b.build_root.handle.readFileAlloc(
b.graph.io,
".git/HEAD",
b.allocator,
.limited(256),
) catch return b.dupe("unknown");
defer b.allocator.free(head);
const head_line = std.mem.trim(u8, head, " \t\r\n");
const ref_suffix = if (std.mem.startsWith(u8, head_line, "ref: "))
std.mem.trim(u8, head_line["ref: ".len..], " \t\r\n")
else
return b.dupe(if (head_line.len >= 7) head_line[0..7] else "unknown");
const ref_path = b.pathJoin(&.{ ".git", ref_suffix });
const sha = b.build_root.handle.readFileAlloc(
b.graph.io,
ref_path,
b.allocator,
.limited(64),
) catch return b.dupe("unknown");
defer b.allocator.free(sha);
const trimmed = std.mem.trim(u8, sha, " \t\r\n");
if (trimmed.len < 7) return b.dupe("unknown");
return b.dupe(trimmed[0..7]);
}
fn parseTomlString(b: *std.Build, line: []const u8) []const u8 {
const open = std.mem.indexOfScalar(u8, line, '"') orelse @panic("release.toml version must be a quoted string");
const rest = line[open + 1 ..];
const close = std.mem.indexOfScalar(u8, rest, '"') orelse @panic("release.toml version must be a quoted string");
return b.dupe(rest[0..close]);
}