aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2021-04-20 22:48:59 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2021-04-21 17:15:28 +0300
commit09c231965f9f8e8f1e86f127a22f112d63ef4d9b (patch)
treee1a8689a0053099719722ba45d35aa33d229fc1e
parent30da2a90b3d433160c06643fb7ca51722fbae6b8 (diff)
Add buildscript depdb builtin 'env' command
-rw-r--r--libbuild2/build/script/parser.cxx29
-rw-r--r--libbuild2/build/script/parser.hxx13
-rw-r--r--libbuild2/script/parser.cxx2
-rw-r--r--libbuild2/script/run.cxx2
-rw-r--r--libbuild2/script/script.cxx28
-rw-r--r--libbuild2/script/script.hxx9
-rw-r--r--tests/recipe/buildscript/testscript62
7 files changed, 127 insertions, 18 deletions
diff --git a/libbuild2/build/script/parser.cxx b/libbuild2/build/script/parser.cxx
index 4c11688..372c622 100644
--- a/libbuild2/build/script/parser.cxx
+++ b/libbuild2/build/script/parser.cxx
@@ -481,7 +481,7 @@ namespace build2
next (t, tt);
if (tt != type::word ||
- (v != "clear" && v != "hash" && v != "string"))
+ (v != "clear" && v != "hash" && v != "string" && v != "env"))
{
fail (get_location (t))
<< "expected 'depdb' builtin command instead of " << t;
@@ -950,6 +950,33 @@ namespace build2
<< "'depdb string' argument change forcing update of "
<< ctx.env.target;});
}
+ else if (cmd == "env")
+ {
+ sha256 cs;
+ const char* pf ("invalid 'depdb env' argument: ");
+
+ try
+ {
+ // Skip <cmd>.
+ //
+ for (auto i (ns.begin () + 1); i != ns.end (); ++i)
+ {
+ string vn (convert<string> (move (*i)));
+ build2::script::verify_environment_var_name (vn, pf, ll);
+ hash_environment (cs, vn);
+ }
+ }
+ catch (const invalid_argument& e)
+ {
+ fail (ll) << pf << e;
+ }
+
+ if (ctx.dd.expect (cs.string ()) != nullptr)
+ l4 ([&] {
+ ctx.trace (ll)
+ << "'depdb env' environment change forcing update of "
+ << ctx.env.target;});
+ }
else
assert (false);
}
diff --git a/libbuild2/build/script/parser.hxx b/libbuild2/build/script/parser.hxx
index b5a45ca..15429e3 100644
--- a/libbuild2/build/script/parser.hxx
+++ b/libbuild2/build/script/parser.hxx
@@ -194,13 +194,16 @@ namespace build2
// The depdb builtin can be used to change the default dependency
// change tracking:
//
- // depdb clear - Cancels the default variables, targets, and
- // prerequisites change tracking. Can only be
- // the first depdb builtin call.
+ // depdb clear - Cancel the default variables, targets, and
+ // prerequisites change tracking. Can only be
+ // the first depdb builtin call.
//
- // depdb hash <args> - Track the argument list change as a hash.
+ // depdb hash <args> - Track the argument list change as a hash.
//
- // depdb string <arg> - Track the argument (single) change as string.
+ // depdb string <arg> - Track the argument (single) change as string.
+ //
+ // depdb env <var-names> - Track the environment variables change as a
+ // hash.
//
optional<location> depdb_clear_; // 'depdb clear' location if any.
lines depdb_preamble_; // Note: excludes 'depdb clear'.
diff --git a/libbuild2/script/parser.cxx b/libbuild2/script/parser.cxx
index 41d3092..ebfd5fc 100644
--- a/libbuild2/script/parser.cxx
+++ b/libbuild2/script/parser.cxx
@@ -1437,7 +1437,7 @@ namespace build2
}
else if (optional<string> v = str ("--unset", "-u"))
{
- verify_environment_var_name (*v, o.c_str (), "env: ", i->second);
+ verify_environment_var_name (*v, "env: ", i->second, o.c_str ());
r.variables.add (move (*v));
}
diff --git a/libbuild2/script/run.cxx b/libbuild2/script/run.cxx
index 3faa35c..f36e979 100644
--- a/libbuild2/script/run.cxx
+++ b/libbuild2/script/run.cxx
@@ -781,7 +781,7 @@ namespace build2
//
auto verify_name = [&ll] (const string& name, const char* opt)
{
- verify_environment_var_name (name, opt, "export: ", ll);
+ verify_environment_var_name (name, "export: ", ll, opt);
};
// Parse options (variable set/unset cleanups and unsets).
diff --git a/libbuild2/script/script.cxx b/libbuild2/script/script.cxx
index db53418..298d71f 100644
--- a/libbuild2/script/script.cxx
+++ b/libbuild2/script/script.cxx
@@ -818,18 +818,34 @@ namespace build2
//
void
verify_environment_var_name (const string& name,
- const char* opt,
const char* prefix,
- const location& l)
+ const location& l,
+ const char* opt)
{
if (name.empty ())
- fail (l) << prefix << "empty value for option " << opt;
+ {
+ diag_record dr (fail (l));
+ dr << prefix << "empty ";
+
+ if (opt == nullptr)
+ dr << "variable name";
+ else
+ dr << "value for option " << opt;
+ }
if (name.find ('=') != string::npos)
- fail (l) << prefix << "invalid value '" << name << "' for option "
- << opt << ": contains '='";
- }
+ {
+ diag_record dr (fail (l));
+ dr << prefix << "invalid ";
+
+ if (opt == nullptr)
+ dr << "variable name '" << name << "'";
+ else
+ dr << "value '" << name << "' for option " << opt;
+ dr << ": contains '='";
+ }
+ }
void
verify_environment_var_assignment (const string& var,
diff --git a/libbuild2/script/script.hxx b/libbuild2/script/script.hxx
index b4cb7fc..dd31e33 100644
--- a/libbuild2/script/script.hxx
+++ b/libbuild2/script/script.hxx
@@ -569,14 +569,15 @@ namespace build2
// Helpers.
//
- // Issue diagnostics with the specified prefix and fail if the string is
- // not a valid variable name or assignment (empty, etc).
+ // Issue diagnostics with the specified prefix and fail if the string
+ // (potentially an option value) is not a valid variable name or
+ // assignment (empty, etc).
//
void
verify_environment_var_name (const string&,
- const char* opt,
const char* prefix,
- const location&);
+ const location&,
+ const char* opt = nullptr);
void
verify_environment_var_assignment (const string&,
diff --git a/tests/recipe/buildscript/testscript b/tests/recipe/buildscript/testscript
index 14036dd..3ccfdd5 100644
--- a/tests/recipe/buildscript/testscript
+++ b/tests/recipe/buildscript/testscript
@@ -306,6 +306,68 @@ posix = ($cxx.target.class != 'windows')
$* clean 2>-
}
+ : env
+ :
+ {
+ : invalid
+ :
+ {
+ cat <<EOI >=buildfile;
+ foo:
+ {{
+ s = $getenv(FOO)
+
+ depdb clear
+ depdb env FOO=bar
+ echo "$s" >$path($>)
+ }}
+ EOI
+
+ $* 2>>/EOE != 0;
+ buildfile:6:3: error: invalid 'depdb env' argument: invalid variable name 'FOO=bar': contains '='
+ info: while updating file{foo}
+ info: while updating dir{./}
+ info: failed to update dir{./}
+ EOE
+
+ $* clean 2>-
+ }
+
+ : valid
+ :
+ {
+ cat <<EOI >=buildfile;
+ foo:
+ {{
+ s = $getenv(FOO)
+
+ depdb clear
+ depdb env FOO
+ echo "$s" >$path($>)
+ }}
+ EOI
+
+ export FOO=foo;
+
+ $* 2>'echo file{foo}';
+ cat <<<foo >'foo';
+
+ $* 2>/'info: dir{./} is up to date';
+
+ export FOO=bar;
+
+ $* 2>'echo file{foo}';
+ cat <<<foo >'bar';
+
+ export -u FOO;
+
+ $* 2>'echo file{foo}';
+ cat <<<foo >'';
+
+ $* clean 2>-
+ }
+ }
+
: preamble
:
{