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 };