╭ changed ────╮ │src/event.zig│ ╰─────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │2229 } │ │2230 try remove(.{ .server = .{ .users_dir = users_dir } }, .user, .xit, user_repo_opts, io, allocator, &user_repo, &Grant.idOf(repo_id, user_id), .grant, author);│ │2231 } │ │2232 + │ │2233 +// add `branch` to the protected branches of the repo `repo_id` in its owner's │ │2234 +// user repo, or take it out when `protect` is false. taking out a branch that │ │2235 +// isn't protected writes nothing. │ │2236 +pub fn protectBranch( │ │2237 + io: std.Io, │ │2238 + allocator: std.mem.Allocator, │ │2239 + users_dir: []const u8, │ │2240 + owner_id: *const [event_id_size]u8, │ │2241 + repo_id: *const [event_id_size]u8, │ │2242 + branch: []const u8, │ │2243 + protect: bool, │ │2244 + author: CommitAuthor, │ │2245 +) !void { │ │2246 + var user_repo = (try openUserRepo(io, allocator, users_dir, owner_id)) orelse return error.NotFound; │ │2247 + defer user_repo.deinit(io, allocator); │ │2248 + var arena = std.heap.ArenaAllocator.init(allocator); │ │2249 + defer arena.deinit(); │ │2250 + const aa = arena.allocator(); │ │2251 + const moment = (try userMoment(&user_repo)) orelse return error.NotFound; │ │2252 + const repo = (try Repo.readById(UserDB, user_repo_opts.hash, moment, &arena, repo_id)) orelse return error.NotFound; │ │2253 + if (repo.removed) return error.NotFound; │ │2254 │ │2255 + var branches: std.ArrayList(u8) = .empty; │ │2256 + var count: usize = 0; │ │2257 + var held = false; │ │2258 + for (try repo.event.protectedBranchNames(aa)) |name| { │ │2259 + if (std.mem.eql(u8, name, branch)) { │ │2260 + held = true; │ │2261 + if (!protect) continue; │ │2262 + } │ │2263 + if (branches.items.len > 0) try branches.append(aa, '\n'); │ │2264 + try branches.appendSlice(aa, name); │ │2265 + count += 1; │ │2266 + } │ │2267 + if (protect) { │ │2268 + if (held) return error.BranchProtected; │ │2269 + if (count >= Repo.protected_branch_max_count) return error.TooManyProtectedBranches; │ │2270 + if (branches.items.len > 0) try branches.append(aa, '\n'); │ │2271 + try branches.appendSlice(aa, branch); │ │2272 + } else if (!held) return; │ │2273 + │ │2274 + var event = repo.event; │ │2275 + event.protected_branches = branches.items; │ │2276 + try consume(.{ .server = .{ .users_dir = users_dir } }, .user, .xit, user_repo_opts, io, allocator, &user_repo, events_ref, &[_]EventWithId{.{ │ │2277 + .id = std.fmt.bytesToHex(repo_id.*, .lower), │ │2278 + .timestamp = @intCast(std.Io.Timestamp.now(io, .real).toSeconds()), │ │2279 + .author = author, │ │2280 + .event = .{ .repo = event }, │ │2281 + }}); │ │2282 +} │ │2283 + │ │2284 // create a user and their user repo, returning the new user's id │ │2285 pub fn createUser( │ │2286 io: std.Io, │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯