From 2af2c4f092aa7efffe839ec615c06d22cf43cc3b Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Tue, 16 Mar 2021 20:21:59 +0300 Subject: Add support for interactive builds --- bbot/worker/worker.cxx | 519 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 353 insertions(+), 166 deletions(-) (limited to 'bbot/worker/worker.cxx') diff --git a/bbot/worker/worker.cxx b/bbot/worker/worker.cxx index bd880ae..3499ac4 100644 --- a/bbot/worker/worker.cxx +++ b/bbot/worker/worker.cxx @@ -16,6 +16,7 @@ #include #include +#include #include // to_utf8() #include #include @@ -147,33 +148,180 @@ catch (const system_error& e) fail << "unable to remove directory " << d << ": " << e << endf; } +// Step IDs. +// +enum class step_id +{ + bpkg_module_create, + bpkg_module_configure_add, + bpkg_module_configure_fetch, + bpkg_module_configure_build, + bpkg_module_update, + bpkg_module_test, + bpkg_create, + bpkg_configure_add, + bpkg_configure_fetch, + bpkg_configure_build, + bpkg_update, + bpkg_test, + bpkg_test_separate_configure_build, + bpkg_test_separate_update, + bpkg_test_separate_test, + bpkg_install, + b_test_installed_create, + b_test_installed_configure, + b_test_installed_test, + bpkg_test_installed_create, + bpkg_test_installed_configure_add, + bpkg_test_installed_configure_fetch, + bpkg_test_separate_installed_configure_build, + bpkg_test_separate_installed_update, + bpkg_test_separate_installed_test, + bpkg_uninstall +}; + +// @@ Feel a bit heavy-weight. Should we move to const char*[]? +// +static const strings step_id_str { + "bpkg.module.create", + "bpkg.module.configure.add", + "bpkg.module.configure.fetch", + "bpkg.module.configure.build", + "bpkg.module.update", + "bpkg.module.test", + "bpkg.create", + "bpkg.configure.add", + "bpkg.configure.fetch", + "bpkg.configure.build", + "bpkg.update", + "bpkg.test", + "bpkg.test-separate.configure.build", + "bpkg.test-separate.update", + "bpkg.test-separate.test", + "bpkg.install", + "b.test-installed.create", + "b.test-installed.configure", + "b.test-installed.test", + "bpkg.test-installed.create", + "bpkg.test-installed.configure.add", + "bpkg.test-installed.configure.fetch", + "bpkg.test-separate-installed.configure.build", + "bpkg.test-separate-installed.update", + "bpkg.test-separate-installed.test", + "bpkg.uninstall"}; + using std::regex; namespace regex_constants = std::regex_constants; using regexes = vector; -// Run a named command. Name is used for logging and diagnostics only. Match -// lines read from the command's stderr against the regular expressions and -// return the warning result status (instead of success) in case of a match. +// Run the worker script command. Name is used for logging and diagnostics +// only. Match lines read from the command's stderr against the regular +// expressions and return the warning result status (instead of success) in +// case of a match. Save the executed command into last_cmd. +// +// If bkp_step is present and is equal to the command step, then prior to +// running this command ask the user if to continue or abort the task +// execution. If bkp_status is present, then ask for that if the command +// execution results with the specified or more critical status. // template static result_status -run_cmd (tracer& t, +run_cmd (step_id step, + tracer& t, string& log, const regexes& warn_detect, const string& name, + const optional& bkp_step, + const optional& bkp_status, + string& last_cmd, const process_env& pe, A&&... a) { + // UTF-8-sanitize and log the diagnostics. Also print the raw diagnostics + // to stderr at verbosity level 3 or higher. + // + auto add = [&log, &t] (string&& s, bool trace = true) + { + if (verb >= 3) + { + if (trace) + t << s; + else + text << s; + } + + to_utf8 (s, '?', codepoint_types::graphic, U"\n\r\t"); + + log += s; + log += '\n'; + }; + + string next_cmd; + + // Prompt the user if to continue the task execution and, if they refuse, + // log this and throw abort. + // + struct abort {}; + + auto prompt = [&last_cmd, &next_cmd, &add] (const string& what) + { + diag_record dr (text); + + dr << '\n' + << what << '\n' + << " current dir: " << current_directory () << '\n' + << " environment: " << ops.environment (); + + if (!last_cmd.empty ()) + dr << '\n' + << " last command: " << last_cmd; + + if (!next_cmd.empty ()) + dr << '\n' + << " next command: " << next_cmd; + + dr.flush (); + + if (!yn_prompt ( + "continue execution (or you may shutdown the machine)? [y/n]")) + { + add ("execution aborted by interactive user"); + throw abort (); + } + }; + try { - // Trace and log the command line. + // Trace, log, and save the command line. // - auto cmdc = [&t, &log] (const char* c[], size_t n) + auto cmdc = [step, &t, &log, &bkp_step, &next_cmd, &prompt] + (const char* c[], size_t n) { - t (c, n); + const string& sid (step_id_str[static_cast (step)]); std::ostringstream os; process::print (os, c, n); - log += os.str (); + next_cmd = os.str (); + + // Prompt the user if the breakpoint is reached. + // + if (bkp_step && *bkp_step == step) + prompt (sid + " step is reached"); + + // Log the step id and the command to be executed. + // + l3 ([&]{t << "step id: " << sid;}); + +#ifndef _WIN32 + log += "# step id: "; +#else + log += "rem step id: "; +#endif + log += sid; + log += '\n'; + + t (c, n); + + log += next_cmd; log += '\n'; }; @@ -191,25 +339,6 @@ run_cmd (tracer& t, result_status r (result_status::success); - // UTF-8-sanitize and log the diagnostics. Also print the raw diagnostics - // to stderr at verbosity level 3 or higher. - // - auto add = [&log, &t] (string&& s, bool trace = true) - { - if (verb >= 3) - { - if (trace) - t << s; - else - text << s; - } - - to_utf8 (s, '?', codepoint_types::graphic, U"\n\r\t"); - - log += s; - log += '\n'; - }; - { ifdstream is (move (pipe.in), fdstream_mode::skip); // Skip on exception. @@ -242,14 +371,26 @@ run_cmd (tracer& t, } } - if (pr.wait ()) - return r; + if (!pr.wait ()) + { + const process_exit& e (*pr.exit); + add (name + " " + to_string (e)); + r = e.normal () ? result_status::error : result_status::abnormal; + } - const process_exit& e (*pr.exit); + last_cmd = move (next_cmd); - add (name + " " + to_string (e)); + if (bkp_status && r >= *bkp_status) + { + next_cmd.clear (); // Note: used by prompt(). + prompt (!r ? "error occured" : "warning is issued"); + } - return e.normal () ? result_status::error : result_status::abnormal; + return r; + } + catch (const abort&) + { + return result_status::abort; } catch (const process_error& e) { @@ -263,39 +404,55 @@ run_cmd (tracer& t, template static result_status -run_bpkg (const V& envvars, +run_bpkg (step_id step, + const V& envvars, tracer& t, string& log, const regexes& warn_detect, + const optional& bkp_step, + const optional& bkp_status, + string& last_cmd, const char* verbosity, const string& cmd, A&&... a) { - return run_cmd (t, + return run_cmd (step, + t, log, warn_detect, "bpkg " + cmd, + bkp_step, bkp_status, last_cmd, process_env ("bpkg", envvars), verbosity, cmd, forward (a)...); } template static result_status -run_bpkg (tracer& t, +run_bpkg (step_id step, + tracer& t, string& log, const regexes& warn_detect, + const optional& bkp_step, + const optional& bkp_status, + string& last_cmd, const char* verbosity, const string& cmd, A&&... a) { const char* const* envvars (nullptr); - return run_bpkg (envvars, + return run_bpkg (step, + envvars, t, log, warn_detect, + bkp_step, bkp_status, last_cmd, verbosity, cmd, forward (a)...); } template static result_status -run_b (const V& envvars, +run_b (step_id step, + const V& envvars, tracer& t, string& log, const regexes& warn_detect, + const optional& bkp_step, + const optional& bkp_status, + string& last_cmd, const char* verbosity, const strings& buildspecs, A&&... a) { @@ -308,39 +465,53 @@ run_b (const V& envvars, name += s; } - return run_cmd (t, + return run_cmd (step, + t, log, warn_detect, name, + bkp_step, bkp_status, last_cmd, process_env ("b", envvars), verbosity, buildspecs, forward (a)...); } template static result_status -run_b (const V& envvars, +run_b (step_id step, + const V& envvars, tracer& t, string& log, const regexes& warn_detect, + const optional& bkp_step, + const optional& bkp_status, + string& last_cmd, const char* verbosity, const string& buildspec, A&&... a) { - return run_cmd (t, + return run_cmd (step, + t, log, warn_detect, "b " + buildspec, + bkp_step, bkp_status, last_cmd, process_env ("b", envvars), verbosity, buildspec, forward (a)...); } template static result_status -run_b (tracer& t, +run_b (step_id step, + tracer& t, string& log, const regexes& warn_detect, + const optional& bkp_step, + const optional& bkp_status, + string& last_cmd, const char* verbosity, const string& buildspec, A&&... a) { const char* const* envvars (nullptr); - return run_b (envvars, + return run_b (step, + envvars, t, log, warn_detect, + bkp_step, bkp_status, last_cmd, verbosity, buildspec, forward (a)...); } @@ -507,71 +678,54 @@ build (size_t argc, const char* argv[]) for (const string& re: tm.unquoted_warning_regex ()) wre.emplace_back (re, f); - // Step IDs. + // Resolve the breakpoint specified by the interactive manifest value into + // the step id or the result status breakpoint. If the breakpoint is + // invalid, then log the error and abort the build. Note that we reuse the + // configure operation log here not to complicate things. // - enum class step_id + optional bkp_step; + optional bkp_status; + string last_cmd; // Used in the user prompt. + + if (tm.interactive) { - bpkg_module_create, - bpkg_module_configure_add, - bpkg_module_configure_fetch, - bpkg_module_configure_build, - bpkg_module_update, - bpkg_module_test, - bpkg_create, - bpkg_configure_add, - bpkg_configure_fetch, - bpkg_configure_build, - bpkg_update, - bpkg_test, - bpkg_test_separate_configure_build, - bpkg_test_separate_update, - bpkg_test_separate_test, - bpkg_install, - b_test_installed_create, - b_test_installed_configure, - b_test_installed_test, - bpkg_test_installed_create, - bpkg_test_installed_configure_add, - bpkg_test_installed_configure_fetch, - bpkg_test_separate_installed_configure_build, - bpkg_test_separate_installed_update, - bpkg_test_separate_installed_test, - bpkg_uninstall - }; + const string& b (*tm.interactive); + + if (b == "error") + bkp_status = result_status::error; + else if (b == "warning") + bkp_status = result_status::warning; + else + { + for (size_t i (0); i < step_id_str.size (); ++i) + { + if (b == step_id_str[i]) + { + bkp_step = static_cast (i); + break; + } + } + } - const strings step_id_str { - "bpkg.module.create", - "bpkg.module.configure.add", - "bpkg.module.configure.fetch", - "bpkg.module.configure.build", - "bpkg.module.update", - "bpkg.module.test", - "bpkg.create", - "bpkg.configure.add", - "bpkg.configure.fetch", - "bpkg.configure.build", - "bpkg.update", - "bpkg.test", - "bpkg.test-separate.configure.build", - "bpkg.test-separate.update", - "bpkg.test-separate.test", - "bpkg.install", - "b.test-installed.create", - "b.test-installed.configure", - "b.test-installed.test", - "bpkg.test-installed.create", - "bpkg.test-installed.configure.add", - "bpkg.test-installed.configure.fetch", - "bpkg.test-separate-installed.configure.build", - "bpkg.test-separate-installed.update", - "bpkg.test-separate-installed.test", - "bpkg.uninstall"}; + if (!bkp_step && !bkp_status) + { + string e ("invalid interactive build breakpoint '" + b + "'"); + + l3 ([&]{trace << e;}); + + operation_result& r (add_result ("configure")); + + r.log = "error: " + e + '\n'; + r.status = result_status::abort; + + break; + } + } // Split the argument into prefix (empty if not present) and unquoted // value. Return nullopt if the prefix is invalid. // - auto parse_arg = - [&step_id_str] (const string& a) -> optional> + auto parse_arg = [] (const string& a) -> optional> { size_t p (a.find_first_of (":=\"'")); @@ -660,10 +814,9 @@ build (size_t argc, const char* argv[]) // Return command arguments for the specified step id. Arguments with more // specific prefixes come last. // - auto step_args = [&step_id_str] (const std::multimap& args, - step_id step, - optional fallback = nullopt) - -> strings + auto step_args = [] (const std::multimap& args, + step_id step, + optional fallback = nullopt) -> strings { strings r; const string& sid (step_id_str[static_cast (step)]); @@ -807,11 +960,13 @@ build (size_t argc, const char* argv[]) // for the build2 process. Return true if the dist meta-operation // succeeds. // - auto redist = [&trace, &wre] (operation_result& r, - const dir_path& dist_root, - const dir_path& pkg_dir, // - - const char* import = nullptr, - const small_vector& envvars = {}) + auto redist = [&trace, &wre, &bkp_step, &bkp_status, &last_cmd] + (step_id step, + operation_result& r, + const dir_path& dist_root, + const dir_path& pkg_dir, // - + const char* import = nullptr, + const small_vector& envvars = {}) { // Temporarily change the current directory to the distribution root // parent directory from the configuration directory to shorten the @@ -832,8 +987,10 @@ build (size_t argc, const char* argv[]) dir_path redist_root ("re" + dn.string ()); r.status |= run_b ( + step, envvars, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-v", "config.dist.root=" + redist_root.string (), import, @@ -907,7 +1064,9 @@ build (size_t argc, const char* argv[]) // to cc. // r.status |= run_b ( + step_id::bpkg_module_create, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-V", "create(" + module_dir.representation () + ",cc)", "config.config.load=~build2", @@ -921,7 +1080,9 @@ build (size_t argc, const char* argv[]) // bpkg create --existing // r.status |= run_bpkg ( + step_id::bpkg_module_create, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-v", "create", "--existing"); @@ -934,7 +1095,9 @@ build (size_t argc, const char* argv[]) // bpkg.module.configure.add (bpkg.configure.add) // r.status |= run_bpkg ( + step_id::bpkg_module_configure_add, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-v", "add", @@ -956,7 +1119,9 @@ build (size_t argc, const char* argv[]) // bpkg.module.configure.fetch (bpkg.configure.fetch) // r.status |= run_bpkg ( + step_id::bpkg_module_configure_fetch, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-v", "fetch", @@ -978,7 +1143,9 @@ build (size_t argc, const char* argv[]) // [bpkg.module.configure.build] // r.status |= run_bpkg ( + step_id::bpkg_module_configure_build, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-v", "build", "--configure-only", @@ -1012,7 +1179,10 @@ build (size_t argc, const char* argv[]) // Note that we reuse the configure operation log for the dist // meta-operation. // - if (!redist (r, dist_root, pkg_dir)) + if (!redist (step_id::bpkg_module_configure_build, + r, + dist_root, + pkg_dir)) break; rm.status |= r.status; @@ -1035,7 +1205,9 @@ build (size_t argc, const char* argv[]) // [bpkg.module.update] // r.status |= run_bpkg ( + step_id::bpkg_module_update, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-v", "update", pkg); @@ -1069,7 +1241,9 @@ build (size_t argc, const char* argv[]) // [bpkg.module.test] // r.status |= run_bpkg ( + step_id::bpkg_module_test, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-v", "test", "--package-cwd", @@ -1113,7 +1287,9 @@ build (size_t argc, const char* argv[]) // importable in this configuration (see above about bootstrap). // r.status |= run_bpkg ( + step_id::bpkg_create, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-V", "create", "-d", build_dir.string (), @@ -1134,7 +1310,9 @@ build (size_t argc, const char* argv[]) // bpkg.configure.add // r.status |= run_bpkg ( + step_id::bpkg_configure_add, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-v", "add", step_args (env_args, step_id::bpkg_configure_add), @@ -1149,7 +1327,9 @@ build (size_t argc, const char* argv[]) // bpkg.configure.fetch // r.status |= run_bpkg ( + step_id::bpkg_configure_fetch, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-v", "fetch", step_args (env_args, step_id::bpkg_configure_fetch), @@ -1167,7 +1347,9 @@ build (size_t argc, const char* argv[]) if (!module) // Note: the module is already built in the pre-step. { r.status |= run_bpkg ( + step_id::bpkg_configure_build, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-v", "build", "--configure-only", @@ -1188,7 +1370,7 @@ build (size_t argc, const char* argv[]) if (dist) { - if (!redist (r, dist_root, pkg_dir)) + if (!redist (step_id::bpkg_configure_build, r, dist_root, pkg_dir)) break; rm.status |= r.status; @@ -1209,7 +1391,9 @@ build (size_t argc, const char* argv[]) // bpkg.update // r.status |= run_bpkg ( + step_id::bpkg_update, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-v", "update", step_args (env_args, step_id::bpkg_update), @@ -1288,6 +1472,7 @@ build (size_t argc, const char* argv[]) // as a special dependency for the test package. // auto test = [&trace, &wre, + &bkp_step, &bkp_status, &last_cmd, &step_args, &config_args, &env_args, &pm, &redist] @@ -1298,18 +1483,6 @@ build (size_t argc, const char* argv[]) const char* import = nullptr, const small_vector& envvars = {}) { - auto args = [installed, &step_args] ( - const std::multimap& args, - step_id test_separate_installed_step, - step_id test_separate_step, - step_id main_step) - { - return installed - ? step_args (args, test_separate_installed_step, main_step) - : step_args (args, test_separate_step, main_step); - - }; - for (const test_dependency& td: pm.tests) { const string& pkg (td.name.string ()); @@ -1321,25 +1494,22 @@ build (size_t argc, const char* argv[]) // // bpkg.test-separate[-installed].configure.build (bpkg.configure.build) // + step_id s (installed + ? step_id::bpkg_test_separate_installed_configure_build + : step_id::bpkg_test_separate_configure_build); + r.status |= run_bpkg ( + s, envvars, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-v", "build", "--configure-only", "--checkout-root", dist_root, "--yes", - - args (env_args, - step_id::bpkg_test_separate_installed_configure_build, - step_id::bpkg_test_separate_configure_build, - step_id::bpkg_configure_build), - - args (config_args, - step_id::bpkg_test_separate_installed_configure_build, - step_id::bpkg_test_separate_configure_build, - step_id::bpkg_configure_build), - + step_args (env_args, s, step_id::bpkg_configure_build), + step_args (config_args, s, step_id::bpkg_configure_build), import, "--", td.string (), @@ -1371,7 +1541,7 @@ build (size_t argc, const char* argv[]) dist_root); if (!pkg_dir.empty () && - !redist (r, dist_root, pkg_dir, import, envvars)) + !redist (s, r, dist_root, pkg_dir, import, envvars)) return false; } catch (const system_error& e) @@ -1385,22 +1555,19 @@ build (size_t argc, const char* argv[]) // // bpkg.test-separate[-installed].update (bpkg.update) // + s = installed + ? step_id::bpkg_test_separate_installed_update + : step_id::bpkg_test_separate_update; + r.status |= run_bpkg ( + s, envvars, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-v", "update", - - args (env_args, - step_id::bpkg_test_separate_installed_update, - step_id::bpkg_test_separate_update, - step_id::bpkg_update), - - args (config_args, - step_id::bpkg_test_separate_installed_update, - step_id::bpkg_test_separate_update, - step_id::bpkg_update), - + step_args (env_args, s, step_id::bpkg_update), + step_args (config_args, s, step_id::bpkg_update), import, pkg); @@ -1416,23 +1583,20 @@ build (size_t argc, const char* argv[]) // // bpkg.test-separate[-installed].test (bpkg.test) // + s = installed + ? step_id::bpkg_test_separate_installed_test + : step_id::bpkg_test_separate_test; + r.status |= run_bpkg ( + s, envvars, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-v", "test", "--package-cwd", // See above for details. - - args (env_args, - step_id::bpkg_test_separate_installed_test, - step_id::bpkg_test_separate_test, - step_id::bpkg_test), - - args (config_args, - step_id::bpkg_test_separate_installed_test, - step_id::bpkg_test_separate_test, - step_id::bpkg_test), - + step_args (env_args, s, step_id::bpkg_test), + step_args (config_args, s, step_id::bpkg_test), import, pkg); @@ -1465,7 +1629,9 @@ build (size_t argc, const char* argv[]) // bpkg.test // r.status |= run_bpkg ( + step_id::bpkg_test, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-v", "test", "--package-cwd", // See above for details. @@ -1538,7 +1704,9 @@ build (size_t argc, const char* argv[]) // bpkg.install // r.status |= run_bpkg ( + step_id::bpkg_install, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-v", "install", step_args (env_args, step_id::bpkg_install), @@ -1634,7 +1802,9 @@ build (size_t argc, const char* argv[]) dir_path out_dir ("build-installed"); r.status |= run_b ( + step_id::b_test_installed_create, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-V", "create('" + out_dir.representation () + "'" + mods + ")", step_args (env_args, step_id::b_test_installed_create), @@ -1660,8 +1830,10 @@ build (size_t argc, const char* argv[]) dir_path subprj_out_dir (out_dir / d); r.status |= run_b ( + step_id::b_test_installed_configure, envvars, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-v", "configure('" + subprj_src_dir.representation () + "'@'" + @@ -1686,8 +1858,10 @@ build (size_t argc, const char* argv[]) // b.test-installed.test // r.status |= run_b ( + step_id::b_test_installed_test, envvars, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-v", test_specs, step_args (env_args, step_id::b_test_installed_test), @@ -1710,7 +1884,9 @@ build (size_t argc, const char* argv[]) dir_path config_dir ("build-installed-bpkg"); r.status |= run_bpkg ( + step_id::bpkg_test_installed_create, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-V", "create", "-d", config_dir.string (), @@ -1738,7 +1914,9 @@ build (size_t argc, const char* argv[]) // bpkg.test-installed.configure.add (bpkg.configure.add) // r.status |= run_bpkg ( + step_id::bpkg_test_installed_configure_add, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-v", "add", @@ -1760,7 +1938,9 @@ build (size_t argc, const char* argv[]) // bpkg.test-installed.configure.fetch (bpkg.configure.fetch) // r.status |= run_bpkg ( + step_id::bpkg_test_installed_configure_fetch, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-v", "fetch", @@ -1808,7 +1988,9 @@ build (size_t argc, const char* argv[]) // bpkg.uninstall // r.status |= run_bpkg ( + step_id::bpkg_uninstall, trace, r.log, wre, + bkp_step, bkp_status, last_cmd, "-v", "uninstall", step_args (env_args, step_id::bpkg_uninstall), @@ -1981,24 +2163,29 @@ startup () // strings os; + // Use the name=value notation for options to minimize the number of + // arguments passed to the environment setup executable. Note that the + // etc/environments/default-*.bat scripts can only handle the limited + // number of arguments. + // if (ops.systemd_daemon ()) os.push_back ("--systemd-daemon"); if (ops.verbose_specified ()) - { - os.push_back ("--verbose"); - os.push_back (to_string (ops.verbose ())); - } + os.push_back ("--verbose=" + to_string (ops.verbose ())); if (ops.tftp_host_specified ()) - { - os.push_back ("--tftp-host"); - os.push_back (ops.tftp_host ()); - } + os.push_back ("--tftp-host=" + ops.tftp_host ()); + + os.push_back (string ("--environment=") + pp.effect_string ()); // Note that we use the effective (absolute) path instead of recall since // we may have changed the CWD. // + // Also note that the worker can ask the user if to continue the task + // execution when the interactive build breakpoint is reached. Thus, we + // don't redirect stdin to /dev/null. + // // Exit code 2 signals abnormal termination but where the worker uploaded // the result itself. // @@ -2007,7 +2194,7 @@ startup () // nobody listening on the other end anymore). // string tg (tm.target.string ()); - switch (run_exit (trace, pp, tg, argv0.effect_string (), os)) + switch (run_io_exit (trace, 0, 2, 2, pp, tg, argv0.effect_string (), os)) { case 3: case 2: return 1; -- cgit v1.1