diff options
Diffstat (limited to 'libbuild2/script')
-rw-r--r-- | libbuild2/script/run.cxx | 135 |
1 files changed, 94 insertions, 41 deletions
diff --git a/libbuild2/script/run.cxx b/libbuild2/script/run.cxx index 3daa789..182696b 100644 --- a/libbuild2/script/run.cxx +++ b/libbuild2/script/run.cxx @@ -2299,19 +2299,82 @@ namespace build2 void clean (environment& env, const location& ll) { - context& ctx (env.context); + // We don't use the build2 filesystem utilities here in order to remove + // the filesystem entries regardless of the dry-run mode and also to add + // the location info to diagnostics. Other than that, these lambdas + // implement the respective utility functions semantics. + // + auto rmfile = [&ll] (const path& f) + { + try + { + rmfile_status r (try_rmfile (f)); + + if (r == rmfile_status::success && verb >= 3) + text << "rm " << f; + + return r; + } + catch (const system_error& e) + { + fail (ll) << "unable to remove file " << f << ": " << e << endf; + } + }; + + auto rmdir = [&ll] (const dir_path& d) + { + try + { + rmdir_status r (!work.sub (d) + ? try_rmdir (d) + : rmdir_status::not_empty); + + if (r == rmdir_status::success && verb >= 3) + text << "rmdir " << d; + + return r; + } + catch (const system_error& e) + { + fail (ll) << "unable to remove directory " << d << ": " << e << endf; + } + }; + + auto rmdir_r = [&ll] (const dir_path& d, bool dir) + { + if (work.sub (d)) // Don't try to remove working directory. + return rmdir_status::not_empty; + + if (!build2::entry_exists (d)) + return rmdir_status::not_exist; + + try + { + butl::rmdir_r (d, dir); + } + catch (const system_error& e) + { + fail (ll) << "unable to remove directory " << d << ": " << e << endf; + } + + if (verb >= 3) + text << "rmdir -r " << d; + + return rmdir_status::success; + }; + const dir_path& wdir (*env.work_dir.path); // Note that we operate with normalized paths here. // - // Remove special files. The order is not important as we don't - // expect directories here. + // Remove special files. The order is not important as we don't expect + // directories here. // for (const path& p: env.special_cleanups) { // Remove the file if exists. Fail otherwise. // - if (rmfile (ctx, p, 3) == rmfile_status::not_exist) + if (rmfile (p) == rmfile_status::not_exist) fail (ll) << "registered for cleanup special file " << p << " does not exist"; } @@ -2332,9 +2395,9 @@ namespace build2 // Wildcard with the last component being '***' (without trailing // separator) matches all files and sub-directories recursively as - // well as the start directories itself. So we will recursively - // remove the directories that match the parent (for the original - // path) directory wildcard. + // well as the start directories itself. So we will recursively remove + // the directories that match the parent (for the original path) + // directory wildcard. // bool recursive (cp.leaf ().representation () == "***"); const path& p (!recursive ? cp : cp.directory ()); @@ -2345,15 +2408,19 @@ namespace build2 { bool removed (false); - auto rm = [&cp, recursive, &removed, &ll, &ctx, &wdir] + auto rm = [&cp, + recursive, + &removed, + &ll, + &wdir, + &rmfile, &rmdir, &rmdir_r] (path&& pe, const string&, bool interm) { if (!interm) { - // While removing the entry we can get not_exist due to - // racing conditions, but that's ok if somebody did our job. - // Note that we still set the removed flag to true in this - // case. + // While removing the entry we can get not_exist due to racing + // conditions, but that's ok if somebody did our job. Note that + // we still set the removed flag to true in this case. // removed = true; // Will be meaningless on failure. @@ -2363,7 +2430,7 @@ namespace build2 if (!recursive) { - rmdir_status r (rmdir (ctx, d, 3)); + rmdir_status r (rmdir (d)); if (r != rmdir_status::not_empty) return true; @@ -2377,13 +2444,10 @@ namespace build2 } else { - // Don't remove the working directory (it will be removed - // by the dedicated cleanup). - // - // Cast to uint16_t to avoid ambiguity with - // libbutl::rmdir_r(). + // Don't remove the working directory (it will be removed by + // the dedicated cleanup). // - rmdir_status r (rmdir_r (ctx, d, d != wdir, 3)); + rmdir_status r (rmdir_r (d, d != wdir)); if (r != rmdir_status::not_empty) return true; @@ -2396,14 +2460,14 @@ namespace build2 } } else - rmfile (ctx, pe, 3); + rmfile (pe); } return true; }; - // Note that here we rely on the fact that recursive iterating - // goes depth-first (which make sense for the cleanup). + // Note that here we rely on the fact that recursive iterating goes + // depth-first (which make sense for the cleanup). // try { @@ -2434,9 +2498,8 @@ namespace build2 : "file"); } - // Remove the directory if exists and empty. Fail otherwise. - // Removal of non-existing directory is not an error for 'maybe' - // cleanup type. + // Remove the directory if exists and empty. Fail otherwise. Removal + // of non-existing directory is not an error for 'maybe' cleanup type. // if (p.to_directory ()) { @@ -2444,20 +2507,10 @@ namespace build2 bool wd (d == wdir); // Don't remove the working directory for the recursive cleanup - // (it will be removed by the dedicated one). - // - // Note that the root working directory contains the - // .buildignore file (see above). - // - // @@ If 'd' is a file then will fail with a diagnostics having - // no location info. Probably need to add an optional location - // parameter to rmdir() function. The same problem exists for - // a file cleanup when try to rmfile() directory instead of - // file. + // since it needs to be removed by the caller (can contain + // .buildignore file, etc). // - rmdir_status r (recursive - ? rmdir_r (ctx, d, !wd, static_cast <uint16_t> (3)) - : rmdir (ctx, d, 3)); + rmdir_status r (recursive ? rmdir_r (d, !wd) : rmdir (d)); if (r == rmdir_status::success || (r == rmdir_status::not_exist && t == cleanup_type::maybe)) @@ -2473,10 +2526,10 @@ namespace build2 print_dir (dr, d, ll); } - // Remove the file if exists. Fail otherwise. Removal of - // non-existing file is not an error for 'maybe' cleanup type. + // Remove the file if exists. Fail otherwise. Removal of non-existing + // file is not an error for 'maybe' cleanup type. // - if (rmfile (ctx, p, 3) == rmfile_status::not_exist && + if (rmfile (p) == rmfile_status::not_exist && t == cleanup_type::always) fail (ll) << "registered for cleanup file " << p << " does not exist"; |