gather.ha (1766B)
1 // SPDX-License-Identifier: GPL-3.0-only 2 // (c) Hare authors <https://harelang.org> 3 4 use fs; 5 use hare::ast; 6 use hare::module; 7 use os; 8 use path; 9 use strings; 10 11 export fn gather(ctx: *context, input: str) ([]module::module | error) = { 12 let mods: []module::module = []; 13 path::set(&buf, input)!; 14 module::gather(&ctx.ctx, &mods, ["rt"])?; 15 if (ctx.test) { 16 module::gather(&ctx.ctx, &mods, ["test"])?; 17 }; 18 if (!ctx.release) { 19 module::gather(&ctx.ctx, &mods, ["debug"])?; 20 }; 21 const nsubmods = if (ctx.submods) { 22 let id: ast::ident = []; 23 defer ast::ident_free(id); 24 yield gather_submodules(&ctx.ctx, &mods, &buf, &id)?; 25 } else 0z; 26 27 ctx.top = match (module::gather(&ctx.ctx, &mods, &buf)) { 28 case let top: size => 29 yield top; 30 case let e: module::error => 31 if (!(unwrap_module_error(e) is module::not_found) 32 || nsubmods == 0) { 33 return e; 34 }; 35 // running `hare test` with no args in a directory which isn't a 36 // module 37 // add a dummy module so the driver knows where in the cache to 38 // put the test runner binary 39 append(mods, module::module { 40 path = strings::dup(input), 41 ... 42 }); 43 yield len(mods) - 1; 44 }; 45 return mods; 46 }; 47 48 fn gather_submodules( 49 ctx: *module::context, 50 mods: *[]module::module, 51 buf: *path::buffer, 52 mod: *ast::ident, 53 ) (size | error) = { 54 let n = 0z; 55 let it = os::iter(path::string(buf))?; 56 defer fs::finish(it); 57 58 for (let dir => module::next(it)?) { 59 path::push(buf, dir.name)?; 60 defer path::pop(buf); 61 append(mod, dir.name); 62 defer delete(mod[len(mod) - 1]); 63 match (module::gather(ctx, mods, *mod)) { 64 case size => 65 n += 1; 66 case let e: module::error => 67 if (!(unwrap_module_error(e) is module::not_found)) { 68 return e; 69 }; 70 }; 71 n += gather_submodules(ctx, mods, buf, mod)?; 72 }; 73 return n; 74 };