hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

cache.ha (1615B)


      1 // SPDX-License-Identifier: GPL-3.0-only
      2 // (c) Hare authors <https://harelang.org>
      3 
      4 use fmt;
      5 use fs;
      6 use getopt;
      7 use os;
      8 use path;
      9 
     10 // TODO: flesh this out some more. we probably want to have some sort of
     11 // per-module statistics (how much space it's taking up in the cache and whether
     12 // it's up to date for each tagset) and maybe also some sort of auto-pruner
     13 // (only prune things that can no longer ever be considered up-to-date?) so that
     14 // people don't need to periodically run hare cache -c n order to avoid the
     15 // cache growing indefinitely
     16 
     17 fn cache(name: str, cmd: *getopt::command) (void | error) = {
     18 	let clear = false;
     19 	for (let opt .. cmd.opts) {
     20 		switch (opt.0) {
     21 		case 'c' =>
     22 			clear = true;
     23 		case => abort();
     24 		};
     25 	};
     26 	if (len(cmd.args) != 0) {
     27 		getopt::printusage(os::stderr, name, cmd.help)?;
     28 		os::exit(os::status::FAILURE);
     29 	};
     30 	let cachedir = harecache();
     31 
     32 	if (clear) {
     33 		os::rmdirall(cachedir)?;
     34 		fmt::println(cachedir, "(0 B)")?;
     35 		return;
     36 	};
     37 
     38 	os::mkdirs(cachedir, 0o755)!;
     39 	let buf = path::init(cachedir)?;
     40 	let sz = dirsize(&buf)?;
     41 	const suffix = ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"];
     42 	let i = 0z;
     43 	for (i < len(suffix) - 1 && sz >= 1024; i += 1) {
     44 		sz /= 1024;
     45 	};
     46 	fmt::printfln("{} ({} {})", cachedir, sz, suffix[i])?;
     47 };
     48 
     49 fn dirsize(buf: *path::buffer) (size | error) = {
     50 	let s = 0z;
     51 	let it = os::iter(path::string(buf))?;
     52 	defer fs::finish(it);
     53 
     54 	for (let d => fs::next(it)?) {
     55 		path::push(buf, d.name)?;
     56 		let stat = os::stat(path::string(buf))?;
     57 		s += stat.sz;
     58 		if (fs::isdir(stat.mode)) {
     59 			s += dirsize(buf)?;
     60 		};
     61 		path::pop(buf);
     62 	};
     63 	return s;
     64 };