commit 8654334524c4632fd1d90b04d55c60f057ba3fa3
parent a2a917d168df847c44df0fb265f7eaf811a48d9c
Author: Drew DeVault <sir@cmpwn.com>
Date: Sun, 7 Mar 2021 15:21:29 -0500
hare::module: implement recursive dir scanning
Diffstat:
M | hare/module/scan.ha | | | 72 | +++++++++++++++++++++++++++++++++++++++++++++++++----------------------- |
1 file changed, 49 insertions(+), 23 deletions(-)
diff --git a/hare/module/scan.ha b/hare/module/scan.ha
@@ -18,10 +18,11 @@ use strio;
export fn scan(ctx: *context, path: path::path) (version | error) = {
let sha = sha256::sha256();
//defer! hash::close(sha);
- let inputs: []input = [];
- let deps: []ast::ident = [];
let iter = match (fs::iter(ctx.fs, path)) {
fs::wrongtype => {
+ // Single file case
+ let inputs: []input = [];
+ let deps: []ast::ident = [];
let ft = match (type_for_ext(path)) {
void => return module_not_found,
ft: filetype => ft,
@@ -45,32 +46,52 @@ export fn scan(ctx: *context, path: path::path) (version | error) = {
err: fs::error => return err,
iter: *fs::iterator => iter,
};
+ let ver = version { ... };
+ scan_directory(ctx, &ver, sha, path, iter)?;
+ ver.hash = hash::finish(sha);
+ return ver;
+};
+
+fn scan_directory(
+ ctx: *context,
+ ver: *version,
+ sha: *hash::hash,
+ path: path::path,
+ iter: *fs::iterator,
+) (void | error) = {
for (true) match (fs::next(iter)) {
void => break,
ent: fs::dirent => switch (ent.ftype) {
- fs::mode::DIR => void, // TODO
fs::mode::LINK => abort(), // TODO
- fs::mode::REG => if (eligible(ctx, ent.name)) {
+ fs::mode::DIR => {
+ let d = ent.name: []u8;
+ if (len(d) == 0 || (d[0] != '+': u32: u8
+ && d[0] != '-': u32: u8)) {
+ continue;
+ };
+ if (!eligible(ctx, ent.name, true)) {
+ continue;
+ };
+ let p = path::join(path, ent.name);
+ let iter = fs::iter(ctx.fs, p)?;
+ scan_directory(ctx, ver, sha, p, iter)?;
+ },
+ fs::mode::REG => if (eligible(ctx, ent.name, false)) {
let p = path::join(path, ent.name);
let st = fs::stat(ctx.fs, p)?;
let in = input {
path = p,
stat = st,
ft = type_for_ext(ent.name) as filetype,
- hash = scan_file(ctx, p, &deps)?,
+ hash = scan_file(ctx, p, &ver.depends)?,
...
};
- append(inputs, in);
+ append(ver.inputs, in);
hash::write(sha, in.hash);
},
* => void,
},
};
- return version {
- hash = hash::finish(sha),
- depends = deps,
- inputs = inputs,
- };
};
// Looks up a module by its identifier from HAREPATH, and returns a [version]
@@ -89,21 +110,23 @@ export fn lookup(ctx: *context, name: ast::ident) (version | error) = {
return module_not_found;
};
-fn eligible(ctx: *context, name: path::path) bool = {
+fn eligible(ctx: *context, name: path::path, dir: bool) bool = {
if (!utf8::valid(name: []u8)) {
return false;
};
- let eligible = false;
- const ext = path::extension(name);
- static const exts = [".ha", ".s"];
- for (let i = 0z; i < len(exts); i += 1) {
- if (exts[i] == ext) {
- eligible = true;
- break;
+ if (!dir) {
+ let eligible = false;
+ const ext = path::extension(name);
+ static const exts = [".ha", ".s"];
+ for (let i = 0z; i < len(exts); i += 1) {
+ if (exts[i] == ext) {
+ eligible = true;
+ break;
+ };
+ };
+ if (!eligible) {
+ return false;
};
- };
- if (!eligible) {
- return false;
};
// XXX: It might be nice if the stdlib offered search functions which
@@ -119,7 +142,10 @@ fn eligible(ctx: *context, name: path::path) bool = {
else if (m is void && p is size) p: size
else if (m: size < p: size) m: size
else p: size;
- let tags = b[i..(bytes::index(b, '.': u32: u8) as size)];
+ let tags = match (bytes::index(b, '.': u32: u8)) {
+ void => b[i..],
+ e: size => b[i..e],
+ };
let tags = match (parse_tags(strings::from_utf8_unsafe(tags))) {
void => return false,
t: []tag => t,