Lindenii Project Forge
Add random test program to write
use errors; use fmt; use fs; use getopt; use io; use os; use strings; use time; use time::date; use git; fn dupu8(s: str) []u8 = { const src = strings::toutf8(s); let dst: []u8 = alloc([], len(src))!; dst[..] = src; return dst; }; fn mkident(name: str, email: str) git::ident = { let now = time::now(time::clock::REALTIME); let d = date::localnow(); let z = date::zone(&d); let ofs = (z.zoff / time::SECOND): i32; // seconds? return git::ident{ name = dupu8(name), email = dupu8(email), when = now.sec, ofs = ofs, }; }; fn bail(msg: str) never = { fmt::errorfln("fatal: {}", msg)!; os::exit(1); }; fn usage(cmd: *getopt::command) void = { getopt::printusage(os::stderr, os::args[0], cmd.help)!; }; export fn main() void = { let repo_path: (str | void) = void; let cmd = getopt::parse( os::args, "create a test commit with random blobs and a tree, then print its OID", ('r', "repo", "path to bare repo or .git"), ); defer getopt::finish(&cmd); for (let opt .. cmd.opts) { switch (opt.0) { case 'r' => repo_path = opt.1; case => abort(); }; }; let rp: str = match (repo_path) { case void => usage(&cmd); os::exit(2); case let s: str => yield s; }; let r = match (git::repo_open(rp)) { case let rr: git::repo => fmt::errorfln("opened repo: {}", rp)!; yield rr; case let fe: fs::error => fmt::errorfln("open repo: {}", fs::strerror(fe))!; os::exit(1); }; defer git::repo_close(r); // Blobs const blob1_body = "blabla\n"; const blob2_body = "woah\n"; let b1 = match (git::blob_parse(strings::toutf8(blob1_body))) { case let bb: git::blob => fmt::errorfln("parsed blob #1 ({} bytes)", len(strings::toutf8(blob1_body)))!; yield bb; case => bail("OOM parsing blob #1"); }; let id1 = match (git::loose_write(r, b1)) { case let oid1: git::oid => const hex = git::oid_stringify(oid1)!; defer free(hex); fmt::errorfln("wrote blob #1: {}", hex)!; yield oid1; case let fe: fs::error => fmt::errorfln("write blob #1: {}", fs::strerror(fe))!; os::exit(1); case let ioe: io::error => fmt::errorfln("write blob #1: {}", io::strerror(ioe))!; os::exit(1); case let ee: errors::invalid => fmt::errorfln("write blob #1: {}", errors::strerror(ee))!; os::exit(1); case => bail("write blob #1: OOM"); }; git::blob_finish(b1); let b2 = match (git::blob_parse(strings::toutf8(blob2_body))) { case let bb: git::blob => fmt::errorfln("parsed blob #2 ({} bytes)", len(strings::toutf8(blob2_body)))!; yield bb; case => bail("OOM parsing blob #2"); }; let id2 = match (git::loose_write(r, b2)) { case let oid2: git::oid => const hex = git::oid_stringify(oid2)!; defer free(hex); fmt::errorfln("wrote blob #2: {}", hex)!; yield oid2; case let fe: fs::error => fmt::errorfln("write blob #2: {}", fs::strerror(fe))!; os::exit(1); case let ioe: io::error => fmt::errorfln("write blob #2: {}", io::strerror(ioe))!; os::exit(1); case let ee: errors::invalid => fmt::errorfln("write blob #2: {}", errors::strerror(ee))!; os::exit(1); case => bail("write blob #2: OOM"); }; git::blob_finish(b2); // Tree entries const MODE_BLOB: u32 = (0o100644: u32); let ents: []git::tree_entry = alloc([], 2)!; append(ents, git::tree_entry{ mode = MODE_BLOB, name = dupu8("a.txt"), oid = id1, })!; append(ents, git::tree_entry{ mode = MODE_BLOB, name = dupu8("b.txt"), oid = id2, })!; fmt::errorfln("constructed 2 tree entries")!; let t = git::tree{ entries = ents, }; // Tree let tree_id = match (git::loose_write(r, t)) { case let toid: git::oid => const hex = git::oid_stringify(toid)!; defer free(hex); fmt::errorfln("wrote tree: {}", hex)!; yield toid; case let fe: fs::error => fmt::errorfln("write tree: {}", fs::strerror(fe))!; os::exit(1); case let ioe: io::error => fmt::errorfln("write tree: {}", io::strerror(ioe))!; os::exit(1); case let ee: errors::invalid => fmt::errorfln("write tree: {}", errors::strerror(ee))!; os::exit(1); case => bail("write tree: OOM"); }; git::tree_finish(t); // Commit let author = mkident("Hare Example", "author@example.com"); let committer = mkident("Hare Example", "author@example.com"); let parents: []git::oid = []; let msg = dupu8("adfawjahlejfljljlj\n"); let c = git::commit{ tree = tree_id, parents = parents, author = author, committer = committer, message = msg, }; fmt::errorfln("constructed commit object")!; let commit_id = match (git::loose_write(r, c)) { case let coid: git::oid => const hex = git::oid_stringify(coid)!; defer free(hex); fmt::errorfln("wrote commit: {}", hex)!; fmt::println(hex)!; yield coid; case let fe: fs::error => fmt::errorfln("write commit: {}", fs::strerror(fe))!; os::exit(1); case let ioe: io::error => fmt::errorfln("write commit: {}", io::strerror(ioe))!; os::exit(1); case let ee: errors::invalid => fmt::errorfln("write commit: {}", errors::strerror(ee))!; os::exit(1); case => bail("write commit: OOM"); }; git::commit_finish(c); };