tacker

a simple web bundler
git clone https://tongong.net/git/tacker.git
Log | Files | Refs | README

main.ha (2174B)


      1 use fmt;
      2 use fs;
      3 use getopt;
      4 use io;
      5 use os;
      6 use strings;
      7 
      8 export fn main() void = {
      9 	const cmd = getopt::parse(os::args,
     10 		"simple web bundler",
     11 		('f', "formats", "file formats to inline (comma seperated)"),
     12 		('p', "basepath", "for resolving modules (defaults to cwd)"),
     13 		"input-file",
     14 		"[output-file]",
     15 	);
     16 	defer getopt::finish(&cmd);
     17 
     18 	const alen = len(cmd.args);
     19 	if (alen == 0)
     20 		fmt::fatal("at least the input file is as argument needed.");
     21 	if (alen > 2) fmt::fatal("too many arguments passed.");
     22 
     23 	basepath = strings::join("", os::getcwd(), "/");
     24 	for (let i = 0z; i < len(cmd.opts); i += 1) {
     25 		if (cmd.opts[i].0 == 'p') {
     26 			free(basepath);
     27 			basepath = strings::join("",
     28 				realpath_resolve(cmd.opts[i].1), "/");
     29 			if (basepath == "//") basepath = strings::fromutf8(
     30 				strings::toutf8(basepath)[..1]);
     31 		};
     32 	};
     33 
     34 	const ifile = cmd.args[0];
     35 	const ofile = if (alen == 1) file_name_bundled(ifile)
     36 	else strings::dup(cmd.args[1]);
     37 	defer free(ofile);
     38 
     39 	const ofile = if (ofile == "-") os::stdout
     40 	else os::create(ofile, fs::mode::USER_RW | fs::mode::GROUP_R |
     41 		fs::mode::OTHER_R, fs::flags::WRONLY, fs::flags::TRUNC)!
     42 		: io::handle;
     43 	defer io::close(ofile)!;
     44 
     45 	const ifile = strings::join("", "./", ifile);
     46 	defer free(ifile);
     47 	const defaultfrom = strings::join("", os::getcwd(), "/");
     48 	defer free(defaultfrom);
     49 	const ifile = resolve_path(ifile, defaultfrom);
     50 	defer free(ifile);
     51 
     52 	let extstart = lastdotindex(ifile);
     53 	if (extstart == -1)
     54 		fixed_fatalf("{}: broken filetype.", ifile);
     55 	let ext = strings::fromutf8(strings::toutf8(ifile)[(extstart + 1)..]);
     56 
     57 	switch (ext) {
     58 	case "html" => tacker_html(ifile, ofile);
     59 	case "js" =>   tacker_js(ifile, ofile, false);
     60 	case "css" =>  tacker_css(ifile, ofile);
     61 	case => fixed_fatalf("{}: unknown filetype.", ifile);
     62 	};
     63 };
     64 
     65 // Should be replaced by fmt::fatalf when the issue with the compiler is fixed
     66 // https://todo.sr.ht/~sircmpwn/hare/717
     67 // Currently defer free() does not work correctly with @noreturn functions
     68 fn fixed_fatalf(fmt: str, args: fmt::field...) void = {
     69 	fmt::fatalf(fmt, args...);
     70 };
     71 
     72 fn warningf(fmt: str, args: fmt::field...) void = {
     73 	fmt::fprintfln(os::stderr, fmt, args...)!;
     74 };