Lindenii Project Forge
Warning: Due to various recent migrations, viewing non-HEAD refs may be broken.
/cmd/write-tests/main.ha (raw)
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);
};