Make process more robust

master
Rasmus Rosengren 3 years ago
parent cc573c56d6
commit 9155a46de6
Signed by: rsrp
GPG Key ID: A13BC7BC4F81CF5F
  1. 418
      Cargo.lock
  2. 4
      Cargo.toml
  3. 71
      src/build.rs
  4. 36
      src/check.rs
  5. 52
      src/link.rs
  6. 111
      src/main.rs
  7. 44
      src/tree.rs

418
Cargo.lock generated

@ -2,6 +2,15 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "ansi_term"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
dependencies = [
"winapi",
]
[[package]]
name = "async-recursion"
version = "0.3.2"
@ -13,18 +22,188 @@ dependencies = [
"syn",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "cc"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2"
dependencies = [
"jobserver",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "2.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
dependencies = [
"ansi_term",
"atty",
"bitflags",
"strsim",
"textwrap",
"unicode-width",
"vec_map",
]
[[package]]
name = "dfm"
version = "0.1.0"
dependencies = [
"async-recursion",
"clap",
"futures",
"git2",
"tokio",
"xdg",
]
[[package]]
name = "form_urlencoded"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
dependencies = [
"matches",
"percent-encoding",
]
[[package]]
name = "futures"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1adc00f486adfc9ce99f77d717836f0c5aa84965eb0b4f051f4e83f7cab53f8b"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-channel"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74ed2411805f6e4e3d9bc904c95d5d423b89b3b25dc0250aa74729de20629ff9"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]]
name = "futures-core"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99"
[[package]]
name = "futures-executor"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d0d535a57b87e1ae31437b892713aee90cd2d7b0ee48727cd11fc72ef54761c"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-io"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b0e06c393068f3a6ef246c75cdca793d6a46347e75286933e5e75fd2fd11582"
[[package]]
name = "futures-macro"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c54913bae956fb8df7f4dc6fc90362aa72e69148e3f39041fbe8742d21e0ac57"
dependencies = [
"autocfg",
"proc-macro-hack",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "futures-sink"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0f30aaa67363d119812743aa5f33c201a7a66329f97d1a887022971feea4b53"
[[package]]
name = "futures-task"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2"
[[package]]
name = "futures-util"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78"
dependencies = [
"autocfg",
"futures-channel",
"futures-core",
"futures-io",
"futures-macro",
"futures-sink",
"futures-task",
"memchr",
"pin-project-lite",
"pin-utils",
"proc-macro-hack",
"proc-macro-nested",
"slab",
]
[[package]]
name = "git2"
version = "0.13.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "659cd14835e75b64d9dba5b660463506763cf0aa6cb640aeeb0e98d841093490"
dependencies = [
"bitflags",
"libc",
"libgit2-sys",
"log",
"openssl-probe",
"openssl-sys",
"url",
]
[[package]]
@ -36,12 +215,93 @@ dependencies = [
"libc",
]
[[package]]
name = "idna"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
dependencies = [
"matches",
"unicode-bidi",
"unicode-normalization",
]
[[package]]
name = "jobserver"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa"
dependencies = [
"libc",
]
[[package]]
name = "libc"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1fa8cddc8fbbee11227ef194b5317ed014b8acbf15139bd716a18ad3fe99ec5"
[[package]]
name = "libgit2-sys"
version = "0.12.22+1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89c53ac117c44f7042ad8d8f5681378dfbc6010e49ec2c0d1f11dfedc7a4a1c3"
dependencies = [
"cc",
"libc",
"libssh2-sys",
"libz-sys",
"openssl-sys",
"pkg-config",
]
[[package]]
name = "libssh2-sys"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0186af0d8f171ae6b9c4c90ec51898bad5d08a2d5e470903a50d9ad8959cbee"
dependencies = [
"cc",
"libc",
"libz-sys",
"openssl-sys",
"pkg-config",
"vcpkg",
]
[[package]]
name = "libz-sys"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de5435b8549c16d423ed0c03dbaafe57cf6c3344744f1242520d59c9d8ecec66"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "log"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if",
]
[[package]]
name = "matches"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
[[package]]
name = "memchr"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]]
name = "num_cpus"
version = "1.13.0"
@ -52,12 +312,61 @@ dependencies = [
"libc",
]
[[package]]
name = "openssl-probe"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a"
[[package]]
name = "openssl-sys"
version = "0.9.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1996d2d305e561b70d1ee0c53f1542833f4e1ac6ce9a6708b6ff2738ca67dc82"
dependencies = [
"autocfg",
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "percent-encoding"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]]
name = "pin-project-lite"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkg-config"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
[[package]]
name = "proc-macro-hack"
version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]]
name = "proc-macro-nested"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
[[package]]
name = "proc-macro2"
version = "1.0.28"
@ -76,6 +385,18 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "slab"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590"
[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "syn"
version = "1.0.75"
@ -87,6 +408,30 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"unicode-width",
]
[[package]]
name = "tinyvec"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "tokio"
version = "1.10.1"
@ -110,8 +455,81 @@ dependencies = [
"syn",
]
[[package]]
name = "unicode-bidi"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "246f4c42e67e7a4e3c6106ff716a5d067d4132a642840b242e357e468a2a0085"
[[package]]
name = "unicode-normalization"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-width"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "url"
version = "2.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
dependencies = [
"form_urlencoded",
"idna",
"matches",
"percent-encoding",
]
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "xdg"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57"

@ -10,4 +10,8 @@ codegen-units = 1
[dependencies]
async-recursion = "0.3"
clap = "2.33"
futures = "0.3"
git2 = "0.13"
tokio = { version = "1.10", features = ["fs", "macros", "rt-multi-thread"] }
xdg = "2.2"

@ -0,0 +1,71 @@
use std::path::PathBuf;
use async_recursion::async_recursion;
use futures::future::join_all;
use tokio::fs::{copy, create_dir, read_dir};
use crate::Context;
pub async fn build_tree(context: &Context) -> std::io::Result<()> {
dir(context, PathBuf::new()).await
}
#[async_recursion]
async fn dir(context: &Context, relative_path: PathBuf) -> std::io::Result<()> {
let source_path = context.tree_source_dir.join(&relative_path);
let build_path = context.tree_build_dir.join(&relative_path);
match create_dir(build_path).await {
Err(e) if e.kind() != std::io::ErrorKind::AlreadyExists => {
return Err(e);
}
_ => (),
}
let mut dir_walker = read_dir(source_path).await?;
let mut dir_tasks = vec![];
let mut file_tasks = vec![];
while let Some(entry) = dir_walker.next_entry().await? {
let metadata = entry.metadata().await?;
let os_name = entry.file_name();
let name = os_name.to_str();
if name == Some(".git") {
continue;
}
let relative_path = relative_path.join(entry.file_name());
if metadata.is_dir() {
dir_tasks.push(dir(context, relative_path));
} else if metadata.is_file() {
file_tasks.push(file(context, relative_path));
}
}
let dir_tasks = async {
join_all(dir_tasks)
.await
.into_iter()
.collect::<std::io::Result<Vec<_>>>()
};
let file_tasks = async {
join_all(file_tasks)
.await
.into_iter()
.collect::<std::io::Result<Vec<_>>>()
};
tokio::try_join!(dir_tasks, file_tasks)?;
Ok(())
}
async fn file(context: &Context, relative_path: PathBuf) -> std::io::Result<()> {
let source_path = context.tree_source_dir.join(&relative_path);
let build_path = context.tree_build_dir.join(&relative_path);
copy(source_path, build_path).await?;
Ok(())
}

@ -0,0 +1,36 @@
use std::path::PathBuf;
use tokio::fs::read;
use crate::{tree::get_tree_files, Context};
pub async fn check_tree(
context: &Context,
) -> std::io::Result<(Vec<PathBuf>, Vec<PathBuf>, Vec<PathBuf>)> {
let source_files = get_tree_files(&context.tree_source_dir).await?;
let installed_files = get_tree_files(&context.tree_install_dir).await?;
let mut deleted_files = vec![];
let mut changed_files = vec![];
for installed_file in installed_files.iter() {
if source_files.contains(installed_file) {
let source_file_content = read(context.tree_build_dir.join(installed_file)).await?;
let installed_file_content =
read(context.tree_install_dir.join(installed_file)).await?;
if source_file_content != installed_file_content {
changed_files.push(installed_file.clone());
}
} else {
deleted_files.push(installed_file.clone());
}
}
let mut added_files = vec![];
for source_file in source_files.iter() {
if !installed_files.contains(source_file) {
added_files.push(source_file.clone());
}
}
Ok((added_files, changed_files, deleted_files))
}

@ -0,0 +1,52 @@
use std::path::PathBuf;
use tokio::fs::{copy, create_dir_all, remove_file, symlink};
use crate::{check::check_tree, Context};
pub async fn link_tree(context: &Context) -> std::io::Result<()> {
let (add, update, remove) = check_tree(context).await?;
for file in add {
copy_and_link(context, file).await?;
}
for file in update {
copy_and_link(context, file).await?;
}
for file in remove {
remove_file(context.link_root_dir.join(file)).await?;
}
Ok(())
}
async fn copy_and_link(context: &Context, relative_path: PathBuf) -> std::io::Result<()> {
// Create all necessary directories that are accessed
let mut current_install_dir = context.tree_install_dir.join(&relative_path);
current_install_dir.pop();
let mut current_link_dir = context.link_root_dir.join(&relative_path);
current_link_dir.pop();
create_dir_all(current_install_dir).await?;
create_dir_all(current_link_dir).await?;
// Copy from build to install
copy(
context.tree_build_dir.join(&relative_path),
context.tree_install_dir.join(&relative_path),
)
.await?;
// Make sure symlink doesn't exist before attempting to symlink
match remove_file(context.link_root_dir.join(&relative_path)).await {
Ok(_) => {}
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {}
Err(e) => return Err(e),
};
symlink(
context.tree_install_dir.join(&relative_path),
context.link_root_dir.join(&relative_path),
)
.await?;
Ok(())
}

@ -1,47 +1,88 @@
use async_recursion::async_recursion;
use tokio::fs;
mod build;
mod check;
mod link;
mod tree;
use std::path::PathBuf;
use build::build_tree;
use check::check_tree;
use link::link_tree;
const APP_VERSION: &'static str = env!("CARGO_PKG_VERSION");
#[tokio::main]
async fn main() -> std::io::Result<()> {
let home_dir = std::env::var("HOME").expect("Could not get home dir");
symlink_folder(&format!("{}/.df", home_dir), &home_dir).await;
Ok(())
}
let app = clap::App::new("DotFiles Manager")
.version(APP_VERSION)
.author("Rasmus Rosengren <rasmus.rosengren@protonmail.com>")
.about("Utility to manage dotfiles")
.arg(
clap::Arg::with_name("dry-run")
.long("dry-run")
.short("d")
.help("Report changes without installing"),
)
.arg(
clap::Arg::with_name("repo-path")
.long("repo-path")
.short("r")
.default_value(".df")
.help("Location of repo, relative to $HOME"),
);
let matches = app.get_matches();
let home_dir = std::env::var("HOME").expect("$HOME variable not found");
let xdg_dirs = xdg::BaseDirectories::with_prefix("dfm").expect("xdg dirs");
#[async_recursion]
async fn symlink_folder(src_dir: &str, target_dir: &str) {
fs::create_dir_all(target_dir)
.await
.unwrap_or_else(|_| panic!("Could not create {}", target_dir));
let mut dir_contents = fs::read_dir(src_dir)
.await
.unwrap_or_else(|_| panic!("Could read dir {}", src_dir));
while let Ok(Some(entry)) = dir_contents.next_entry().await {
let os_name = entry.file_name();
let name = os_name.to_str().unwrap();
if name == ".git" {
continue;
let context = Context {
tree_source_dir: format!("{}/{}", home_dir, matches.value_of("repo-path").unwrap()).into(),
tree_build_dir: xdg_dirs
.create_cache_directory("tree")
.expect("xdg cache dir"),
tree_install_dir: xdg_dirs
.create_config_directory("tree")
.expect("xdg config dir"),
link_root_dir: home_dir.into(),
};
build_tree(&context).await?;
if matches.is_present("dry-run") {
let (add, change, delete) = check_tree(&context).await?;
if !add.is_empty() {
println!("The following files have been added:");
for file in add {
println!("\t{}", file.to_string_lossy());
}
println!();
}
if let Ok(metadata) = entry.metadata().await {
if metadata.is_dir() {
symlink_folder(
&format!("{}/{}", src_dir, name),
&format!("{}/{}", target_dir, name),
)
.await;
if !change.is_empty() {
println!("The following files have been changed:");
for file in change {
println!("\t{}", file.to_string_lossy());
}
println!();
}
if metadata.is_file() {
#[allow(unused_must_use)]
let _ = fs::remove_file(&format!("{}/{}", target_dir, name)).await;
fs::symlink(
&format!("{}/{}", src_dir, name),
&format!("{}/{}", target_dir, name),
)
.await
.unwrap();
if !delete.is_empty() {
println!("The following files have been deleted:");
for file in delete {
println!("\t{}", file.to_string_lossy());
}
println!();
}
} else {
link_tree(&context).await?;
}
Ok(())
}
pub struct Context {
tree_source_dir: PathBuf,
tree_build_dir: PathBuf,
tree_install_dir: PathBuf,
link_root_dir: PathBuf,
}

@ -0,0 +1,44 @@
use std::{
collections::HashSet,
path::{Path, PathBuf},
};
use async_recursion::async_recursion;
use futures::future::try_join_all;
use tokio::fs::read_dir;
pub async fn get_tree_files(tree_root_path: &Path) -> std::io::Result<HashSet<PathBuf>> {
dir(tree_root_path, PathBuf::new()).await
}
#[async_recursion]
async fn dir(tree_root_path: &Path, relative_path: PathBuf) -> std::io::Result<HashSet<PathBuf>> {
let current_path = tree_root_path.join(&relative_path);
let mut dir_walker = read_dir(&current_path).await?;
let mut dir_tasks = vec![];
let mut files = HashSet::new();
while let Some(entry) = dir_walker.next_entry().await? {
let metadata = entry.metadata().await?;
let os_name = entry.file_name();
let name = os_name.to_string_lossy().to_string();
if name == ".git" {
continue;
}
if metadata.is_dir() {
dir_tasks.push(dir(tree_root_path, relative_path.join(name)));
} else if metadata.is_file() {
files.insert(relative_path.join(name));
}
}
let file_sets = try_join_all(dir_tasks).await?;
for file_set in file_sets {
files.extend(file_set);
}
Ok(files)
}
Loading…
Cancel
Save