Recursively walk a directory and add entries to a tar archive, skipping paths that match `.dockerignore` patterns.
(
root: &Path,
current: &Path,
ignore_patterns: &[IgnorePattern],
builder: &mut tar::Builder<Vec<u8>>,
)
| 283 | /// Recursively walk a directory and add entries to a tar archive, |
| 284 | /// skipping paths that match `.dockerignore` patterns. |
| 285 | fn walk_and_add( |
| 286 | root: &Path, |
| 287 | current: &Path, |
| 288 | ignore_patterns: &[IgnorePattern], |
| 289 | builder: &mut tar::Builder<Vec<u8>>, |
| 290 | ) -> Result<()> { |
| 291 | let entries = std::fs::read_dir(current) |
| 292 | .into_diagnostic() |
| 293 | .wrap_err_with(|| format!("failed to read directory: {}", current.display()))?; |
| 294 | |
| 295 | for entry in entries { |
| 296 | let entry = entry |
| 297 | .into_diagnostic() |
| 298 | .wrap_err("failed to read directory entry")?; |
| 299 | let path = entry.path(); |
| 300 | let relative = path |
| 301 | .strip_prefix(root) |
| 302 | .unwrap_or(&path) |
| 303 | .to_string_lossy() |
| 304 | .to_string(); |
| 305 | |
| 306 | // Normalize to forward slashes for pattern matching. |
| 307 | let relative_normalized = relative.replace('\\', "/"); |
| 308 | |
| 309 | if is_ignored(&relative_normalized, path.is_dir(), ignore_patterns) { |
| 310 | continue; |
| 311 | } |
| 312 | |
| 313 | if path.is_dir() { |
| 314 | walk_and_add(root, &path, ignore_patterns, builder)?; |
| 315 | } else { |
| 316 | // Use append_path_with_name which handles GNU LongName extensions |
| 317 | // for paths exceeding 100 bytes (the POSIX tar name field limit). |
| 318 | builder |
| 319 | .append_path_with_name(&path, &relative_normalized) |
| 320 | .into_diagnostic() |
| 321 | .wrap_err_with(|| format!("failed to add file to tar: {relative_normalized}"))?; |
| 322 | } |
| 323 | } |
| 324 | |
| 325 | Ok(()) |
| 326 | } |
| 327 | |
| 328 | /// A parsed `.dockerignore` pattern. |
| 329 | #[derive(Debug, Clone)] |
no test coverage detected