ww: recursive DIR/... package discovery for ww test
This commit is contained in:
@@ -88,7 +88,7 @@ fn pkgfailpath(path: str, reason: str) void = {
|
||||
|
||||
fn pkgusage() void = {
|
||||
let s: str = strings.concat(
|
||||
"usage: wwtest package [-c] [-list] [-j N] [-I DIR] [-run|-filter GLOB] [-timeout-ms=N] [DIR] [-- GLOB ...]\n",
|
||||
"usage: wwtest package [-c] [-list] [-j N] [-I DIR] [-run|-filter GLOB] [-timeout-ms=N] [DIR | DIR/...] [-- GLOB ...]\n",
|
||||
" *_test.ww is canonical; noncanonical files require an actual @test declaration\n",
|
||||
" -c retains the compiled package binaries; -j is reserved by sequential v1\n");
|
||||
pkgput(os.STDERR_FILENO, s);
|
||||
@@ -240,10 +240,12 @@ fn pkgkeepfile(name: str) bool = {
|
||||
return true;
|
||||
};
|
||||
|
||||
// The first vertical slice owns exactly one explicit package directory. It
|
||||
// never recurses, and lstat is used both for the root and each candidate so a
|
||||
// symlink cannot be used to cross that boundary (including DT_UNKNOWN files).
|
||||
fn pkgdiscoverdir(path: str, st: *pkgdiscover) void = {
|
||||
// One explicit package directory; with recurse (the DIR/... form) every
|
||||
// subdirectory whose name does not begin with '.' or '_' is descended as
|
||||
// well, Go's ./... convention. lstat is used for the root and each
|
||||
// candidate so a symlink cannot be used to cross the boundary (including
|
||||
// DT_UNKNOWN files); a symlinked subdirectory is skipped, not followed.
|
||||
fn pkgdiscoverdir(path: str, st: *pkgdiscover, recurse: bool) void = {
|
||||
let rootstat: os.filestat;
|
||||
match (os.lstat(&rootstat, path)) {
|
||||
case void => void;
|
||||
@@ -307,6 +309,22 @@ fn pkgdiscoverdir(path: str, st: *pkgdiscover) void = {
|
||||
st.errors += 1;
|
||||
};
|
||||
};
|
||||
} else if (recurse && name.len != 0
|
||||
&& name[0] != '.' && name[0] != '_') {
|
||||
let child: str = strings.concat(path, "/", name);
|
||||
let fi: os.filestat;
|
||||
match (os.lstat(&fi, child)) {
|
||||
case void => {
|
||||
if (pkgmodeis(fi.mode, os.mode.DIR)) {
|
||||
pkgdiscoverdir(child, st, true);
|
||||
};
|
||||
};
|
||||
case let e: os.oserror => {
|
||||
pkgfailpath(child,
|
||||
"cannot stat directory entry");
|
||||
st.errors += 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
off += reclen;
|
||||
};
|
||||
@@ -690,15 +708,28 @@ export fn packagecommand(args: []str) int = {
|
||||
"wwtest package: -j is reserved; sequential package scheduling is active");
|
||||
};
|
||||
|
||||
// Go's ./... form: a trailing "..." path element walks the tree
|
||||
// rooted at the prefix instead of one explicit directory.
|
||||
let discoverroot: str = roots[0];
|
||||
let recurse: bool = false;
|
||||
if (strings.compare(discoverroot, "...") == 0) {
|
||||
discoverroot = ".";
|
||||
recurse = true;
|
||||
} else if (strings.hassuffix(discoverroot, "/...")) {
|
||||
discoverroot = discoverroot[0:discoverroot.len - 4];
|
||||
if (discoverroot.len == 0) { discoverroot = "/"; };
|
||||
recurse = true;
|
||||
};
|
||||
|
||||
let ds: pkgdiscover;
|
||||
let discoveredpaths: []str = alloc([], 64u64)!;
|
||||
ds.paths = discoveredpaths;
|
||||
ds.errors = 0;
|
||||
pkgdiscoverdir(roots[0], &ds);
|
||||
pkgdiscoverdir(discoverroot, &ds, recurse);
|
||||
if (ds.errors != 0) { return 1; };
|
||||
pkgsort(ds.paths);
|
||||
if (ds.paths.len == 0) {
|
||||
pkgfailpath(roots[0], "directory contains no WW package sources");
|
||||
pkgfailpath(discoverroot, "directory contains no WW package sources");
|
||||
return 1;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user