From 5d6ce25142dd4624f785ebf2ffe4cc2afb8d49e0 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Sun, 18 Mar 2018 00:33:28 +0300 Subject: Add support for cp builtin -p option --- build2/test/script/builtin.cxx | 65 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 12 deletions(-) (limited to 'build2/test') diff --git a/build2/test/script/builtin.cxx b/build2/test/script/builtin.cxx index 80954a1..91d5bf2 100644 --- a/build2/test/script/builtin.cxx +++ b/build2/test/script/builtin.cxx @@ -258,6 +258,7 @@ namespace build2 cpfile (scope& sp, const path& from, const path& to, bool overwrite, + bool attrs, bool cleanup, const function& fail) { @@ -265,10 +266,15 @@ namespace build2 { bool exists (file_exists (to)); - cpfile (from, to, - overwrite - ? cpflags::overwrite_permissions | cpflags::overwrite_content - : cpflags::none); + cpflags f ( + overwrite + ? cpflags::overwrite_permissions | cpflags::overwrite_content + : cpflags::none); + + if (attrs) + f |= cpflags::overwrite_permissions | cpflags::copy_timestamps; + + cpfile (from, to, f); if (!exists && cleanup) sp.clean ({cleanup_type::always, to}, true); @@ -288,6 +294,7 @@ namespace build2 static void cpdir (scope& sp, const dir_path& from, const dir_path& to, + bool attrs, bool cleanup, const function& fail) { @@ -308,10 +315,20 @@ namespace build2 cpdir (sp, path_cast (move (f)), path_cast (move (t)), + attrs, cleanup, fail); else - cpfile (sp, f, t, false, cleanup, fail); + cpfile (sp, f, t, false /* overwrite */, attrs, cleanup, fail); + } + + // Note that it is essential to copy timestamps and permissions after + // the directory content is copied. + // + if (attrs) + { + path_permissions (to, path_permissions (from)); + dir_time (to, dir_time (from)); } } catch (const system_error& e) @@ -321,10 +338,10 @@ namespace build2 } } - // cp [--no-cleanup] - // cp [--no-cleanup] -R|-r - // cp [--no-cleanup] ... / - // cp [--no-cleanup] -R|-r ... / + // cp [-p] [--no-cleanup] + // cp [-p] [--no-cleanup] -R|-r + // cp [-p] [--no-cleanup] ... / + // cp [-p] [--no-cleanup] -R|-r ... / // // Note: can be executed synchronously. // @@ -353,6 +370,7 @@ namespace build2 // Process options. // bool recursive (false); + bool attrs (false); bool cleanup (true); for (; i != e; ++i) { @@ -360,6 +378,8 @@ namespace build2 if (o == "-R" || o == "-r") recursive = true; + else if (o == "-p") + attrs = true; else if (o == "--no-cleanup") cleanup = false; else @@ -406,12 +426,19 @@ namespace build2 if (!recursive) // Synopsis 1: make a file copy at the specified path. // - cpfile (sp, src, dst, true, cleanup, fail); + cpfile (sp, + src, + dst, + true /* overwrite */, + attrs, + cleanup, + fail); else // Synopsis 2: make a directory copy at the specified path. // cpdir (sp, path_cast (src), path_cast (dst), + attrs, cleanup, fail); } @@ -429,13 +456,20 @@ namespace build2 cpdir (sp, path_cast (src), path_cast (dst / src.leaf ()), + attrs, cleanup, fail); else // Synopsis 3: copy a file into the specified directory. Also, // here we cover synopsis 4 for the source path being a file. // - cpfile (sp, src, dst / src.leaf (), true, cleanup, fail); + cpfile (sp, + src, + dst / src.leaf (), + true /* overwrite */, + attrs, + cleanup, + fail); } } @@ -612,10 +646,17 @@ namespace build2 if (dir) cpdir (sp, path_cast (target), path_cast (link), + false, cleanup, fail); else - cpfile (sp, target, link, false, cleanup, fail); + cpfile (sp, + target, + link, + false /* overwrite */, + true /* attrs */, + cleanup, + fail); } } } -- cgit v1.1