diff options
author | Karen Arutyunov <karen@codesynthesis.com> | 2020-05-26 14:55:40 +0300 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2020-05-27 14:38:01 +0200 |
commit | d6581aa9be74e83cc689bfdaae9aaf2e78287975 (patch) | |
tree | e741d2c6fcdb567d8c7b897d17f3f0ca2358d307 /libbuild2/build/script/script.cxx | |
parent | e6470e37093084251b7ee60a904a78e54d13e31b (diff) |
Create build script temporary directory on demand
Diffstat (limited to 'libbuild2/build/script/script.cxx')
-rw-r--r-- | libbuild2/build/script/script.cxx | 95 |
1 files changed, 91 insertions, 4 deletions
diff --git a/libbuild2/build/script/script.cxx b/libbuild2/build/script/script.cxx index d27a30a..e344b59 100644 --- a/libbuild2/build/script/script.cxx +++ b/libbuild2/build/script/script.cxx @@ -3,9 +3,11 @@ #include <libbuild2/build/script/script.hxx> +#include <libbutl/filesystem.mxx> + #include <libbuild2/target.hxx> -#include <libbuild2/script/parser.hxx> +#include <libbuild2/build/script/parser.hxx> using namespace std; @@ -32,7 +34,9 @@ namespace build2 target (t), vars (context, false /* global */) { - // Set special variables. + // Set special variables. Note that the $~ variable is set later and + // only if the temporary directory is required for the script + // execution (see create_temp_dir() for details). // { // $> @@ -64,8 +68,76 @@ namespace build2 } void environment:: - set_variable (string&& nm, names&& val, const string& attrs) + create_temp_dir () + { + // Create the temporary directory for this run regardless of the + // dry-run mode, since some commands still can be executed (see run() + // for details). This is also the reason why we are not using the + // build2 filesystem API that considers the dry-run mode. + // + // Note that the directory auto-removal is active. + // + dir_path& td (temp_dir.path); + + assert (td.empty ()); // Must be called once. + + try + { + td = dir_path::temp_path ("buildscript"); + } + catch (const system_error& e) + { + fail << "unable to obtain temporary directory for buildscript " + << "execution" << e; + } + + mkdir_status r; + + try + { + r = try_mkdir (td); + } + catch (const system_error& e) + { + fail << "unable to create temporary directory '" << td << "': " + << e << endf; + } + + // Note that the temporary directory can potentially stay after some + // abnormally terminated script run. Clean it up and reuse if that's + // the case. + // + if (r == mkdir_status::already_exists) + try + { + butl::rmdir_r (td, false /* dir */); + } + catch (const system_error& e) + { + fail << "unable to cleanup temporary directory '" << td << "': " + << e; + } + + // Set the $~ special variable. + // + value& v (assign (var_pool.insert<dir_path> ("~"))); + v = td; + + if (verb >= 3) + text << "mkdir " << td; + } + + void environment:: + set_variable (string&& nm, + names&& val, + const string& attrs, + const location& ll) { + // Check if we are trying to modify any of the special variables. + // + if (parser::special_variable (nm)) + fail (ll) << "attempt to set '" << nm << "' special variable"; + // Set the variable value and attributes. // const variable& var (var_pool.insert (move (nm))); @@ -80,7 +152,22 @@ namespace build2 lhs.assign (move (val), &var); else { - build2::script::parser p (context); + // If there is an error in the attributes string, our diagnostics + // will look like this: + // + // <attributes>:1:1 error: unknown value attribute x + // buildfile:10:1 info: while parsing attributes '[x]' + // + // Note that the attributes parsing error is the only reason for a + // failure. + // + auto df = make_diag_frame ( + [attrs, &ll](const diag_record& dr) + { + dr << info (ll) << "while parsing attributes '" << attrs << "'"; + }); + + parser p (context); p.apply_value_attributes (&var, lhs, value (move (val)), |