feat(mkdwarfs): support time strings for --set-time

This commit is contained in:
Marcus Holland-Moritz 2024-01-01 13:53:47 +01:00
parent 9e83ebd312
commit d432b4bfa9
3 changed files with 48 additions and 9 deletions

View File

@ -255,10 +255,14 @@ Most other options are concerned with compression tuning:
size of the file system. If the input only has a single group already, size of the file system. If the input only has a single group already,
setting this won't make any difference. setting this won't make any difference.
- `--set-time=`*time*|`now`: - `--set-time=now`|*iso-8601-string*|*unix-timestamp*:
Set the time stamps for all entities to this value. This can significantly Set the time stamps for all entities to this value. This can significantly
reduce the size of the file system. You can pass either a unix time stamp reduce the size of the file system. You can pass the string `now` for the
or `now`. current time, an ISO 8601 string, or a unix timestamp (seconds since epoch).
The ISO 8601 string supports a space character instead of the `T` between
date and time and supports dashes as separators. Seconds or the full time
part may be omitted as long as this doesn't turn the whole string into a
single number (i.e. `2008-03-17` is supported, but `20080317` is not).
- `--keep-all-times`: - `--keep-all-times`:
As of release 0.3.0, by default, `mkdwarfs` will only save the contents of As of release 0.3.0, by default, `mkdwarfs` will only save the contents of

View File

@ -934,11 +934,17 @@ int mkdwarfs_main(int argc, sys_char** argv, iolayer const& iol) {
} else if (auto val = folly::tryTo<uint64_t>(timestamp)) { } else if (auto val = folly::tryTo<uint64_t>(timestamp)) {
options.timestamp = *val; options.timestamp = *val;
} else { } else {
iol.err << "error: argument for option '--set-time' must be numeric or " try {
"`now`\n"; auto tp = parse_time_point(timestamp);
options.timestamp = std::chrono::duration_cast<std::chrono::seconds>(
tp.time_since_epoch())
.count();
} catch (std::exception const& e) {
iol.err << "error: " << e.what() << "\n";
return 1; return 1;
} }
} }
}
if (auto it = time_resolutions.find(time_resolution); if (auto it = time_resolutions.find(time_resolution);
it != time_resolutions.end()) { it != time_resolutions.end()) {

View File

@ -111,6 +111,10 @@ class mkdwarfs_tester {
return mkdwarfs_main(args, iol.get()); return mkdwarfs_main(args, iol.get());
} }
int run(std::initializer_list<std::string> args) {
return run(std::vector<std::string>(args));
}
int run(std::string args) { return run(test::parse_args(args)); } int run(std::string args) { return run(test::parse_args(args)); }
filesystem_v2 fs_from_data(std::string data) { filesystem_v2 fs_from_data(std::string data) {
@ -126,6 +130,9 @@ class mkdwarfs_tester {
return fs_from_data(std::move(fsimage.value())); return fs_from_data(std::move(fsimage.value()));
} }
std::string out() const { return iol.out(); }
std::string err() const { return iol.err(); }
std::shared_ptr<test::test_file_access> fa; std::shared_ptr<test::test_file_access> fa;
std::shared_ptr<test::os_access_mock> os; std::shared_ptr<test::os_access_mock> os;
test::test_iolayer iol; test::test_iolayer iol;
@ -471,8 +478,8 @@ TEST(mkdwarfs_test, set_time_now) {
auto t1 = auto t1 =
std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
EXPECT_EQ(reg.size(), 11); ASSERT_EQ(reg.size(), 11);
EXPECT_EQ(opt.size(), 1); ASSERT_EQ(opt.size(), 1);
EXPECT_GE(*opt.begin(), t0); EXPECT_GE(*opt.begin(), t0);
EXPECT_LE(*opt.begin(), t1); EXPECT_LE(*opt.begin(), t1);
@ -488,7 +495,29 @@ TEST(mkdwarfs_test, set_time_epoch) {
auto opt = get_all_fs_times(*optfs); auto opt = get_all_fs_times(*optfs);
EXPECT_EQ(reg.size(), 11); EXPECT_EQ(reg.size(), 11);
EXPECT_EQ(opt.size(), 1); ASSERT_EQ(opt.size(), 1);
EXPECT_EQ(*opt.begin(), 100000001); EXPECT_EQ(*opt.begin(), 100000001);
} }
TEST(mkdwarfs_test, set_time_epoch_string) {
using namespace std::chrono_literals;
using std::chrono::sys_days;
auto optfs = build_with_args({"--set-time", "2020-01-01 01:02"});
ASSERT_TRUE(optfs);
auto opt = get_all_fs_times(*optfs);
ASSERT_EQ(opt.size(), 1);
EXPECT_EQ(*opt.begin(),
std::chrono::duration_cast<std::chrono::seconds>(
(sys_days{2020y / 1 / 1} + 1h + 2min).time_since_epoch())
.count());
}
TEST(mkdwarfs_test, set_time_error) {
auto t = mkdwarfs_tester::create_empty();
EXPECT_NE(0, t.run({"-i", "/", "-o", "-", "--set-time=InVaLiD"}));
EXPECT_THAT(t.err(), ::testing::HasSubstr("cannot parse time point"));
}