From 4a416fd328d685b0946e5e6f40e5ea18e9c1adf0 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Thu, 9 Feb 2017 16:35:03 +0300 Subject: Add support for &dir/*[*][/] test path cleanup syntax --- build2/test/script/runner.cxx | 57 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) (limited to 'build2/test/script/runner.cxx') diff --git a/build2/test/script/runner.cxx b/build2/test/script/runner.cxx index ffb95e8..bc3c1ce 100644 --- a/build2/test/script/runner.cxx +++ b/build2/test/script/runner.cxx @@ -672,12 +672,14 @@ namespace build2 continue; const path& p (c.path); + const path& l (p.leaf ()); + const string& ls (l.string ()); // Remove the directory recursively if not current. Fail otherwise. // Recursive removal of non-existing directory is not an error for // 'maybe' cleanup type. // - if (p.leaf ().string () == "***") + if (ls == "***") { // Cast to uint16_t to avoid ambiguity with libbutl::rmdir_r(). // @@ -697,6 +699,56 @@ namespace build2 : " doesn't match a directory"); } + // Remove files or directories using wildcard. Removal of sub-entries + // of non-existing directory is not an error for 'maybe' cleanup + // type. + // + // Note that only the leaf part of the cleanup wildcard is a pattern + // in terms of libbutl::path_search(). + // + if (ls == "*" || ls == "**") + { + dir_path d (p.directory ()); + + if (t == cleanup_type::always && !dir_exists (d)) + fail (ll) << "registered for cleanup wildcard " << p + << " doesn't match a directory"; + + if (l.to_directory ()) + { + auto rm = [&p, &d, &ll] (path&& de) -> bool + { + dir_path sd (path_cast (d / de)); + + // We can get not_exist here due to racing conditions, but + // that's ok if somebody did our job. + // + rmdir_status r (rmdir (sd, 2)); + + if (r != rmdir_status::not_empty) + return true; + + fail (ll) << "registered for cleanup directory " << sd + << " is not empty" << + info << "wildcard: '" << p << "'" << endf; + }; + + path_search (l, rm, d); + } + else + { + auto rm = [&d] (path&& p) -> bool + { + rmfile (d / p, 2); // That's ok if not exists. + return true; + }; + + path_search (l, rm, d); + } + + continue; + } + // Remove the directory if exists and empty. Fail otherwise. Removal // of non-existing directory is not an error for 'maybe' cleanup // type. @@ -770,7 +822,8 @@ namespace build2 const path& p (cl.path); path np (normalize (p, sp, ll)); - bool wc (np.leaf ().string () == "***"); + const string& ls (np.leaf ().string ()); + bool wc (ls == "*" || ls == "**" || ls == "***"); const path& cp (wc ? np.directory () : np); const dir_path& wd (sp.root->wd_path); -- cgit v1.1