Add --remove-empty-dirs option to mkdwarfs

This commit is contained in:
Marcus Holland-Moritz 2020-12-03 00:50:51 +01:00
parent 915a75eacb
commit 34b3de12c2
6 changed files with 40 additions and 8 deletions

View File

@ -134,6 +134,8 @@ class dir : public entry {
global_entry_data const& data) const;
uint32_t inode_num() const override { return inode_; }
void scan(os_access& os, progress& prog) override;
bool empty() const { return entries_.empty(); }
void remove_empty_dirs(progress& prog);
private:
using entry_ptr = std::shared_ptr<entry>;

View File

@ -49,10 +49,11 @@ struct filesystem_options {
enum class file_order_mode { NONE, PATH, SCRIPT, SIMILARITY };
struct scanner_options {
file_order_mode file_order;
file_order_mode file_order{file_order_mode::NONE};
std::optional<uint16_t> uid;
std::optional<uint16_t> gid;
std::optional<uint64_t> timestamp;
bool remove_empty_dirs{false};
};
std::ostream& operator<<(std::ostream& os, file_order_mode mode);

View File

@ -501,18 +501,20 @@ int main(int argc, char* argv[]) {
fuse_opt_parse(&args, &s_opts, dwarfs_opts, option_hdl);
s_opts.cachesize = s_opts.cachesize_str ? parse_size_with_unit(s_opts.cachesize_str)
: (static_cast<size_t>(512) << 20);
s_opts.cachesize = s_opts.cachesize_str
? parse_size_with_unit(s_opts.cachesize_str)
: (static_cast<size_t>(512) << 20);
// TODO: foreground mode, stderr vs. syslog?
s_opts.debuglevel = s_opts.debuglevel_str
? logger::parse_level(s_opts.debuglevel_str)
: logger::INFO;
s_opts.workers = s_opts.workers_str ? folly::to<size_t>(s_opts.workers_str) : 2;
? logger::parse_level(s_opts.debuglevel_str)
: logger::INFO;
s_opts.workers =
s_opts.workers_str ? folly::to<size_t>(s_opts.workers_str) : 2;
s_opts.lock_mode =
s_opts.mlock_str ? parse_mlock_mode(s_opts.mlock_str) : mlock_mode::NONE;
s_opts.decompress_ratio = s_opts.decompress_ratio_str
? folly::to<double>(s_opts.decompress_ratio_str)
: 0.8;
? folly::to<double>(s_opts.decompress_ratio_str)
: 0.8;
s_lgr.set_threshold(s_opts.debuglevel);
log_proxy<debug_logger_policy> log(s_lgr);

View File

@ -211,6 +211,24 @@ void dir::pack(thrift::metadata::metadata& mv2,
}
}
void dir::remove_empty_dirs(progress& prog) {
auto last = std::remove_if(entries_.begin(), entries_.end(),
[&](std::shared_ptr<entry> const& e) {
if (auto d = dynamic_cast<dir*>(e.get())) {
d->remove_empty_dirs(prog);
return d->empty();
}
return false;
});
if (last != entries_.end()) {
auto num = std::distance(last, entries_.end());
prog.dirs_scanned -= num;
prog.dirs_found -= num;
entries_.erase(last, entries_.end());
}
}
entry::type_t link::type() const { return E_LINK; }
const std::string& link::linkname() const { return link_; }

View File

@ -451,6 +451,12 @@ void scanner_<LoggerPolicy>::scan(filesystem_writer& fsw,
auto root = scan_tree(path, prog);
if (options_.remove_empty_dirs) {
log_.info() << "removing empty directories...";
auto d = dynamic_cast<dir*>(root.get());
d->remove_empty_dirs(prog);
}
// now scan all files
scan_files_visitor sfv(wg_, *os_, prog);
root->accept(sfv);

View File

@ -328,6 +328,9 @@ int mkdwarfs(int argc, char** argv) {
po::value<unsigned>(&cfg.window_increment_shift)
->default_value(1),
"window increment (as right shift of size)")
("remove-empty-dirs",
po::value<bool>(&options.remove_empty_dirs)->zero_tokens(),
"remove empty directories in file system")
("log-level",
po::value<std::string>(&log_level)->default_value("info"),
"log level (error, warn, info, debug, trace)")