diff options
-rw-r--r-- | build2/test/script/builtin.cxx | 54 | ||||
-rw-r--r-- | doc/testscript.cli | 9 | ||||
-rw-r--r-- | tests/in/testscript | 4 | ||||
-rw-r--r-- | tests/test/script/builtin/touch.test | 35 |
4 files changed, 82 insertions, 20 deletions
diff --git a/build2/test/script/builtin.cxx b/build2/test/script/builtin.cxx index d0b8b38..4ab1ec3 100644 --- a/build2/test/script/builtin.cxx +++ b/build2/test/script/builtin.cxx @@ -909,8 +909,8 @@ namespace build2 return 1; } - // mv [--no-cleanup] <src-path> <dst-path> - // mv [--no-cleanup] <src-path>... <dst-dir>/ + // mv [--no-cleanup] [-f] <src-path> <dst-path> + // mv [--no-cleanup] [-f] <src-path>... <dst-dir>/ // // Note: can be executed synchronously. // @@ -1413,7 +1413,7 @@ namespace build2 else if (o == "-e") { // Only a single script is supported. - // + // if (subst) error () << "multiple scripts"; @@ -1490,15 +1490,15 @@ namespace build2 // path p; if (i != e) - { - if (*i != "-") + { + if (*i != "-") p = parse_path (*i, sp.wd_path); ++i; - } + } if (i != e) - error () << "unexpected argument"; + error () << "unexpected argument"; // If we edit file in place make sure that the file path is specified // and obtain a temporary file path. We will be writing to the @@ -1702,7 +1702,7 @@ namespace build2 return 2; } - // touch [--no-cleanup] <file>... + // touch [--no-cleanup] [--after <ref-file>] <file>... // // Note that POSIX doesn't specify the behavior for touching an entry // other than file. @@ -1732,8 +1732,25 @@ namespace build2 in.close (); out.close (); - if (args.empty ()) - error () << "missing file"; + auto mtime = [&error] (const path& p) -> timestamp + { + try + { + timestamp t (file_mtime (p)); + + if (t == timestamp_nonexistent) + throw_generic_error (ENOENT); + + return t; + } + catch (const system_error& e) + { + error () << "cannot obtain file '" << p + << "' modification time: " << e; + } + assert (false); // Can't be here. + return timestamp (); + }; auto i (args.begin ()); auto e (args.end ()); @@ -1741,12 +1758,20 @@ namespace build2 // Process options. // bool cleanup (true); + optional<timestamp> after; for (; i != e; ++i) { const string& o (*i); if (o == "--no-cleanup") cleanup = false; + else if (o == "--after") + { + if (++i == e) + error () << "missing --after option value"; + + after = mtime (parse_path (*i, sp.wd_path)); + } else { if (o == "--") @@ -1756,6 +1781,9 @@ namespace build2 } } + if (i == e) + error () << "missing file"; + // Create files. // for (; i != e; ++i) @@ -1769,6 +1797,12 @@ namespace build2 // if (touch_file (p) && cleanup) sp.clean ({cleanup_type::always, p}, true); + + if (after) + { + while (mtime (p) <= *after) + touch_file (p, false /* create */); + } } catch (const system_error& e) { diff --git a/doc/testscript.cli b/doc/testscript.cli index ad5557d..b7e89f1 100644 --- a/doc/testscript.cli +++ b/doc/testscript.cli @@ -2681,13 +2681,20 @@ Note that tests dereference symbolic links. \h#builtins-touch|\c{touch}| \ -touch [--no-cleanup] <file>... +touch [--no-cleanup] [--after <ref-file>] <file>... \ Change file access and modification times to the current time. Create files that do not exist. Fail if a filesystem entry other than the file exists for the specified name. +\dl| + +\li|\n\c{--after <ref-file>}\n + + Keep touching the file until its modification time becomes after that of the + specified reference file.|| + Unless the \c{--no-cleanup} option is specified, newly created files that are inside the script working directory are automatically registered for cleanup. diff --git a/tests/in/testscript b/tests/in/testscript index fe299d7..3e06137 100644 --- a/tests/in/testscript +++ b/tests/in/testscript @@ -62,10 +62,8 @@ $* <<EOI; file{test}: in{test} EOI cat test >'FOO BAR'; -if ($cxx.target.class != 'windows') - sleep 1 -end; cat <'$fox$ $baz$' >=test.in; +touch --after test test.in; $* <<EOI; fox = fox baz = baz diff --git a/tests/test/script/builtin/touch.test b/tests/test/script/builtin/touch.test index 7188a21..04391bd 100644 --- a/tests/test/script/builtin/touch.test +++ b/tests/test/script/builtin/touch.test @@ -22,14 +22,14 @@ EOI : Test that existing file touch doesn't fail. : $c <<EOI && $b -cat <"" >=a; +cat <'' >=a; touch a EOI : no-cleanup : -: Test that touches an existing file doesn't register cleanup. If it does then -: the file would be removed while leaving the embedded scope, and so the +: Test that touching an existing file does not register cleanup. If it does +: then the file would be removed while leaving the embedded scope, and so the : cleanup registered by the first touch would fail. : $c <<EOI && $b @@ -45,14 +45,14 @@ EOI : : Test passing no arguments. : -$c <'touch 2>"touch: missing file" == 1' && $b +$c <'touch --no-cleanup 2>"touch: missing file" != 0' && $b : empty-path : : Test touching an empty path. : $c <<EOI && $b -touch '' 2>"touch: invalid path ''" == 1 +touch '' 2>"touch: invalid path ''" != 0 EOI : dir-update @@ -61,5 +61,28 @@ EOI : $c <<EOI && $b mkdir a; -touch a 2>~"%touch: cannot create/update .+: .+%" == 1 +touch a 2>~'%touch: cannot create/update .+: .+%' != 0 EOI + +: after +: +{ + : success + : + $c <<EOI && $b + touch a; + touch --after a b + EOI + + : no-value + : + $c <<EOI && $b + touch --after 2>'touch: missing --after option value' != 0 + EOI + + : not-exists + : + $c <<EOI && $b + touch --after a b 2>~"%touch: cannot obtain file '.+a' modification time: .+%" != 0 + EOI +} |