ww: unify directory package-test products
This commit is contained in:
@@ -24,7 +24,12 @@ type pkgfolder = struct {
|
||||
type pkggroup = struct {
|
||||
dir: str,
|
||||
pkg: str,
|
||||
external: bool,
|
||||
prodpkg: str,
|
||||
samepkg: str,
|
||||
externalpkg: str,
|
||||
hassame: bool,
|
||||
hasexternal: bool,
|
||||
notests: bool,
|
||||
production: bool,
|
||||
plan: i32,
|
||||
root: str,
|
||||
@@ -1299,8 +1304,6 @@ fn pkglabel(g: *pkggroup) void = {
|
||||
pkgput(os.STDOUT_FILENO, g.dir);
|
||||
pkgput(os.STDOUT_FILENO, " [");
|
||||
pkgput(os.STDOUT_FILENO, g.pkg);
|
||||
if (g.external) { pkgput(os.STDOUT_FILENO, ", external"); }
|
||||
else { pkgput(os.STDOUT_FILENO, ", same-package"); };
|
||||
pkgput(os.STDOUT_FILENO, "]");
|
||||
};
|
||||
|
||||
@@ -1331,11 +1334,11 @@ fn pkgstartbuild(p: *pkgplan, groups: []pkggroup, builder: str, includes: []str,
|
||||
libdirs: []str, libs: []str, h: *exec.process) bool = {
|
||||
let nproducts: i32 = p.end - p.start;
|
||||
let capacity: i32 = 16;
|
||||
if (nproducts < 0 || nproducts > (PKG_COUNT_MAX - capacity) / 6) {
|
||||
if (nproducts < 0 || nproducts > (PKG_COUNT_MAX - capacity) / 9) {
|
||||
pkgputln(os.STDERR_FILENO, "wwtest package: package graph is too large");
|
||||
return false;
|
||||
};
|
||||
capacity += nproducts * 6;
|
||||
capacity += nproducts * 9;
|
||||
if (includes.len > (PKG_COUNT_MAX - capacity) / 2) {
|
||||
pkgputln(os.STDERR_FILENO, "wwtest package: package graph is too large");
|
||||
return false;
|
||||
@@ -1379,11 +1382,15 @@ fn pkgstartbuild(p: *pkgplan, groups: []pkggroup, builder: str, includes: []str,
|
||||
for (i < p.end) {
|
||||
let g: *pkggroup = &groups[i];
|
||||
append(ba, "--ww-package-test");
|
||||
if (g.production) { append(ba, "production"); }
|
||||
else { if (g.external) { append(ba, "external"); }
|
||||
else { append(ba, "same"); };
|
||||
};
|
||||
if (p.buildonly) { append(ba, "build"); }
|
||||
else { append(ba, "test"); };
|
||||
append(ba, g.pkg);
|
||||
if (g.prodpkg.len != 0) { append(ba, g.prodpkg); }
|
||||
else { append(ba, "-"); };
|
||||
if (g.hassame) { append(ba, g.samepkg); }
|
||||
else { append(ba, "-"); };
|
||||
if (g.hasexternal) { append(ba, g.externalpkg); }
|
||||
else { append(ba, "-"); };
|
||||
append(ba, g.dir);
|
||||
append(ba, g.bin);
|
||||
append(ba, g.buildok);
|
||||
@@ -1469,7 +1476,7 @@ fn pkgstartrun(g: *pkggroup, filters: []str, timeoutarg: str,
|
||||
};
|
||||
|
||||
fn pkgproductbuilt(g: *pkggroup, buildonly: bool) bool = {
|
||||
if (buildonly) { return pkgisreg(g.buildok); };
|
||||
if (buildonly || g.notests) { return pkgisreg(g.buildok); };
|
||||
return pkgisreg(g.buildok) && pkgisreg(g.bin);
|
||||
};
|
||||
|
||||
@@ -1480,6 +1487,12 @@ fn pkgrunok(g: *pkggroup) bool = {
|
||||
};
|
||||
|
||||
fn pkgemitgroup(g: *pkggroup, compileonly: bool) bool = {
|
||||
if (g.notests) {
|
||||
pkgput(os.STDOUT_FILENO, "? ");
|
||||
pkgput(os.STDOUT_FILENO, g.dir);
|
||||
pkgputln(os.STDOUT_FILENO, " [no tests]");
|
||||
return true;
|
||||
};
|
||||
if (compileonly) {
|
||||
pkgput(os.STDOUT_FILENO, "built ");
|
||||
pkglabel(g);
|
||||
@@ -1494,15 +1507,6 @@ fn pkgemitgroup(g: *pkggroup, compileonly: bool) bool = {
|
||||
pkgfailpath(g.root, "cannot read test capture");
|
||||
return false;
|
||||
};
|
||||
// The compiler-owned dispatcher is the authority on whether a variant
|
||||
// contains runnable tests. With an empty generated table, test.run returns
|
||||
// zero without output; no coordinator-side source scan is involved.
|
||||
if (pkgrunok(g) && runstdout.len == 0 && runstderr.len == 0) {
|
||||
pkgput(os.STDOUT_FILENO, "? ");
|
||||
pkgput(os.STDOUT_FILENO, g.dir);
|
||||
pkgputln(os.STDOUT_FILENO, " [no tests]");
|
||||
return true;
|
||||
};
|
||||
pkgput(os.STDOUT_FILENO, runstdout);
|
||||
pkgput(os.STDERR_FILENO, runstderr);
|
||||
if (!pkgrunok(g)) {
|
||||
@@ -1888,17 +1892,23 @@ export fn packagecommand(args: []str) int = {
|
||||
};
|
||||
i = 0;
|
||||
for (i < ds.paths.len) {
|
||||
let s: pkgsource;
|
||||
s.path = ds.paths[i];
|
||||
if (!pkgstring(&s.dir, pkgdirname(ds.paths[i]))) { return 1; };
|
||||
s.test = strings.hassuffix(pkgbase(ds.paths[i]), "_test.ww");
|
||||
if (buildonly && s.test) {
|
||||
s.pkg = "";
|
||||
append(srcs, s);
|
||||
i += 1;
|
||||
continue;
|
||||
};
|
||||
let body: str;
|
||||
let pn: str;
|
||||
if (!pkgread(ds.paths[i], &body) || !pkgclause(body, &pn)) {
|
||||
pkgfailpath(ds.paths[i], "invalid or missing package clause");
|
||||
return 1;
|
||||
};
|
||||
let s: pkgsource;
|
||||
s.path = ds.paths[i];
|
||||
if (!pkgstring(&s.dir, pkgdirname(ds.paths[i]))
|
||||
|| !pkgstring(&s.pkg, pn)) { return 1; };
|
||||
s.test = strings.hassuffix(pkgbase(ds.paths[i]), "_test.ww");
|
||||
if (!pkgstring(&s.pkg, pn)) { return 1; };
|
||||
append(srcs, s);
|
||||
i += 1;
|
||||
};
|
||||
@@ -1948,7 +1958,12 @@ export fn packagecommand(args: []str) int = {
|
||||
let g: pkggroup;
|
||||
g.dir = f.path;
|
||||
g.pkg = f.prodpkg;
|
||||
g.external = false;
|
||||
g.prodpkg = f.prodpkg;
|
||||
g.samepkg = "";
|
||||
g.externalpkg = "";
|
||||
g.hassame = false;
|
||||
g.hasexternal = false;
|
||||
g.notests = false;
|
||||
g.production = true;
|
||||
append(groups, g);
|
||||
} else {
|
||||
@@ -1970,64 +1985,110 @@ export fn packagecommand(args: []str) int = {
|
||||
i += 1;
|
||||
continue;
|
||||
};
|
||||
let family: str = f.prodpkg;
|
||||
let samepkg: str = "";
|
||||
let externalpkg: str = "";
|
||||
if (f.prodpkg.len != 0) {
|
||||
if (!pkgstring(&externalpkg, f.prodpkg, "_test")) { return 1; };
|
||||
};
|
||||
let standalonepkg: str = "";
|
||||
let hassame: bool = false;
|
||||
let hasexternal: bool = false;
|
||||
let sawtestfile: bool = false;
|
||||
let j: i32 = f.start;
|
||||
for (j < f.end) {
|
||||
if (srcs[j].test) {
|
||||
sawtestfile = true;
|
||||
if (f.prodpkg.len != 0
|
||||
&& strings.compare(srcs[j].pkg, f.prodpkg) != 0
|
||||
&& strings.compare(srcs[j].pkg, externalpkg) != 0) {
|
||||
pkgfailpath(srcs[j].path,
|
||||
"test package must match production package or <package>_test");
|
||||
return 1;
|
||||
};
|
||||
if (f.prodpkg.len == 0) {
|
||||
if (standalonepkg.len == 0) {
|
||||
standalonepkg = srcs[j].pkg;
|
||||
} else if (strings.compare(standalonepkg,
|
||||
srcs[j].pkg) != 0) {
|
||||
pkgfailpath(f.path,
|
||||
"test-only directory declares conflicting packages");
|
||||
if (f.prodpkg.len != 0) {
|
||||
let expectedexternal: str;
|
||||
if (!pkgstring(&expectedexternal, f.prodpkg, "_test")) {
|
||||
return 1;
|
||||
};
|
||||
let j: i32 = f.start;
|
||||
for (j < f.end) {
|
||||
if (srcs[j].test) {
|
||||
sawtestfile = true;
|
||||
if (strings.compare(srcs[j].pkg, f.prodpkg) == 0) {
|
||||
hassame = true;
|
||||
samepkg = srcs[j].pkg;
|
||||
} else if (strings.compare(srcs[j].pkg,
|
||||
expectedexternal) == 0) {
|
||||
hasexternal = true;
|
||||
externalpkg = srcs[j].pkg;
|
||||
} else {
|
||||
pkgfailpath(srcs[j].path,
|
||||
"test package must match production package or <package>_test");
|
||||
return 1;
|
||||
};
|
||||
};
|
||||
let found: bool = false;
|
||||
let k: i32 = 0;
|
||||
for (k < groups.len) {
|
||||
if (strings.compare(groups[k].dir, f.path) == 0
|
||||
&& strings.compare(groups[k].pkg, srcs[j].pkg) == 0) {
|
||||
found = true;
|
||||
break;
|
||||
j += 1;
|
||||
};
|
||||
} else {
|
||||
let firstpkg: str = "";
|
||||
let secondpkg: str = "";
|
||||
let j: i32 = f.start;
|
||||
for (j < f.end) {
|
||||
if (srcs[j].test) {
|
||||
sawtestfile = true;
|
||||
if (firstpkg.len == 0) {
|
||||
firstpkg = srcs[j].pkg;
|
||||
} else if (strings.compare(srcs[j].pkg, firstpkg) != 0
|
||||
&& secondpkg.len == 0) {
|
||||
secondpkg = srcs[j].pkg;
|
||||
} else if (strings.compare(srcs[j].pkg, firstpkg) != 0
|
||||
&& strings.compare(srcs[j].pkg, secondpkg) != 0) {
|
||||
pkgfailpath(srcs[j].path,
|
||||
"test package must match production package or <package>_test");
|
||||
return 1;
|
||||
};
|
||||
k += 1;
|
||||
};
|
||||
if (!found) {
|
||||
let g: pkggroup;
|
||||
g.dir = f.path;
|
||||
g.pkg = srcs[j].pkg;
|
||||
g.external = f.prodpkg.len != 0
|
||||
&& strings.compare(f.prodpkg, g.pkg) != 0;
|
||||
g.production = false;
|
||||
append(groups, g);
|
||||
j += 1;
|
||||
};
|
||||
if (secondpkg.len == 0) {
|
||||
if (strings.hassuffix(firstpkg, "_test")) {
|
||||
family = firstpkg[0:(firstpkg.len - 5)];
|
||||
if (family.len == 0) {
|
||||
pkgfailpath(f.path,
|
||||
"external test package has empty base name");
|
||||
return 1;
|
||||
};
|
||||
hasexternal = true;
|
||||
externalpkg = firstpkg;
|
||||
} else {
|
||||
family = firstpkg;
|
||||
hassame = true;
|
||||
samepkg = firstpkg;
|
||||
};
|
||||
} else {
|
||||
let firstexternal: str;
|
||||
let secondexternal: str;
|
||||
if (!pkgstring(&firstexternal, firstpkg, "_test")
|
||||
|| !pkgstring(&secondexternal, secondpkg, "_test")) {
|
||||
return 1;
|
||||
};
|
||||
if (strings.compare(secondpkg, firstexternal) == 0) {
|
||||
family = firstpkg;
|
||||
hassame = true;
|
||||
samepkg = firstpkg;
|
||||
hasexternal = true;
|
||||
externalpkg = secondpkg;
|
||||
} else if (strings.compare(firstpkg, secondexternal) == 0) {
|
||||
family = secondpkg;
|
||||
hassame = true;
|
||||
samepkg = secondpkg;
|
||||
hasexternal = true;
|
||||
externalpkg = firstpkg;
|
||||
} else {
|
||||
pkgfailpath(f.path,
|
||||
"test package must match production package or <package>_test");
|
||||
return 1;
|
||||
};
|
||||
};
|
||||
j += 1;
|
||||
};
|
||||
if (!sawtestfile) {
|
||||
let g: pkggroup;
|
||||
g.dir = f.path;
|
||||
g.pkg = f.prodpkg;
|
||||
if (g.pkg.len == 0) { g.pkg = srcs[f.start].pkg; };
|
||||
g.external = false;
|
||||
g.production = true;
|
||||
append(groups, g);
|
||||
};
|
||||
let g: pkggroup;
|
||||
g.dir = f.path;
|
||||
g.pkg = family;
|
||||
if (g.pkg.len == 0) { g.pkg = srcs[f.start].pkg; };
|
||||
g.prodpkg = f.prodpkg;
|
||||
g.samepkg = samepkg;
|
||||
g.externalpkg = externalpkg;
|
||||
g.hassame = hassame;
|
||||
g.hasexternal = hasexternal;
|
||||
g.notests = !sawtestfile;
|
||||
g.production = f.prodpkg.len != 0;
|
||||
append(groups, g);
|
||||
i += 1;
|
||||
};
|
||||
if (groups.len == 0) {
|
||||
@@ -2225,6 +2286,9 @@ export fn packagecommand(args: []str) int = {
|
||||
if (!pkgproductbuilt(g, buildonly)) {
|
||||
g.state = PKGDONE;
|
||||
productcompleted += 1;
|
||||
} else if (g.notests) {
|
||||
g.state = PKGDONE;
|
||||
productcompleted += 1;
|
||||
} else {
|
||||
if (!pkgstartrun(g, filters, timeoutarg, list,
|
||||
&runhandles[gi])) {
|
||||
|
||||
Reference in New Issue
Block a user