mirror of
https://github.com/mhx/dwarfs.git
synced 2025-09-09 12:28:13 -04:00
feat(dwarfsextract): add --format-options
This allows users to pass custom libarchive options of the specific output format. Eg. `mtree:sha256` or `zstd:compression-level=9`.
This commit is contained in:
parent
acf2df1a09
commit
dd5a8e3ac0
@ -67,6 +67,12 @@ to disk:
|
||||
if no output directory is specified). For a full list of supported formats,
|
||||
see libarchive-formats(5).
|
||||
|
||||
- `--format-options=`*options*:
|
||||
|
||||
Comma-separated libarchive options for the specific output format.
|
||||
The options are passed to libarchive. For a full list of options for each
|
||||
output format, see archive_write_set_options(3).
|
||||
|
||||
- `--continue-on-error`:
|
||||
Try to continue with extraction even when errors are encountered. This
|
||||
only applies to errors when reading from the file system image. Errors
|
||||
|
@ -63,12 +63,14 @@ class filesystem_extractor {
|
||||
static void add_library_dependencies(library_dependencies& deps);
|
||||
|
||||
void
|
||||
open_archive(std::filesystem::path const& output, std::string const& format) {
|
||||
impl_->open_archive(output, format);
|
||||
open_archive(std::filesystem::path const& output, std::string const& format,
|
||||
std::string const& format_options = "") {
|
||||
impl_->open_archive(output, format, format_options);
|
||||
}
|
||||
|
||||
void open_stream(std::ostream& os, std::string const& format) {
|
||||
impl_->open_stream(os, format);
|
||||
void open_stream(std::ostream& os, std::string const& format,
|
||||
std::string const& format_options = "") {
|
||||
impl_->open_stream(os, format, format_options);
|
||||
}
|
||||
|
||||
void open_disk(std::filesystem::path const& output) {
|
||||
@ -94,9 +96,11 @@ class filesystem_extractor {
|
||||
public:
|
||||
virtual ~impl() = default;
|
||||
|
||||
virtual void open_archive(std::filesystem::path const& output,
|
||||
std::string const& format) = 0;
|
||||
virtual void open_stream(std::ostream& os, std::string const& format) = 0;
|
||||
virtual void
|
||||
open_archive(std::filesystem::path const& output, std::string const& format,
|
||||
std::string const& format_options = "") = 0;
|
||||
virtual void open_stream(std::ostream& os, std::string const& format,
|
||||
std::string const& format_options) = 0;
|
||||
virtual void open_disk(std::filesystem::path const& output) = 0;
|
||||
virtual void close() = 0;
|
||||
virtual bool
|
||||
|
@ -122,16 +122,20 @@ class filesystem_extractor_ final : public filesystem_extractor::impl {
|
||||
}
|
||||
}
|
||||
|
||||
void open_archive(std::filesystem::path const& output [[maybe_unused]],
|
||||
std::string const& format [[maybe_unused]]) override {
|
||||
void
|
||||
open_archive(std::filesystem::path const& output [[maybe_unused]],
|
||||
std::string const& format [[maybe_unused]],
|
||||
std::string const& format_options [[maybe_unused]]) override {
|
||||
#ifdef DWARFS_FILESYSTEM_EXTRACTOR_NO_OPEN_FORMAT
|
||||
DWARFS_THROW(runtime_error, "open_archive() not supported in this build");
|
||||
#else
|
||||
LOG_DEBUG << "opening archive file in " << format << " format";
|
||||
LOG_DEBUG << "opening archive file in " << format
|
||||
<< " format with options '" << format_options << "'";
|
||||
|
||||
a_ = ::archive_write_new();
|
||||
|
||||
check_result(::archive_write_set_format_by_name(a_, format.c_str()));
|
||||
check_result(::archive_write_set_options(a_, format_options.c_str()));
|
||||
check_result(::archive_write_set_bytes_in_last_block(a_, 1));
|
||||
|
||||
#ifdef _WIN32
|
||||
@ -144,8 +148,10 @@ class filesystem_extractor_ final : public filesystem_extractor::impl {
|
||||
#endif
|
||||
}
|
||||
|
||||
void open_stream(std::ostream& os [[maybe_unused]],
|
||||
std::string const& format [[maybe_unused]]) override {
|
||||
void
|
||||
open_stream(std::ostream& os [[maybe_unused]],
|
||||
std::string const& format [[maybe_unused]],
|
||||
std::string const& format_options [[maybe_unused]]) override {
|
||||
#ifdef DWARFS_FILESYSTEM_EXTRACTOR_NO_OPEN_FORMAT
|
||||
DWARFS_THROW(runtime_error, "open_stream() not supported in this build");
|
||||
#else
|
||||
@ -162,11 +168,13 @@ class filesystem_extractor_ final : public filesystem_extractor::impl {
|
||||
iot_ = std::make_unique<std::thread>(
|
||||
[this, &os, fd = pipefd_[0]] { pump(os, fd); });
|
||||
|
||||
LOG_DEBUG << "opening archive stream in " << format << " format";
|
||||
LOG_DEBUG << "opening archive stream in " << format
|
||||
<< " format with options '" << format_options << "'";
|
||||
|
||||
a_ = ::archive_write_new();
|
||||
|
||||
check_result(::archive_write_set_format_by_name(a_, format.c_str()));
|
||||
check_result(::archive_write_set_options(a_, format_options.c_str()));
|
||||
check_result(::archive_write_set_bytes_in_last_block(a_, 1));
|
||||
check_result(::archive_write_open_fd(a_, pipefd_[1]));
|
||||
#endif
|
||||
|
@ -194,6 +194,7 @@ TEST_P(manpage_coverage_test, options) {
|
||||
if (tool_name == "dwarfsextract") {
|
||||
#ifdef DWARFS_FILESYSTEM_EXTRACTOR_NO_OPEN_FORMAT
|
||||
man_opts.erase("format");
|
||||
man_opts.erase("format-options");
|
||||
#endif
|
||||
man_opts.erase("pattern");
|
||||
}
|
||||
|
@ -2253,11 +2253,14 @@ INSTANTIATE_TEST_SUITE_P(dwarfs, mkdwarfs_progress_test,
|
||||
#ifndef DWARFS_FILESYSTEM_EXTRACTOR_NO_OPEN_FORMAT
|
||||
TEST(dwarfsextract_test, mtree) {
|
||||
auto t = dwarfsextract_tester::create_with_image();
|
||||
ASSERT_EQ(0, t.run({"-i", "image.dwarfs", "-f", "mtree"})) << t.err();
|
||||
ASSERT_EQ(0, t.run({"-i", "image.dwarfs", "-f", "mtree", "--format-options",
|
||||
"mtree:sha256"}))
|
||||
<< t.err();
|
||||
auto out = t.out();
|
||||
EXPECT_TRUE(out.starts_with("#mtree")) << out;
|
||||
EXPECT_THAT(out, ::testing::HasSubstr("type=dir"));
|
||||
EXPECT_THAT(out, ::testing::HasSubstr("type=file"));
|
||||
EXPECT_THAT(out, ::testing::HasSubstr("sha256digest="));
|
||||
}
|
||||
|
||||
TEST(dwarfsextract_test, patterns) {
|
||||
|
@ -72,7 +72,7 @@ int dwarfsextract_main(int argc, sys_char** argv, iolayer const& iol) {
|
||||
std::string cache_size_str, image_offset;
|
||||
logger_options logopts;
|
||||
#ifndef DWARFS_FILESYSTEM_EXTRACTOR_NO_OPEN_FORMAT
|
||||
std::string format;
|
||||
std::string format, format_options;
|
||||
#endif
|
||||
#if DWARFS_PERFMON_ENABLED
|
||||
std::string perfmon_str;
|
||||
@ -100,6 +100,9 @@ int dwarfsextract_main(int argc, sys_char** argv, iolayer const& iol) {
|
||||
("format,f",
|
||||
po::value<std::string>(&format),
|
||||
"output format")
|
||||
("format-options",
|
||||
po::value<std::string>(&format_options),
|
||||
"comma-separated libarchive options for the specific output format")
|
||||
#endif
|
||||
("continue-on-error",
|
||||
po::value<bool>(&continue_on_error)->zero_tokens(),
|
||||
@ -228,9 +231,9 @@ int dwarfsextract_main(int argc, sys_char** argv, iolayer const& iol) {
|
||||
}
|
||||
|
||||
if (stream) {
|
||||
fsx.open_stream(*stream, format);
|
||||
fsx.open_stream(*stream, format, format_options);
|
||||
} else {
|
||||
fsx.open_archive(iol.os->canonical(output), format);
|
||||
fsx.open_archive(iol.os->canonical(output), format, format_options);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user