Detect mtimes file after formatting (#50)

* Detect mtimes file after formatting

* fix test

* remove all .as_path() function
This commit is contained in:
Andika Demas Riyandi 2021-02-11 21:54:10 +07:00 committed by GitHub
parent c8e525f78c
commit d58362ca3a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 35 additions and 60 deletions

View File

@ -12,7 +12,7 @@ pub fn format_cmd(cli: Cli) -> anyhow::Result<()> {
None => env::current_dir()?,
};
let prjfmt_toml = cwd.as_path().join("prjfmt.toml");
let prjfmt_toml = cwd.join("prjfmt.toml");
let xdg_cache_dir = match env::var("XDG_CACHE_DIR") {
Ok(path) => path,
Err(err) => {
@ -24,14 +24,14 @@ pub fn format_cmd(cli: Cli) -> anyhow::Result<()> {
"Set the $XDG_CACHE_DIR to {}",
home_cache.display()
));
home_cache.as_path().display().to_string()
home_cache.display().to_string()
}
Err(err) => return Err(anyhow!("cannot open HOME due to {}.", err)),
}
}
};
if prjfmt_toml.as_path().exists() {
if prjfmt_toml.exists() {
CLOG.debug(&format!(
"Found {} at {}",
prjfmt_toml.display(),

View File

@ -9,10 +9,10 @@ pub fn init_cmd(path: Option<PathBuf>) -> anyhow::Result<()> {
Some(loc) => loc,
None => PathBuf::from("."),
};
let file_path = file.as_path().join("prjfmt.toml");
let file_path = file.join("prjfmt.toml");
// TODO: detect if file exists
fs::write(
file_path.as_path(),
&file_path,
r#"# prjfmt is the universal code formatter - https://github.com/numtide/prjfmt
[formatter.<Language>]
includes = [ "*.<language-extension>" ]

View File

@ -31,35 +31,24 @@ pub fn check_bin(command: &str) -> Result<()> {
}
/// Run the prjfmt
//
// 1. Find and load prjfmt.toml
// 1b. Resolve all of the formatters paths. If missing, print an error, remove the formatters from the list and continue.
// 2. Load the manifest if it exists, otherwise start with empty manifest
// 3. Get the list of files, use the ones passed as argument if not empty, other default to all.
// Errorr if a file belongs to two formatters
// => HashMap<formatter>(files, mtimes) // map A
// 4. Compare the list of files with the manifest, keep the ones that are not in the manifest. // map B
// 5. Iterate over each formatter (in parallel)
// a. Run the formatter with the list of files
// b. Collect the new list of (files, mtimes) and return that // map C
// 6. Merge map C into map B. Write this as the new manifest.
pub fn run_prjfmt(cwd: PathBuf, cache_dir: PathBuf) -> anyhow::Result<()> {
let prjfmt_toml = cwd.as_path().join("prjfmt.toml");
let prjfmt_toml = cwd.join("prjfmt.toml");
// Once the prjfmt found the $XDG_CACHE_DIR/prjfmt/eval-cache/ folder,
// it will try to scan the manifest and passed it into check_prjfmt function
let manifest: RootManifest = read_manifest(&prjfmt_toml, &cache_dir)?;
let old_ctx = create_command_context(&prjfmt_toml)?;
let ctxs = check_prjfmt(&prjfmt_toml, &old_ctx, &manifest)?;
let context = if manifest.manifest.is_empty() && ctxs.is_empty() {
// TODO: Resolve all of the formatters paths. If missing, print an error, remove the formatters from the list and continue.
// Load the manifest if it exists, otherwise start with empty manifest
let mfst: RootManifest = read_manifest(&prjfmt_toml, &cache_dir)?;
// Compare the list of files with the manifest, keep the ones that are not in the manifest
let ctxs = check_prjfmt(&prjfmt_toml, &old_ctx, &mfst)?;
let context = if mfst.manifest.is_empty() && ctxs.is_empty() {
&old_ctx
} else {
&ctxs
};
if !prjfmt_toml.as_path().exists() {
if !prjfmt_toml.exists() {
return Err(anyhow!(
"{}prjfmt.toml not found, please run --init command",
customlog::ERROR
@ -91,31 +80,13 @@ pub fn run_prjfmt(cwd: PathBuf, cache_dir: PathBuf) -> anyhow::Result<()> {
let cmd_arg = &c.command;
let paths = c.metadata.iter().map(|f| &f.path);
cmd!("{cmd_arg} {arg...} {paths...}").output()
// TODO: go over all the paths, and collect the ones that have a new mtime.
// => list (file, mtime)
})
.collect();
}).collect();
let new_ctx: Vec<CmdContext> = old_ctx
.iter()
.flat_map(|octx| {
ctxs.iter().clone().map(move |c| {
if c.command == octx.command {
CmdContext {
command: c.command.clone(),
options: c.options.clone(),
metadata: octx.metadata.union(&c.metadata).cloned().collect(),
}
} else {
octx.clone()
}
})
})
.collect();
if manifest.manifest.is_empty() || ctxs.is_empty() {
if mfst.manifest.is_empty() || ctxs.is_empty() {
create_manifest(prjfmt_toml, cache_dir, old_ctx)?;
} else {
// Read the current status of files and insert into the manifest.
let new_ctx = create_command_context(&prjfmt_toml)?;
println!("Format successful");
println!("capturing formatted file's state...");
create_manifest(prjfmt_toml, cache_dir, new_ctx)?;
@ -125,7 +96,7 @@ pub fn run_prjfmt(cwd: PathBuf, cache_dir: PathBuf) -> anyhow::Result<()> {
}
/// Convert glob pattern into list of pathBuf
pub fn glob_to_path(
pub fn glob_to_path (
cwd: &PathBuf,
extensions: &FileExtensions,
includes: &Option<Vec<String>>,
@ -161,11 +132,11 @@ pub fn glob_to_path(
.overrides(overrides)
.build()
.filter_map(|e| {
e.ok().and_then(|e| {
match e.file_type() {
e.ok().and_then(|f| {
match f.file_type() {
// Skip directory entries
Some(t) if t.is_dir() => None,
_ => Some(e.into_path()),
_ => Some(f.into_path()),
}
})
})
@ -188,7 +159,6 @@ pub fn path_to_filemeta(paths: Vec<PathBuf>) -> Result<BTreeSet<FileMeta>> {
CLOG.warn(&format!(
"Maybe you want to format one file with different formatter?"
));
// return Err(anyhow!("prjfmt failed to run."));
}
}
Ok(filemeta)
@ -196,7 +166,7 @@ pub fn path_to_filemeta(paths: Vec<PathBuf>) -> Result<BTreeSet<FileMeta>> {
/// Creating command configuration based on prjfmt.toml
pub fn create_command_context(prjfmt_toml: &PathBuf) -> Result<Vec<CmdContext>> {
let open_prjfmt = match read_to_string(prjfmt_toml.as_path()) {
let open_prjfmt = match read_to_string(prjfmt_toml) {
Ok(file) => file,
Err(err) => {
return Err(anyhow!(
@ -246,9 +216,9 @@ mod tests {
/// Transforming glob into file path
#[test]
fn test_glob_to_path() -> Result<()> {
let cwd = PathBuf::from(r"examples/monorepo");
let cwd = PathBuf::from(r"examples");
let file_ext = FileExtensions::SingleFile("*.rs".to_string());
let glob_path = PathBuf::from(r"examples/monorepo/rust/src/main.rs");
let glob_path = PathBuf::from(r"examples/rust/src/main.rs");
let mut vec_path = Vec::new();
vec_path.push(glob_path);
assert_eq!(glob_to_path(&cwd, &file_ext, &None, &None)?, vec_path);
@ -258,14 +228,14 @@ mod tests {
/// Transforming path into FileMeta
#[test]
fn test_path_to_filemeta() -> Result<()> {
let file_path = PathBuf::from(r"examples/monorepo/rust/src/main.rs");
let file_path = PathBuf::from(r"examples/rust/src/main.rs");
let metadata = metadata(&file_path)?;
let mtime = FileTime::from_last_modification_time(&metadata).unix_seconds();
let mut vec_path = Vec::new();
vec_path.push(file_path);
let file_meta = FileMeta {
mtimes: mtime,
path: PathBuf::from(r"examples/monorepo/rust/src/main.rs"),
path: PathBuf::from(r"examples/rust/src/main.rs"),
};
let mut set_filemeta = BTreeSet::new();
set_filemeta.insert(file_meta);

View File

@ -26,6 +26,11 @@ pub fn check_prjfmt(
new.metadata.difference(&old.metadata).cloned().collect()
},
})
}).filter(|c| {
match c {
Ok(x) => !x.metadata.is_empty(),
_ => false
}
})
.collect::<Result<Vec<CmdContext>, Error>>()?;

View File

@ -17,7 +17,7 @@ pub fn create_manifest(
) -> Result<()> {
let hash_toml = create_hash(&prjfmt_toml)?;
let mut f = File::create(cache_dir.as_path().join(hash_toml))?;
let mut f = File::create(cache_dir.join(hash_toml))?;
let map_manifest: BTreeMap<String, CmdContext> = cmd_ctx
.into_iter()
.map(|cmd| {
@ -48,11 +48,11 @@ pub fn create_manifest(
/// Read the <hex(hash(path-to-prjfmt))>.toml and return list of config's cache evaluation
pub fn read_manifest(prjfmt_toml: &PathBuf, cache_dir: &PathBuf) -> Result<RootManifest> {
let hash_toml = create_hash(&prjfmt_toml)?;
let manifest_toml = cache_dir.as_path().join(&hash_toml);
let manifest_toml = cache_dir.join(&hash_toml);
if manifest_toml.as_path().exists() {
if manifest_toml.exists() {
CLOG.debug(&format!("Found {} in: {}", hash_toml, cache_dir.display()));
let open_file = match read_to_string(manifest_toml.as_path()) {
let open_file = match read_to_string(&manifest_toml) {
Ok(file) => file,
Err(err) => {
return Err(anyhow!(