╭ changed ────╮ │src/event.zig│ ╰─────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1947 │ │1948 try writeRepoEvent(io, allocator, users_dir, &user_repo, owner_id, owner, &id_bytes, name, description, read_access); │ │1949 return .{ .owner_id = owner_id.*, .repo_id = id_bytes }; │ │1950 +} │ │1951 + │ │1952 +// change the name, description, and read access of the repo named │ │1953 +// `old_name` in its owner's user repo │ │1954 +pub fn updateRepo( │ │1955 + io: std.Io, │ │1956 + allocator: std.mem.Allocator, │ │1957 + users_dir: []const u8, │ │1958 + owner_id: *const [event_id_size]u8, │ │1959 + author: CommitAuthor, │ │1960 + old_name: []const u8, │ │1961 + name: []const u8, │ │1962 + description: []const u8, │ │1963 + read_access: Repo.Access, │ │1964 +) !void { │ │1965 + try Repo.validateName(name); │ │1966 + var user_repo = (try openUserRepo(io, allocator, users_dir, owner_id)) orelse return error.NotFound; │ │1967 + defer user_repo.deinit(io, allocator); │ │1968 + var arena = std.heap.ArenaAllocator.init(allocator); │ │1969 + defer arena.deinit(); │ │1970 + const moment = (try userMoment(&user_repo)) orelse return error.NotFound; │ │1971 + const found = (try Repo.readByName(UserDB, user_repo_opts.hash, moment, &arena, old_name)) orelse return error.NotFound; │ │1972 + if (try Repo.readByName(UserDB, user_repo_opts.hash, moment, &arena, name)) |taken| { │ │1973 + if (!std.mem.eql(u8, &taken.event_id, &found.event_id)) return error.NameTaken; │ │1974 + } │ │1975 + │ │1976 + var event = found.repo.event; │ │1977 + event.name = name; │ │1978 + event.description = description; │ │1979 + event.read_access = read_access; │ │1980 + try consume(.{ .server = .{ .users_dir = users_dir } }, .user, .xit, user_repo_opts, io, allocator, &user_repo, events_ref, &[_]EventWithId{.{│ │1981 + .id = std.fmt.bytesToHex(found.event_id, .lower), │ │1982 + .timestamp = @intCast(std.Io.Timestamp.now(io, .real).toSeconds()), │ │1983 + .author = author, │ │1984 + .event = .{ .repo = event }, │ │1985 + }}); │ │1986 } │ │1987 │ │1988 // create a user and their user repo, returning the new user's id │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ─╮ │src/ui.zig│ ╰──────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ 96 }; │ │ 97 }, │ │ 98 .repo => switch (route) { │ │ 99 - .repo_files, .repo_commits, .repo_diff, .repo_refs, .repo_issues, .repo_patches, .repo_discussions, .repo_events, .repo_undo, .repo_repo_new, .repo_user_new, .repo_user => .{ .repo = try Repo.init(arena, session, route) }, │ │ 99 + .repo_files, .repo_commits, .repo_diff, .repo_refs, .repo_issues, .repo_patches, .repo_discussions, .repo_events, .repo_undo, .repo_repo, .repo_repo_new, .repo_user_new, .repo_user => .{ .repo = try Repo.init(arena, session, route) },│ │100 else => return error.UnexpectedRoute, │ │101 }, │ │102 .fork => switch (route) { │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────╮ │190 repo_undo: RepoUndoRoute, │ │191 repo_repo_new: Array(repo_route_max_len),│ │192 repo_user_new: Array(repo_route_max_len),│ │193 + repo_repo: Array(repo_route_max_len), │ │194 repo_user: Array(repo_route_max_len), │ │195 fork_patch: ForkRoute, │ │196 fork_diff: ForkDiffRoute, │ ╰──────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │428 // the clear-history confirmation page, which has no selected entry │ │429 clear: bool = false, │ │430 }; │ │431 + │ │432 + pub fn repoRepoRoute(identity: []const u8) ?RoutablePage { │ │433 + return .{ .repo_repo = Array(repo_route_max_len).from(identity) orelse return null }; │ │434 + } │ │435 │ │436 pub fn repoUndoRoute(identity: []const u8, index: ?u64) ?RoutablePage { │ │437 return .{ .repo_undo = .{ .name = Array(repo_identity_max_len).from(identity) orelse return null, .index = index } };│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1246 }, │ │1247 .repo_repo_new => |name| try std.fmt.allocPrint(arena.allocator(), "{s}/repo/new", .{try repoUrlPrefix(arena, name.slice())}), │ │1248 .repo_user_new => |name| try std.fmt.allocPrint(arena.allocator(), "{s}/user/new", .{try repoUrlPrefix(arena, name.slice())}), │ │1249 + .repo_repo => |name| try std.fmt.allocPrint(arena.allocator(), "{s}/repo", .{try repoUrlPrefix(arena, name.slice())}), │ │1250 .repo_user => |name| try std.fmt.allocPrint(arena.allocator(), "{s}/user", .{try repoUrlPrefix(arena, name.slice())}), │ │1251 .fork_patch => |f| try std.fmt.allocPrint(arena.allocator(), fork_segment ++ "{s}/" ++ patch_seg ++ "{s}", .{ f.name.slice(), f.id.slice() }),│ │1252 .fork_diff => |d| blk: { │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────╮ │1408 .repo_discussions => |*t| t.name.slice(), │ │1409 .repo_events => |*e| e.name.slice(), │ │1410 .repo_undo => |*u| u.name.slice(), │ │1405 - .repo_repo_new, .repo_user_new, .repo_user => |*name| name.slice(), │ │1411 + .repo_repo, .repo_repo_new, .repo_user_new, .repo_user => |*name| name.slice(),│ │1412 else => null, │ │1413 }; │ │1414 } │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1451 return switch (self) { │ │1452 .home_about, .home_users, .home_repo_new, .home_user_new, .home_user => .home, │ │1453 .user_repos, .user_forks, .user_repo_new, .user_user_new, .user_user => .user, │ │1448 - .repo_files, .repo_commits, .repo_diff, .repo_refs, .repo_issues, .repo_patches, .repo_discussions, .repo_events, .repo_undo, .repo_repo_new, .repo_user_new, .repo_user => .repo, │ │1454 + .repo_files, .repo_commits, .repo_diff, .repo_refs, .repo_issues, .repo_patches, .repo_discussions, .repo_events, .repo_undo, .repo_repo, .repo_repo_new, .repo_user_new, .repo_user => .repo,│ │1455 .fork_patch, .fork_diff, .fork_files, .fork_commits, .fork_repo_new, .fork_user_new, .fork_user => .fork, │ │1456 .not_found => .not_found, │ │1457 }; │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1499 var segments = std.mem.splitScalar(u8, sub, '/'); │ │1500 const tab = segments.next() orelse return null; │ │1501 var params = Params{}; │ │1496 - if (std.mem.eql(u8, tab, "repo")) return if (isNewTail(&segments)) .{ .repo_repo_new = Array(repo_route_max_len).from(pair) orelse return null } else null; │ │1502 + if (std.mem.eql(u8, tab, "repo")) return if (segments.peek() == null) .{ .repo_repo = Array(repo_route_max_len).from(pair) orelse return null } else if (isNewTail(&segments)) .{ .repo_repo_new = Array(repo_route_max_len).from(pair) orelse return null } else null;│ │1503 if (std.mem.eql(u8, tab, "user")) return if (segments.peek() == null) .{ .repo_user = Array(repo_route_max_len).from(pair) orelse return null } else if (isNewTail(&segments)) .{ .repo_user_new = Array(repo_route_max_len).from(pair) orelse return null } else null;│ │1504 if (std.mem.eql(u8, tab, "refs")) { │ │1505 const word = params.scanTail(&segments) catch return null; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1812 std.mem.eql(u8, a_e.selected.slice(), b.repo_events.selected.slice()), │ │1813 .repo_repo_new => |a_name| std.mem.eql(u8, a_name.slice(), b.repo_repo_new.slice()), │ │1814 .repo_user_new => |a_name| std.mem.eql(u8, a_name.slice(), b.repo_user_new.slice()), │ │1815 + .repo_repo => |a_name| std.mem.eql(u8, a_name.slice(), b.repo_repo.slice()), │ │1816 .repo_user => |a_name| std.mem.eql(u8, a_name.slice(), b.repo_user.slice()), │ │1817 .fork_patch => |a_f| std.mem.eql(u8, a_f.name.slice(), b.fork_patch.name.slice()) and std.mem.eql(u8, a_f.id.slice(), b.fork_patch.id.slice()),│ │1818 .fork_diff => |a_d| std.mem.eql(u8, a_d.fork.name.slice(), b.fork_diff.fork.name.slice()) and │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────╮ │2267 access: evt.Repo.Access,│ │2268 }, │ │2269 }, │ │2270 + repo_settings: struct { │ │2271 + failure: RepoFailure, │ │2272 + fields: struct { │ │2273 + name: []const u8, │ │2274 + description: []const u8,│ │2275 + access: evt.Repo.Access,│ │2276 + }, │ │2277 + }, │ │2278 issue: struct { │ │2279 failure: ThreadFailure, │ │2280 fields: ?struct { │ ╰──────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯