Further rework path handling
This commit is contained in:
parent
a6c3fb165b
commit
d74edb6a5a
@ -449,7 +449,8 @@ void create_tarball(const std::string &tarball_path,
|
|||||||
throw std::runtime_error(err);
|
throw std::runtime_error(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For duplicate checking only for directories.
|
// Track directories already added.
|
||||||
|
// For directories that are not symlinks, use their canonical absolute path as a key.
|
||||||
std::unordered_set<std::string> added_directories;
|
std::unordered_set<std::string> added_directories;
|
||||||
|
|
||||||
for (auto it = fs::recursive_directory_iterator(directory, fs::directory_options::skip_permission_denied);
|
for (auto it = fs::recursive_directory_iterator(directory, fs::directory_options::skip_permission_denied);
|
||||||
@ -458,13 +459,14 @@ void create_tarball(const std::string &tarball_path,
|
|||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
fs::path rel_path = fs::relative(path, directory, ec);
|
fs::path rel_path = fs::relative(path, directory, ec);
|
||||||
if (ec) {
|
if (ec) {
|
||||||
if (log) log->append("Failed to compute relative path for: " + path.string() + " Error: " + ec.message());
|
if (log)
|
||||||
|
log->append("Failed to compute relative path for: " + path.string() + " Error: " + ec.message());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
fs::path norm_rel = rel_path.lexically_normal();
|
fs::path norm_rel = rel_path.lexically_normal();
|
||||||
std::string rel_str = norm_rel.string();
|
std::string rel_str = norm_rel.string();
|
||||||
|
|
||||||
// Check exclusions regardless of type.
|
// Apply exclusions (if any substring appears in the relative path, skip it)
|
||||||
bool is_excluded = std::any_of(exclusions.begin(), exclusions.end(),
|
bool is_excluded = std::any_of(exclusions.begin(), exclusions.end(),
|
||||||
[&rel_str](const std::string &excl) {
|
[&rel_str](const std::string &excl) {
|
||||||
return rel_str.find(excl) != std::string::npos;
|
return rel_str.find(excl) != std::string::npos;
|
||||||
@ -472,18 +474,26 @@ void create_tarball(const std::string &tarball_path,
|
|||||||
if (is_excluded)
|
if (is_excluded)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// For directories, check if we've already added this path.
|
|
||||||
fs::file_status fstatus = it->symlink_status(ec);
|
fs::file_status fstatus = it->symlink_status(ec);
|
||||||
if (ec) {
|
if (ec) {
|
||||||
if (log) log->append("Failed to get file status for: " + path.string() + " Error: " + ec.message());
|
if (log)
|
||||||
|
log->append("Failed to get file status for: " + path.string() + " Error: " + ec.message());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (fs::is_directory(fstatus)) {
|
|
||||||
if (added_directories.find(rel_str) != added_directories.end())
|
// For directories (that are not symlinks), compute a canonical key.
|
||||||
continue; // Skip duplicate directory entry.
|
if (fs::is_directory(fstatus) && !fs::is_symlink(fstatus)) {
|
||||||
added_directories.insert(rel_str);
|
fs::path canon = fs::canonical(path, ec);
|
||||||
|
if (ec) {
|
||||||
|
// If canonical fails, fall back to the relative path.
|
||||||
|
canon = rel_path;
|
||||||
}
|
}
|
||||||
// (For regular files or symlinks, always add them.)
|
std::string canon_str = canon.string();
|
||||||
|
if (added_directories.find(canon_str) != added_directories.end())
|
||||||
|
continue;
|
||||||
|
added_directories.insert(canon_str);
|
||||||
|
}
|
||||||
|
// For files and symlinks, we always add them.
|
||||||
|
|
||||||
struct archive_entry *entry = archive_entry_new();
|
struct archive_entry *entry = archive_entry_new();
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
@ -491,8 +501,7 @@ void create_tarball(const std::string &tarball_path,
|
|||||||
log->append("Failed to create archive entry for: " + path.string());
|
log->append("Failed to create archive entry for: " + path.string());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// For directories, ensure the entry pathname ends with '/'
|
||||||
// For directories, ensure the entry name ends with '/'
|
|
||||||
std::string entry_path = rel_str;
|
std::string entry_path = rel_str;
|
||||||
if (fs::is_directory(fstatus)) {
|
if (fs::is_directory(fstatus)) {
|
||||||
if (!entry_path.empty() && entry_path.back() != '/')
|
if (!entry_path.empty() && entry_path.back() != '/')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user