From 61c77b931a735a3305eabc3e1f0ae1a6cc4d3709 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 31 Jul 2020 16:57:51 +0300 Subject: Fix buildscript diagnostics so diff output is always in unified format Also make sure diff refers program stdout as 'stdout' rather than '-' in the test rule diagnostics. --- libbuild2/script/run.cxx | 43 +++++++++++++++++++++++++++---------- libbuild2/test/rule.cxx | 17 ++++++++++++++- tests/recipe/buildscript/testscript | 22 +++++++++++++++++++ 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 (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 <=buildfile; + foo: bar + {{ + echo 'baz' >? $path($<) + }} + EOI + + $* 2>>/~%EOE% != 0; + %.+ + %--- .+/bar% + +++ stdout + %.+ + EOE + + $* clean 2>- +} -- cgit v1.1