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