╭ try.zig ──────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
1 //! start a server with some fake data and then launch 2 //! the TUI. this provides a nice way to test things 3 //! out safely. 4 5 const std = @import("std"); 6 const hx = @import("haxy"); 7 const srv = hx.serve; 8 const evt = hx.event; 9 const xit = hx.xit; 10 const rp = xit.repo; 11 12 pub fn main() !void { 13 var gpa: std.heap.DebugAllocator(.{}) = .init; 14 defer _ = gpa.deinit(); 15 const allocator = gpa.allocator(); 16 17 var threaded = std.Io.Threaded.init(allocator, .{}); 18 defer threaded.deinit(); 19 const io = threaded.io(); 20 21 const temp_dir_name = "temp-try"; 22 23 // create the temp dir 24 const cwd = std.Io.Dir.cwd(); 25 var temp_dir_or_err = cwd.openDir(io, temp_dir_name, .{}); 26 if (temp_dir_or_err) |*temp_dir| { 27 temp_dir.close(io); 28 try cwd.deleteTree(io, temp_dir_name); 29 } else |_| {} 30 var temp_dir = try cwd.createDirPathOpen(io, temp_dir_name, .{}); 31 defer cwd.deleteTree(io, temp_dir_name) catch {}; 32 defer temp_dir.close(io); 33 34 const cwd_path = try std.process.currentPathAlloc(io, allocator); 35 defer allocator.free(cwd_path); 36 37 const server_path = try std.fs.path.join(allocator, &.{ cwd_path, temp_dir_name, "server" }); 38 defer allocator.free(server_path); 39 40 // create the admin repo 41 { 42 const work_path = try std.fs.path.join(allocator, &.{ cwd_path, temp_dir_name, "server", "admin" }); 43 defer allocator.free(work_path); 44 45 const repo_opts: rp.RepoOpts(.xit) = .{ .is_test = true }; 46 const Repo = rp.Repo(.xit, repo_opts); 47 var repo = try Repo.init(io, allocator, .{ .path = work_path }); 48 defer repo.deinit(io, allocator); 49 50 var arena = std.heap.ArenaAllocator.init(allocator); 51 defer arena.deinit(); 52 53 // define test events 54 55 var prng = std.Random.DefaultPrng.init(std.testing.random_seed); 56 57 const user_data = [_]struct { 58 name: []const u8, 59 display_name: []const u8, 60 email: []const u8, 61 }{ 62 .{ .name = "alice", .display_name = "Alice Example", .email = "alice@example.test" }, 63 .{ .name = "bob", .display_name = "Bob Smith", .email = "bob@example.test" }, 64 .{ .name = "carol", .display_name = "Carol Johnson", .email = "carol@example.test" }, 65 .{ .name = "dave", .display_name = "Dave Wilson", .email = "dave@example.test" }, 66 .{ .name = "eve", .display_name = "Eve Anderson", .email = "eve@example.test" }, 67 .{ .name = "frank", .display_name = "Frank Miller", .email = "frank@example.test" }, 68 .{ .name = "grace", .display_name = "Grace Lee", .email = "grace@example.test" }, 69 .{ .name = "henry", .display_name = "Henry Davis", .email = "henry@example.test" }, 70 .{ .name = "ivy", .display_name = "Ivy Martinez", .email = "ivy@example.test" }, 71 .{ .name = "jack", .display_name = "Jack Thompson", .email = "jack@example.test" }, 72 }; 73 74 const repo_data = [_]struct { 75 user_index: usize, 76 name: []const u8, 77 description: []const u8, 78 }{ 79 .{ .user_index = 0, .name = "ziglings", .description = "Learn the Zig programming language by fixing tiny broken programs" }, 80 .{ .user_index = 1, .name = "linux", .description = "Linux kernel source tree" }, 81 .{ .user_index = 2, .name = "kubernetes", .description = "Production-grade container orchestration" }, 82 .{ .user_index = 3, .name = "react", .description = "A declarative, efficient, and flexible JavaScript library for building user interfaces" }, 83 .{ .user_index = 4, .name = "typescript", .description = "TypeScript is a superset of JavaScript that compiles to clean JavaScript output" }, 84 .{ .user_index = 5, .name = "rust", .description = "Empowering everyone to build reliable and efficient software" }, 85 .{ .user_index = 6, .name = "go", .description = "The Go programming language" }, 86 .{ .user_index = 7, .name = "nodejs", .description = "Node.js JavaScript runtime" }, 87 .{ .user_index = 8, .name = "cpython", .description = "The Python programming language" }, 88 .{ .user_index = 9, .name = "docker", .description = "Container platform for developing, shipping, and running applications" }, 89 .{ .user_index = 0, .name = "vim", .description = "The ubiquitous text editor" }, 90 .{ .user_index = 1, .name = "neovim", .description = "Hyperextensible Vim-based text editor" }, 91 .{ .user_index = 2, .name = "emacs", .description = "GNU Emacs source code mirror" }, 92 .{ .user_index = 3, .name = "tmux", .description = "Terminal multiplexer" }, 93 .{ .user_index = 4, .name = "zsh", .description = "Mirror of the Z shell source code repository" }, 94 .{ .user_index = 5, .name = "git", .description = "Distributed version control system" }, 95 .{ .user_index = 6, .name = "mercurial", .description = "Source-control management tool" }, 96 .{ .user_index = 7, .name = "tensorflow", .description = "An end-to-end open source machine learning platform" }, 97 .{ .user_index = 8, .name = "pytorch", .description = "Tensors and dynamic neural networks in Python with strong GPU acceleration" }, 98 .{ .user_index = 9, .name = "numpy", .description = "The fundamental package for scientific computing with Python" }, 99 .{ .user_index = 0, .name = "pandas", .description = "Flexible and powerful data analysis and manipulation library for Python" }, 100 .{ .user_index = 1, .name = "scikit-learn", .description = "Machine learning in Python" }, 101 .{ .user_index = 2, .name = "nginx", .description = "High performance HTTP server and reverse proxy" }, 102 .{ .user_index = 3, .name = "redis", .description = "In-memory data structure store, used as a database, cache, and message broker" }, 103 .{ .user_index = 4, .name = "postgres", .description = "The world's most advanced open source relational database" }, 104 .{ .user_index = 5, .name = "sqlite", .description = "Self-contained, serverless, zero-configuration SQL database engine" }, 105 .{ .user_index = 6, .name = "mongodb", .description = "The MongoDB Database" }, 106 .{ .user_index = 7, .name = "elasticsearch", .description = "Free and open, distributed, RESTful search engine" }, 107 .{ .user_index = 8, .name = "kafka", .description = "Distributed event streaming platform" }, 108 .{ .user_index = 9, .name = "terraform", .description = "Infrastructure as code tool" }, 109 }; 110 111 var user_ids: [user_data.len][evt.event_id_size]u8 = undefined; 112 for (&user_ids) |*id| id.* = evt.EventWithId.randomId(prng.random()); 113 114 var repo_event_ids: [repo_data.len][evt.event_id_size]u8 = undefined; 115 for (&repo_event_ids) |*id| id.* = evt.EventWithId.randomId(prng.random()); 116 117 var password_hash_buf: [evt.User.password_hash_max_len]u8 = undefined; 118 const password_hash = try evt.User.hashPassword("correct horse battery staple", &password_hash_buf, io); 119 120 var events_to_consume: [user_data.len + repo_data.len]evt.EventWithId = undefined; 121 for (user_data, 0..) |u, i| { 122 events_to_consume[i] = .{ 123 .id = std.fmt.bytesToHex(user_ids[i], .lower), 124 .event = .{ 125 .user = .{ 126 .name = u.name, 127 .display_name = u.display_name, 128 .email = u.email, 129 .password_hash = password_hash, 130 }, 131 }, 132 }; 133 } 134 for (repo_data, 0..) |r, i| { 135 events_to_consume[user_data.len + i] = .{ 136 .id = std.fmt.bytesToHex(repo_event_ids[i], .lower), 137 .event = .{ 138 .repo = .{ 139 .user_id = &user_ids[r.user_index], 140 .name = r.name, 141 .description = r.description, 142 .enable_issue = true, 143 }, 144 }, 145 }; 146 } 147 148 // insert users and repos as commits in the repo 149 { 150 var json: std.Io.Writer.Allocating = .init(allocator); 151 defer json.deinit(); 152 153 for (events_to_consume) |event| { 154 json.clearRetainingCapacity(); 155 156 try std.json.Stringify.value(event, .{}, &json.writer); 157 158 // commit the event into a special branch 159 _ = try repo.commitAtRef(io, allocator, .{ .message = json.written() }, null, .{ .kind = .head, .name = "haxy/meta" }); 160 } 161 } 162 163 // consume events into the database 164 try evt.consume(repo_opts, io, allocator, &repo, .{ .kind = .head, .name = "haxy/meta" }); 165 } 166 167 // start server 168 169 var null_writer = std.Io.Writer.Discarding.init(&.{}); 170 var environ_map = std.process.Environ.Map.init(allocator); 171 defer environ_map.deinit(); 172 const run_opts = hx.main.RunOpts{ .out = &null_writer.writer, .err = &null_writer.writer, .environ_map = &environ_map }; 173 174 try srv.run(.xit, .{}, io, allocator, cwd_path, .{ 175 .data_dir = server_path, 176 .tui = true, 177 }, run_opts.err); 178 } 179