aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbuild2/script/run.cxx43
-rw-r--r--libbuild2/test/rule.cxx17
-rw-r--r--tests/recipe/buildscript/testscript22
3 files changed, 70 insertions, 12 deletions
diff --git a/libbuild2/script/run.cxx b/libbuild2/script/run.cxx
index b90ba48..8c71b32 100644
--- a/libbuild2/script/run.cxx
+++ b/libbuild2/script/run.cxx
@@ -321,23 +321,44 @@ namespace build2
path dp ("diff");
process_path pp (run_search (dp, true));
- cstrings args {pp.recall_string ()};
-
- // If both files being compared won't be available on failure, then
- // instruct diff not to print the file paths. It seems that the only
- // way to achieve this is to abandon the output unified format in the
- // favor of the minimal output, which normally is still informative
- // enough for the troubleshooting (contains the difference line
- // numbers, etc).
- //
- if (avail_on_failure (eop, env) || avail_on_failure (op, env))
- args.push_back ("-u");
+ cstrings args {pp.recall_string (), "-u"};
// Ignore Windows newline fluff if that's what we are running on.
//
if (env.host.class_ == "windows")
args.push_back ("--strip-trailing-cr");
+ // Instruct diff not to print the file paths that won't be available
+ // on failure.
+ //
+ // It seems that the only portable way to achieve this is to abandon
+ // the output unified format in the favor of the minimal output.
+ // However, the FreeBSD's, OpenBSD's and GNU's (used on Linux, MacOS,
+ // Windows, and NetBSD) diff utilities support the -L option that
+ // allows to replace the compared file path(s) with custom string(s)
+ // in the utility output. We will use this option for both files if
+ // any of them won't be available on failure (note that we can't
+ // assign a label only for the second file).
+ //
+ // Add the -L option using the file name as its value if it won't be
+ // available on failure and its full path otherwise.
+ //
+ auto add_label = [&args, &env] (const path& p)
+ {
+ const char* s (p.string ().c_str ());
+
+ args.push_back ("-L");
+ args.push_back (avail_on_failure (p, env)
+ ? s
+ : path::traits_type::find_leaf (s));
+ };
+
+ if (!avail_on_failure (eop, env) || !avail_on_failure (op, env))
+ {
+ add_label (eop);
+ add_label (op);
+ }
+
args.push_back (eop.string ().c_str ());
args.push_back (op.string ().c_str ());
args.push_back (nullptr);
diff --git a/libbuild2/test/rule.cxx b/libbuild2/test/rule.cxx
index e1006d8..db490d9 100644
--- a/libbuild2/test/rule.cxx
+++ b/libbuild2/test/rule.cxx
@@ -866,7 +866,22 @@ namespace build2
if (cast<target_triplet> (tt[test_target]).class_ == "windows")
args.push_back ("--strip-trailing-cr");
- args.push_back (op.string ().c_str ());
+ const char* f (op.string ().c_str ());
+
+ // Note that unmatched program stdout will be referred by diff as '-'
+ // by default. Let's name it as 'stdout' for clarity and consistency
+ // with the buildscript diagnostics.
+ //
+ // Also note that the -L option is not portable but is supported by all
+ // the major implementations (see script/run.cxx for details).
+ //
+ args.push_back ("-L");
+ args.push_back (f);
+
+ args.push_back ("-L");
+ args.push_back ("stdout");
+
+ args.push_back (f);
args.push_back ("-");
args.push_back (nullptr);
}
diff --git a/tests/recipe/buildscript/testscript b/tests/recipe/buildscript/testscript
index 26718df..551f64a 100644
--- a/tests/recipe/buildscript/testscript
+++ b/tests/recipe/buildscript/testscript
@@ -85,3 +85,25 @@
$* clean 2>-
}
+
+: diff-label
+:
+{
+ echo 'bar' >=bar;
+
+ cat <<EOI >=buildfile;
+ foo: bar
+ {{
+ echo 'baz' >? $path($<)
+ }}
+ EOI
+
+ $* 2>>/~%EOE% != 0;
+ %.+
+ %--- .+/bar%
+ +++ stdout
+ %.+
+ EOE
+
+ $* clean 2>-
+}