(collection: &str, slug: &str, target: &str)
| 302 | .ok(); |
| 303 | for child in ["res", "src", "docs", "deps.toml", "routes.toml"] { |
| 304 | let path = project_root.join(child); |
| 305 | if let Some(time) = newest_mtime(&path)? { |
| 306 | newest = Some(match newest { |
| 307 | Some(current) if current >= time => current, |
| 308 | _ => time, |
| 309 | }); |
| 310 | } |
| 311 | } |
| 312 | Ok(newest) |
| 313 | } |
| 314 | |
| 315 | fn newest_mtime(path: &Path) -> io::Result<Option<SystemTime>> { |
| 316 | if !path.exists() { |
| 317 | return Ok(None); |
| 318 | } |
| 319 | let metadata = fs::metadata(path)?; |
| 320 | if metadata.is_file() { |
| 321 | return Ok(metadata.modified().ok()); |
| 322 | } |
| 323 | |
| 324 | let mut newest = metadata.modified().ok(); |
| 325 | for entry in fs::read_dir(path)? { |
| 326 | let path = entry?.path(); |
| 327 | let name = path |
| 328 | .file_name() |
| 329 | .and_then(|name| name.to_str()) |
| 330 | .unwrap_or(""); |
| 331 | if name == "target" || name == ".output" { |
| 332 | continue; |
| 333 | } |
| 334 | if let Some(time) = newest_mtime(&path)? { |
| 335 | newest = Some(match newest { |
| 336 | Some(current) if current >= time => current, |
| 337 | _ => time, |
| 338 | }); |
| 339 | } |
| 340 | } |
| 341 | Ok(newest) |
| 342 | } |
| 343 | |
| 344 | fn sync_dir(src: &Path, dst: &Path) -> io::Result<()> { |
| 345 | if dst.exists() { |
| 346 | fs::remove_dir_all(dst)?; |
| 347 | } |
| 348 | fs::create_dir_all(dst)?; |
| 349 | copy_dir(src, dst) |
| 350 | } |
| 351 | |
| 352 | fn copy_dir(src: &Path, dst: &Path) -> io::Result<()> { |
| 353 | for entry in fs::read_dir(src)? { |
| 354 | let src_path = entry?.path(); |
| 355 | let file_name = src_path |
| 356 | .file_name() |
| 357 | .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "source has no file name"))?; |
no test coverage detected