[feat] Add known fileformats
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Reliably stripping (multiple) archive extensions (e.g. .tar.gz) is not supported by std::filesystem::path. Dots in the regular root folder name can cause issues. fileformats.hpp adds well-known format extensions which are used for stripping the extension. Note that this is not used by libarchive or xwim to determine the filters/formats for extraction. This is done by libarchive's `bidding`.
This commit is contained in:
parent
064c936f11
commit
e59968444e
7 changed files with 48 additions and 17 deletions
|
@ -1,5 +1,5 @@
|
||||||
project('xwim', 'cpp',
|
project('xwim', 'cpp',
|
||||||
version: '0.1',
|
version: '0.2',
|
||||||
default_options: ['cpp_std=c++17'])
|
default_options: ['cpp_std=c++17'])
|
||||||
|
|
||||||
subdir('src')
|
subdir('src')
|
||||||
|
|
|
@ -14,6 +14,7 @@ namespace logger = spdlog;
|
||||||
#include "archive_sys.hpp"
|
#include "archive_sys.hpp"
|
||||||
#include "archive.hpp"
|
#include "archive.hpp"
|
||||||
#include "spec.hpp"
|
#include "spec.hpp"
|
||||||
|
#include "fileformats.hpp"
|
||||||
|
|
||||||
namespace xwim {
|
namespace xwim {
|
||||||
|
|
||||||
|
@ -22,9 +23,7 @@ static void _spec_is_root_filename(ArchiveSpec* spec,
|
||||||
std::filesystem::path* filepath) {
|
std::filesystem::path* filepath) {
|
||||||
auto entry_path = entry.path();
|
auto entry_path = entry.path();
|
||||||
auto norm_stem = filepath->filename();
|
auto norm_stem = filepath->filename();
|
||||||
|
norm_stem = xwim::stem(norm_stem);
|
||||||
while (norm_stem.has_extension())
|
|
||||||
norm_stem = norm_stem.stem();
|
|
||||||
|
|
||||||
if (*entry_path.begin() != norm_stem) {
|
if (*entry_path.begin() != norm_stem) {
|
||||||
logger::debug("Archive root does not match archive name");
|
logger::debug("Archive root does not match archive name");
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#ifndef ARCHIVE_H
|
#pragma once
|
||||||
#define ARCHIVE_H
|
|
||||||
|
|
||||||
#include <archive.h>
|
#include <archive.h>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
@ -42,5 +41,3 @@ class ArchiveException : public std::exception {
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace xwim
|
} // namespace xwim
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
38
src/fileformats.hpp
Normal file
38
src/fileformats.hpp
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
namespace logger = spdlog;
|
||||||
|
|
||||||
|
/** Common archive formats understood by xwim
|
||||||
|
*
|
||||||
|
* The underlying libarchive backend retrieves format information by a process
|
||||||
|
* called `bidding`. Hence, this information is mainly used to strip extensions.
|
||||||
|
*
|
||||||
|
* Stripping extensions via `std::filesystem::path` does not work reliably since
|
||||||
|
* it gets easily confused by dots in the regular file name.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <set>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace xwim {
|
||||||
|
|
||||||
|
const std::set<std::string> fileformats{
|
||||||
|
".7z", ".7zip", ".jar", ".tgz", ".bz2", ".bzip2", ".gz",
|
||||||
|
".gzip", ".rar", ".tar", ".tar.gz", ".tar.bz2", ".tar.xz", ".zip"};
|
||||||
|
|
||||||
|
inline std::filesystem::path stem(std::filesystem::path& path) {
|
||||||
|
std::filesystem::path p_stem {path};
|
||||||
|
logger::trace("Stemming {}", p_stem.string());
|
||||||
|
|
||||||
|
while( fileformats.find(p_stem.extension().string()) != fileformats.end() ) {
|
||||||
|
p_stem = p_stem.stem();
|
||||||
|
logger::trace("Stemmed to {}", p_stem.string());
|
||||||
|
}
|
||||||
|
|
||||||
|
logger::trace("Finished stemming {}", p_stem.string());
|
||||||
|
return p_stem;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace xwim
|
|
@ -9,6 +9,7 @@ namespace logger = spdlog;
|
||||||
|
|
||||||
#include "archive.hpp"
|
#include "archive.hpp"
|
||||||
#include "spec.hpp"
|
#include "spec.hpp"
|
||||||
|
#include "fileformats.hpp"
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
logger::set_level(logger::level::trace);
|
logger::set_level(logger::level::trace);
|
||||||
|
@ -25,10 +26,7 @@ int main(int argc, char** argv) {
|
||||||
if (!archive_spec.has_single_root || !archive_spec.is_root_filename) {
|
if (!archive_spec.has_single_root || !archive_spec.is_root_filename) {
|
||||||
extract_spec.make_dir = true;
|
extract_spec.make_dir = true;
|
||||||
|
|
||||||
std::filesystem::path stem = filepath.stem();
|
std::filesystem::path stem = xwim::stem(filepath);
|
||||||
|
|
||||||
while (stem.has_extension())
|
|
||||||
stem = stem.stem();
|
|
||||||
|
|
||||||
extract_spec.dirname = stem;
|
extract_spec.dirname = stem;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
src = ['main.cpp',
|
src = ['main.cpp',
|
||||||
'archive.cpp',
|
'archive.cpp',
|
||||||
'archive_sys.cpp']
|
'archive_sys.cpp']
|
||||||
|
|
||||||
inc = ['archive.hpp',
|
inc = ['archive.hpp',
|
||||||
'spec.hpp',
|
'spec.hpp',
|
||||||
'archive_sys.hpp']
|
'archive_sys.hpp',
|
||||||
|
'fileformats.hpp']
|
||||||
|
|
||||||
libs = [dependency('libarchive', required: true),
|
libs = [dependency('libarchive', required: true),
|
||||||
dependency('fmt', required: true),
|
dependency('fmt', required: true),
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#ifndef SPEC_H
|
#pragma once
|
||||||
#define SPEC_H
|
|
||||||
|
|
||||||
#include <archive.h>
|
#include <archive.h>
|
||||||
#include <fmt/core.h>
|
#include <fmt/core.h>
|
||||||
|
@ -55,5 +54,3 @@ struct fmt::formatter<xwim::ExtractSpec> {
|
||||||
spec.make_dir, spec.dirname.string(), spec.extract_subarchive);
|
spec.make_dir, spec.dirname.string(), spec.extract_subarchive);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
Loading…
Reference in a new issue