hare

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

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