ww: grow package universes dynamically
This commit is contained in:
727
cmd/ww/main.c
727
cmd/ww/main.c
File diff suppressed because it is too large
Load Diff
@@ -35,6 +35,7 @@ type pkggroup = struct {
|
|||||||
runout: str,
|
runout: str,
|
||||||
runerr: str,
|
runerr: str,
|
||||||
state: i32,
|
state: i32,
|
||||||
|
runstartfailed: bool,
|
||||||
runres: exec.result,
|
runres: exec.result,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -52,6 +53,44 @@ type pkgplan = struct {
|
|||||||
buildres: exec.result,
|
buildres: exec.result,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
def PKG_COUNT_MAX: i32 = 2147483647;
|
||||||
|
def PKG_INITIAL_CAP: i32 = 8;
|
||||||
|
|
||||||
|
fn pkgallocstrs(cap: i32) ([]str | nomem) = {
|
||||||
|
let value: []str = alloc([], cap: u64)?;
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn pkgallocbytes(cap: i32) ([]u8 | nomem) = {
|
||||||
|
let value: []u8 = alloc([], cap: u64)?;
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn pkgallocsources(cap: i32) ([]pkgsource | nomem) = {
|
||||||
|
let value: []pkgsource = alloc([], cap: u64)?;
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn pkgallocfolders(cap: i32) ([]pkgfolder | nomem) = {
|
||||||
|
let value: []pkgfolder = alloc([], cap: u64)?;
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn pkgallocgroups(cap: i32) ([]pkggroup | nomem) = {
|
||||||
|
let value: []pkggroup = alloc([], cap: u64)?;
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn pkgallocplans(cap: i32) ([]pkgplan | nomem) = {
|
||||||
|
let value: []pkgplan = alloc([], cap: u64)?;
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn pkgallocprocesses(cap: i32) ([]exec.process | nomem) = {
|
||||||
|
let value: []exec.process = alloc([], cap: u64)?;
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
// Product and directory-plan process states for the bounded coordinator.
|
// Product and directory-plan process states for the bounded coordinator.
|
||||||
def PKGQUEUED: i32 = 0;
|
def PKGQUEUED: i32 = 0;
|
||||||
def PKGBUILDING: i32 = 1;
|
def PKGBUILDING: i32 = 1;
|
||||||
@@ -63,13 +102,88 @@ def pkgpoll: time.duration = 1000000i64: time.duration;
|
|||||||
type pkgdiscover = struct {
|
type pkgdiscover = struct {
|
||||||
paths: []str,
|
paths: []str,
|
||||||
errors: i32,
|
errors: i32,
|
||||||
|
fatal: bool,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn pkggrowcap(current: i32, need: i32) i32 = {
|
||||||
|
if (need < 0) { return -1; };
|
||||||
|
if (need <= current) { return current; };
|
||||||
|
let cap: i32 = current;
|
||||||
|
if (cap == 0) { cap = PKG_INITIAL_CAP; };
|
||||||
|
for (cap < need) {
|
||||||
|
if (cap > PKG_COUNT_MAX / 2) {
|
||||||
|
cap = PKG_COUNT_MAX;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
cap *= 2;
|
||||||
|
};
|
||||||
|
if (cap < need) { return -1; };
|
||||||
|
return cap;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn pkgappenddiscovered(st: *pkgdiscover, path: str) bool = {
|
||||||
|
if (st.paths.len == PKG_COUNT_MAX) {
|
||||||
|
pkgputln(os.STDERR_FILENO,
|
||||||
|
"wwtest package: package graph is too large");
|
||||||
|
st.errors += 1;
|
||||||
|
st.fatal = true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
let need: i32 = st.paths.len + 1;
|
||||||
|
if (need > st.paths.cap) {
|
||||||
|
let cap: i32 = pkggrowcap(st.paths.cap, need);
|
||||||
|
if (cap < 0) {
|
||||||
|
pkgputln(os.STDERR_FILENO,
|
||||||
|
"wwtest package: package graph is too large");
|
||||||
|
st.errors += 1;
|
||||||
|
st.fatal = true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
let allocation: ([]str | nomem) = pkgallocstrs(cap);
|
||||||
|
let next: []str;
|
||||||
|
match (allocation) {
|
||||||
|
case let value: []str => next = value;
|
||||||
|
case nomem => {
|
||||||
|
pkgputln(os.STDERR_FILENO,
|
||||||
|
"wwtest package: out of memory");
|
||||||
|
st.errors += 1;
|
||||||
|
st.fatal = true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
let n: i32 = st.paths.len;
|
||||||
|
next.len = cap;
|
||||||
|
let i: i32 = 0;
|
||||||
|
for (i < n) { next[i] = st.paths[i]; i += 1; };
|
||||||
|
next.len = n;
|
||||||
|
if (st.paths.ptr != nil) {
|
||||||
|
os.free(st.paths.ptr: *void,
|
||||||
|
(st.paths.cap: u64) * (size(str): u64));
|
||||||
|
};
|
||||||
|
st.paths = next;
|
||||||
|
};
|
||||||
|
append(st.paths, path);
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Preserve the caller's toolchain environment while pinning the locale and
|
// Preserve the caller's toolchain environment while pinning the locale and
|
||||||
// temporary directory used by the current build plan or test product.
|
// temporary directory used by the current build plan or test product.
|
||||||
fn toolenv(tmpdir: str) []str = {
|
fn toolenv(tmpdir: str, out: *[]str) bool = {
|
||||||
let inherited: []str = os.getenvs();
|
let inherited: []str = os.getenvs();
|
||||||
let env: []str = alloc([], (inherited.len + 2): u64)!;
|
if (inherited.len > PKG_COUNT_MAX - 2) {
|
||||||
|
pkgputln(os.STDERR_FILENO,
|
||||||
|
"wwtest package: package graph is too large");
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
let allocation: ([]str | nomem) = pkgallocstrs(inherited.len + 2);
|
||||||
|
let env: []str;
|
||||||
|
match (allocation) {
|
||||||
|
case let value: []str => env = value;
|
||||||
|
case nomem => {
|
||||||
|
pkgputln(os.STDERR_FILENO, "wwtest package: out of memory");
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
};
|
||||||
let i: i32 = 0;
|
let i: i32 = 0;
|
||||||
for (i < inherited.len) {
|
for (i < inherited.len) {
|
||||||
if (!strings.hasprefix(inherited[i], "TMPDIR=")
|
if (!strings.hasprefix(inherited[i], "TMPDIR=")
|
||||||
@@ -80,7 +194,8 @@ fn toolenv(tmpdir: str) []str = {
|
|||||||
};
|
};
|
||||||
append(env, "LC_ALL=C");
|
append(env, "LC_ALL=C");
|
||||||
append(env, strings.concat("TMPDIR=", tmpdir));
|
append(env, strings.concat("TMPDIR=", tmpdir));
|
||||||
return env;
|
*out = env;
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
fn pkgwrite(fd: i32, s: str) bool = {
|
fn pkgwrite(fd: i32, s: str) bool = {
|
||||||
@@ -125,8 +240,24 @@ fn pkgread(path: str, out: *str) bool = {
|
|||||||
case let v: i64 => n = v;
|
case let v: i64 => n = v;
|
||||||
case let e: os.oserror => { os.close(fd); return false; };
|
case let e: os.oserror => { os.close(fd); return false; };
|
||||||
};
|
};
|
||||||
if (n < 0i64) { os.close(fd); return false; };
|
if (n < 0i64 || n >= PKG_COUNT_MAX: i64) {
|
||||||
let b: []u8 = alloc([], (n + 1i64): u64)!;
|
os.close(fd);
|
||||||
|
if (n >= PKG_COUNT_MAX: i64) {
|
||||||
|
pkgputln(os.STDERR_FILENO,
|
||||||
|
"wwtest package: package graph is too large");
|
||||||
|
};
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
let allocation: ([]u8 | nomem) = pkgallocbytes((n + 1i64): i32);
|
||||||
|
let b: []u8;
|
||||||
|
match (allocation) {
|
||||||
|
case let value: []u8 => b = value;
|
||||||
|
case nomem => {
|
||||||
|
os.close(fd);
|
||||||
|
pkgputln(os.STDERR_FILENO, "wwtest package: out of memory");
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
};
|
||||||
b.len = (n + 1i64): i32;
|
b.len = (n + 1i64): i32;
|
||||||
let rr: (i64 | os.oserror) = os.readall(fd, b.ptr, n: u64);
|
let rr: (i64 | os.oserror) = os.readall(fd, b.ptr, n: u64);
|
||||||
os.close(fd);
|
os.close(fd);
|
||||||
@@ -275,6 +406,7 @@ fn pkgkeepfile(name: str) bool = {
|
|||||||
// canonical planning coalesces it with the target directory. Recursive child
|
// canonical planning coalesces it with the target directory. Recursive child
|
||||||
// symlinks remain skipped and symlink source files remain rejected.
|
// symlinks remain skipped and symlink source files remain rejected.
|
||||||
fn pkgdiscoverdir(path: str, st: *pkgdiscover, recurse: bool) void = {
|
fn pkgdiscoverdir(path: str, st: *pkgdiscover, recurse: bool) void = {
|
||||||
|
if (st.fatal) { return; };
|
||||||
let rootstat: os.filestat;
|
let rootstat: os.filestat;
|
||||||
match (os.lstat(&rootstat, path)) {
|
match (os.lstat(&rootstat, path)) {
|
||||||
case void => void;
|
case void => void;
|
||||||
@@ -305,7 +437,18 @@ fn pkgdiscoverdir(path: str, st: *pkgdiscover, recurse: bool) void = {
|
|||||||
st.errors += 1;
|
st.errors += 1;
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let buf: []u8 = alloc([], 8192u64)!;
|
let bufallocation: ([]u8 | nomem) = pkgallocbytes(8192);
|
||||||
|
let buf: []u8;
|
||||||
|
match (bufallocation) {
|
||||||
|
case let value: []u8 => buf = value;
|
||||||
|
case nomem => {
|
||||||
|
os.close(fd);
|
||||||
|
pkgputln(os.STDERR_FILENO, "wwtest package: out of memory");
|
||||||
|
st.errors += 1;
|
||||||
|
st.fatal = true;
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
};
|
||||||
buf.len = 8192;
|
buf.len = 8192;
|
||||||
let n: i64 = os.getdents64(fd, buf.ptr, 8192u64);
|
let n: i64 = os.getdents64(fd, buf.ptr, 8192u64);
|
||||||
for (n > 0i64) {
|
for (n > 0i64) {
|
||||||
@@ -335,7 +478,10 @@ fn pkgdiscoverdir(path: str, st: *pkgdiscover, recurse: bool) void = {
|
|||||||
"symlink source is not allowed");
|
"symlink source is not allowed");
|
||||||
st.errors += 1;
|
st.errors += 1;
|
||||||
} else if (pkgmodeis(fi.mode, os.mode.REG)) {
|
} else if (pkgmodeis(fi.mode, os.mode.REG)) {
|
||||||
append(st.paths, child);
|
if (!pkgappenddiscovered(st, child)) {
|
||||||
|
os.close(fd);
|
||||||
|
return;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
case let e: os.oserror => {
|
case let e: os.oserror => {
|
||||||
@@ -351,6 +497,7 @@ fn pkgdiscoverdir(path: str, st: *pkgdiscover, recurse: bool) void = {
|
|||||||
case void => {
|
case void => {
|
||||||
if (pkgmodeis(fi.mode, os.mode.DIR)) {
|
if (pkgmodeis(fi.mode, os.mode.DIR)) {
|
||||||
pkgdiscoverdir(child, st, true);
|
pkgdiscoverdir(child, st, true);
|
||||||
|
if (st.fatal) { os.close(fd); return; };
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
case let e: os.oserror => {
|
case let e: os.oserror => {
|
||||||
@@ -484,7 +631,12 @@ fn pkgremoveall(path: str) bool = {
|
|||||||
if (!pkgmodeis(opened.mode, os.mode.DIR)
|
if (!pkgmodeis(opened.mode, os.mode.DIR)
|
||||||
|| opened.inode != st.inode) { os.close(fd); return false; };
|
|| opened.inode != st.inode) { os.close(fd); return false; };
|
||||||
let ok: bool = true;
|
let ok: bool = true;
|
||||||
let buf: []u8 = alloc([], 8192u64)!;
|
let allocation: ([]u8 | nomem) = pkgallocbytes(8192);
|
||||||
|
let buf: []u8;
|
||||||
|
match (allocation) {
|
||||||
|
case let value: []u8 => buf = value;
|
||||||
|
case nomem => { os.close(fd); return false; };
|
||||||
|
};
|
||||||
buf.len = 8192;
|
buf.len = 8192;
|
||||||
let n: i64 = os.getdents64(fd, buf.ptr, 8192u64);
|
let n: i64 = os.getdents64(fd, buf.ptr, 8192u64);
|
||||||
for (n > 0i64) {
|
for (n > 0i64) {
|
||||||
@@ -643,9 +795,28 @@ fn pkgreportcommand(kind: str, g: *pkggroup, r: *exec.result) void = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
fn pkgstartbuild(p: *pkgplan, groups: []pkggroup, builder: str, includes: []str,
|
fn pkgstartbuild(p: *pkgplan, groups: []pkggroup, builder: str, includes: []str,
|
||||||
h: *exec.process) void = {
|
h: *exec.process) bool = {
|
||||||
let ba: []str = alloc([],
|
let nproducts: i32 = p.end - p.start;
|
||||||
(12 + (p.end - p.start) * 6 + includes.len * 2): u64)!;
|
let capacity: i32 = 12;
|
||||||
|
if (nproducts < 0 || nproducts > (PKG_COUNT_MAX - capacity) / 6) {
|
||||||
|
pkgputln(os.STDERR_FILENO, "wwtest package: package graph is too large");
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
capacity += nproducts * 6;
|
||||||
|
if (includes.len > (PKG_COUNT_MAX - capacity) / 2) {
|
||||||
|
pkgputln(os.STDERR_FILENO, "wwtest package: package graph is too large");
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
capacity += includes.len * 2;
|
||||||
|
let allocation: ([]str | nomem) = pkgallocstrs(capacity);
|
||||||
|
let ba: []str;
|
||||||
|
match (allocation) {
|
||||||
|
case let value: []str => ba = value;
|
||||||
|
case nomem => {
|
||||||
|
pkgputln(os.STDERR_FILENO, "wwtest package: out of memory");
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
};
|
||||||
append(ba, builder);
|
append(ba, builder);
|
||||||
append(ba, "test");
|
append(ba, "test");
|
||||||
append(ba, "-c");
|
append(ba, "-c");
|
||||||
@@ -682,10 +853,12 @@ fn pkgstartbuild(p: *pkgplan, groups: []pkggroup, builder: str, includes: []str,
|
|||||||
append(ba, p.workdir);
|
append(ba, p.workdir);
|
||||||
};
|
};
|
||||||
append(ba, p.dir);
|
append(ba, p.dir);
|
||||||
|
let env: []str;
|
||||||
|
if (!toolenv(p.root, &env)) { return false; };
|
||||||
let bcmd: exec.command;
|
let bcmd: exec.command;
|
||||||
bcmd.path = builder;
|
bcmd.path = builder;
|
||||||
bcmd.argv = ba;
|
bcmd.argv = ba;
|
||||||
bcmd.env = toolenv(p.root);
|
bcmd.env = env;
|
||||||
bcmd.dir = "";
|
bcmd.dir = "";
|
||||||
bcmd.stdoutpath = p.buildout;
|
bcmd.stdoutpath = p.buildout;
|
||||||
bcmd.stderrpath = p.builderr;
|
bcmd.stderrpath = p.builderr;
|
||||||
@@ -693,21 +866,37 @@ fn pkgstartbuild(p: *pkgplan, groups: []pkggroup, builder: str, includes: []str,
|
|||||||
bcmd.deadline.nsec = 0i64;
|
bcmd.deadline.nsec = 0i64;
|
||||||
bcmd.grace = 0i64: time.duration;
|
bcmd.grace = 0i64: time.duration;
|
||||||
exec.start(h, &bcmd);
|
exec.start(h, &bcmd);
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
fn pkgstartrun(g: *pkggroup, filters: []str, timeoutarg: str,
|
fn pkgstartrun(g: *pkggroup, filters: []str, timeoutarg: str,
|
||||||
list: bool, h: *exec.process) void = {
|
list: bool, h: *exec.process) bool = {
|
||||||
let ra: []str = alloc([], (filters.len + 4): u64)!;
|
if (filters.len > PKG_COUNT_MAX - 4) {
|
||||||
|
pkgputln(os.STDERR_FILENO,
|
||||||
|
"wwtest package: package graph is too large");
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
let allocation: ([]str | nomem) = pkgallocstrs(filters.len + 4);
|
||||||
|
let ra: []str;
|
||||||
|
match (allocation) {
|
||||||
|
case let value: []str => ra = value;
|
||||||
|
case nomem => {
|
||||||
|
pkgputln(os.STDERR_FILENO, "wwtest package: out of memory");
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
};
|
||||||
append(ra, g.bin);
|
append(ra, g.bin);
|
||||||
append(ra, strings.concat("-package=", g.pkg));
|
append(ra, strings.concat("-package=", g.pkg));
|
||||||
if (list) { append(ra, "-list"); };
|
if (list) { append(ra, "-list"); };
|
||||||
if (timeoutarg.len != 0) { append(ra, timeoutarg); };
|
if (timeoutarg.len != 0) { append(ra, timeoutarg); };
|
||||||
let i: i32 = 0;
|
let i: i32 = 0;
|
||||||
for (i < filters.len) { append(ra, filters[i]); i += 1; };
|
for (i < filters.len) { append(ra, filters[i]); i += 1; };
|
||||||
|
let env: []str;
|
||||||
|
if (!toolenv(g.root, &env)) { return false; };
|
||||||
let rcmd: exec.command;
|
let rcmd: exec.command;
|
||||||
rcmd.path = g.bin;
|
rcmd.path = g.bin;
|
||||||
rcmd.argv = ra;
|
rcmd.argv = ra;
|
||||||
rcmd.env = toolenv(g.root);
|
rcmd.env = env;
|
||||||
rcmd.dir = "";
|
rcmd.dir = "";
|
||||||
rcmd.stdoutpath = g.runout;
|
rcmd.stdoutpath = g.runout;
|
||||||
rcmd.stderrpath = g.runerr;
|
rcmd.stderrpath = g.runerr;
|
||||||
@@ -715,6 +904,7 @@ fn pkgstartrun(g: *pkggroup, filters: []str, timeoutarg: str,
|
|||||||
rcmd.deadline.nsec = 0i64;
|
rcmd.deadline.nsec = 0i64;
|
||||||
rcmd.grace = 0i64: time.duration;
|
rcmd.grace = 0i64: time.duration;
|
||||||
exec.start(h, &rcmd);
|
exec.start(h, &rcmd);
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
fn pkgproductbuilt(g: *pkggroup) bool = {
|
fn pkgproductbuilt(g: *pkggroup) bool = {
|
||||||
@@ -735,6 +925,7 @@ fn pkgemitgroup(g: *pkggroup, compileonly: bool) bool = {
|
|||||||
pkgputln(os.STDOUT_FILENO, g.bin);
|
pkgputln(os.STDOUT_FILENO, g.bin);
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
if (g.runstartfailed) { return false; };
|
||||||
let runstdout: str;
|
let runstdout: str;
|
||||||
let runstderr: str;
|
let runstderr: str;
|
||||||
if (!pkgread(g.runout, &runstdout) || !pkgread(g.runerr, &runstderr)) {
|
if (!pkgread(g.runout, &runstdout) || !pkgread(g.runerr, &runstderr)) {
|
||||||
@@ -791,9 +982,39 @@ export fn packagecommand(args: []str) int = {
|
|||||||
let list: bool = false;
|
let list: bool = false;
|
||||||
let jobs: i32 = 1;
|
let jobs: i32 = 1;
|
||||||
let afterdash: bool = false;
|
let afterdash: bool = false;
|
||||||
let roots: []str = alloc([], 2u64)!;
|
if (args.len == PKG_COUNT_MAX) {
|
||||||
let filters: []str = alloc([], (args.len + 1): u64)!;
|
pkgputln(os.STDERR_FILENO,
|
||||||
let includes: []str = alloc([], (args.len + 1): u64)!;
|
"wwtest package: package graph is too large");
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
let argcapacity: i32 = args.len + 1;
|
||||||
|
let rootallocation: ([]str | nomem) = pkgallocstrs(argcapacity);
|
||||||
|
let roots: []str;
|
||||||
|
match (rootallocation) {
|
||||||
|
case let value: []str => roots = value;
|
||||||
|
case nomem => {
|
||||||
|
pkgputln(os.STDERR_FILENO, "wwtest package: out of memory");
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
let filterallocation: ([]str | nomem) = pkgallocstrs(argcapacity);
|
||||||
|
let filters: []str;
|
||||||
|
match (filterallocation) {
|
||||||
|
case let value: []str => filters = value;
|
||||||
|
case nomem => {
|
||||||
|
pkgputln(os.STDERR_FILENO, "wwtest package: out of memory");
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
let includeallocation: ([]str | nomem) = pkgallocstrs(argcapacity);
|
||||||
|
let includes: []str;
|
||||||
|
match (includeallocation) {
|
||||||
|
case let value: []str => includes = value;
|
||||||
|
case nomem => {
|
||||||
|
pkgputln(os.STDERR_FILENO, "wwtest package: out of memory");
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
let timeoutarg: str = "";
|
let timeoutarg: str = "";
|
||||||
let outname: str = "";
|
let outname: str = "";
|
||||||
let workroot: str = "";
|
let workroot: str = "";
|
||||||
@@ -925,9 +1146,10 @@ export fn packagecommand(args: []str) int = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let ds: pkgdiscover;
|
let ds: pkgdiscover;
|
||||||
let discoveredpaths: []str = alloc([], 64u64)!;
|
let emptypaths: []str;
|
||||||
ds.paths = discoveredpaths;
|
ds.paths = emptypaths;
|
||||||
ds.errors = 0;
|
ds.errors = 0;
|
||||||
|
ds.fatal = false;
|
||||||
pkgdiscoverdir(discoverroot, &ds, recurse);
|
pkgdiscoverdir(discoverroot, &ds, recurse);
|
||||||
if (ds.errors != 0) { return 1; };
|
if (ds.errors != 0) { return 1; };
|
||||||
pkgsort(ds.paths);
|
pkgsort(ds.paths);
|
||||||
@@ -941,7 +1163,16 @@ export fn packagecommand(args: []str) int = {
|
|||||||
return 1;
|
return 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
let srcs: []pkgsource = alloc([], ds.paths.len: u64)!;
|
let sourceallocation: ([]pkgsource | nomem) =
|
||||||
|
pkgallocsources(ds.paths.len);
|
||||||
|
let srcs: []pkgsource;
|
||||||
|
match (sourceallocation) {
|
||||||
|
case let value: []pkgsource => srcs = value;
|
||||||
|
case nomem => {
|
||||||
|
pkgputln(os.STDERR_FILENO, "wwtest package: out of memory");
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
i = 0;
|
i = 0;
|
||||||
for (i < ds.paths.len) {
|
for (i < ds.paths.len) {
|
||||||
let body: str;
|
let body: str;
|
||||||
@@ -959,7 +1190,16 @@ export fn packagecommand(args: []str) int = {
|
|||||||
i += 1;
|
i += 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
let folders: []pkgfolder = alloc([], srcs.len: u64)!;
|
let folderallocation: ([]pkgfolder | nomem) =
|
||||||
|
pkgallocfolders(srcs.len);
|
||||||
|
let folders: []pkgfolder;
|
||||||
|
match (folderallocation) {
|
||||||
|
case let value: []pkgfolder => folders = value;
|
||||||
|
case nomem => {
|
||||||
|
pkgputln(os.STDERR_FILENO, "wwtest package: out of memory");
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
i = 0;
|
i = 0;
|
||||||
for (i < srcs.len) {
|
for (i < srcs.len) {
|
||||||
let f: pkgfolder;
|
let f: pkgfolder;
|
||||||
@@ -977,7 +1217,16 @@ export fn packagecommand(args: []str) int = {
|
|||||||
i = f.end;
|
i = f.end;
|
||||||
};
|
};
|
||||||
|
|
||||||
let groups: []pkggroup = alloc([], srcs.len: u64)!;
|
let groupallocation: ([]pkggroup | nomem) =
|
||||||
|
pkgallocgroups(srcs.len);
|
||||||
|
let groups: []pkggroup;
|
||||||
|
match (groupallocation) {
|
||||||
|
case let value: []pkggroup => groups = value;
|
||||||
|
case nomem => {
|
||||||
|
pkgputln(os.STDERR_FILENO, "wwtest package: out of memory");
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
i = 0;
|
i = 0;
|
||||||
for (i < folders.len) {
|
for (i < folders.len) {
|
||||||
let f: pkgfolder = folders[i];
|
let f: pkgfolder = folders[i];
|
||||||
@@ -1050,7 +1299,15 @@ export fn packagecommand(args: []str) int = {
|
|||||||
"wwtest package: cannot use -o with multiple packages");
|
"wwtest package: cannot use -o with multiple packages");
|
||||||
return 2;
|
return 2;
|
||||||
};
|
};
|
||||||
let plans: []pkgplan = alloc([], 1u64)!;
|
let planallocation: ([]pkgplan | nomem) = pkgallocplans(1);
|
||||||
|
let plans: []pkgplan;
|
||||||
|
match (planallocation) {
|
||||||
|
case let value: []pkgplan => plans = value;
|
||||||
|
case nomem => {
|
||||||
|
pkgputln(os.STDERR_FILENO, "wwtest package: out of memory");
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
let plan: pkgplan;
|
let plan: pkgplan;
|
||||||
plan.dir = discoverroot;
|
plan.dir = discoverroot;
|
||||||
plan.sourceroot = canonicalroot;
|
plan.sourceroot = canonicalroot;
|
||||||
@@ -1081,19 +1338,48 @@ export fn packagecommand(args: []str) int = {
|
|||||||
// Build the complete request in one command-owned package universe. Once
|
// Build the complete request in one command-owned package universe. Once
|
||||||
// the union build completes, successful products run under the same global
|
// the union build completes, successful products run under the same global
|
||||||
// -j bound. Emission stays in byte-sorted group order below.
|
// -j bound. Emission stays in byte-sorted group order below.
|
||||||
let handles: []exec.process = alloc([], plans.len: u64)!;
|
let handleallocation: ([]exec.process | nomem) =
|
||||||
|
pkgallocprocesses(plans.len);
|
||||||
|
let handles: []exec.process;
|
||||||
|
match (handleallocation) {
|
||||||
|
case let value: []exec.process => handles = value;
|
||||||
|
case nomem => {
|
||||||
|
pkgputln(os.STDERR_FILENO, "wwtest package: out of memory");
|
||||||
|
if (!pkgremoveall(tmproot)) {
|
||||||
|
pkgput(os.STDERR_FILENO,
|
||||||
|
"wwtest package: cleanup failed; retained ");
|
||||||
|
pkgputln(os.STDERR_FILENO, tmproot);
|
||||||
|
};
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
i = 0;
|
i = 0;
|
||||||
for (i < plans.len) {
|
for (i < plans.len) {
|
||||||
let h: exec.process;
|
let h: exec.process;
|
||||||
append(handles, h);
|
append(handles, h);
|
||||||
i += 1;
|
i += 1;
|
||||||
};
|
};
|
||||||
let runhandles: []exec.process = alloc([], groups.len: u64)!;
|
let runhandleallocation: ([]exec.process | nomem) =
|
||||||
|
pkgallocprocesses(groups.len);
|
||||||
|
let runhandles: []exec.process;
|
||||||
|
match (runhandleallocation) {
|
||||||
|
case let value: []exec.process => runhandles = value;
|
||||||
|
case nomem => {
|
||||||
|
pkgputln(os.STDERR_FILENO, "wwtest package: out of memory");
|
||||||
|
if (!pkgremoveall(tmproot)) {
|
||||||
|
pkgput(os.STDERR_FILENO,
|
||||||
|
"wwtest package: cleanup failed; retained ");
|
||||||
|
pkgputln(os.STDERR_FILENO, tmproot);
|
||||||
|
};
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
i = 0;
|
i = 0;
|
||||||
for (i < groups.len) {
|
for (i < groups.len) {
|
||||||
let h: exec.process;
|
let h: exec.process;
|
||||||
append(runhandles, h);
|
append(runhandles, h);
|
||||||
groups[i].state = PKGQUEUED;
|
groups[i].state = PKGQUEUED;
|
||||||
|
groups[i].runstartfailed = false;
|
||||||
i += 1;
|
i += 1;
|
||||||
};
|
};
|
||||||
let planlaunched: i32 = 0;
|
let planlaunched: i32 = 0;
|
||||||
@@ -1118,10 +1404,15 @@ export fn packagecommand(args: []str) int = {
|
|||||||
g.state = PKGDONE;
|
g.state = PKGDONE;
|
||||||
productcompleted += 1;
|
productcompleted += 1;
|
||||||
} else {
|
} else {
|
||||||
pkgstartrun(g, filters, timeoutarg, list,
|
if (!pkgstartrun(g, filters, timeoutarg, list,
|
||||||
&runhandles[gi]);
|
&runhandles[gi])) {
|
||||||
g.state = PKGRUNNING;
|
g.runstartfailed = true;
|
||||||
active += 1;
|
g.state = PKGDONE;
|
||||||
|
productcompleted += 1;
|
||||||
|
} else {
|
||||||
|
g.state = PKGRUNNING;
|
||||||
|
active += 1;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
filling = true;
|
filling = true;
|
||||||
break;
|
break;
|
||||||
@@ -1130,8 +1421,15 @@ export fn packagecommand(args: []str) int = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
if (!filling && planlaunched < plans.len) {
|
if (!filling && planlaunched < plans.len) {
|
||||||
pkgstartbuild(&plans[planlaunched], groups, builder, includes,
|
if (!pkgstartbuild(&plans[planlaunched], groups, builder,
|
||||||
&handles[planlaunched]);
|
includes, &handles[planlaunched])) {
|
||||||
|
if (!pkgremoveall(tmproot)) {
|
||||||
|
pkgput(os.STDERR_FILENO,
|
||||||
|
"wwtest package: cleanup failed; retained ");
|
||||||
|
pkgputln(os.STDERR_FILENO, tmproot);
|
||||||
|
};
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
plans[planlaunched].state = PKGBUILDING;
|
plans[planlaunched].state = PKGBUILDING;
|
||||||
active += 1;
|
active += 1;
|
||||||
planlaunched += 1;
|
planlaunched += 1;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user