Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 51 additions & 22 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use notify::{Event, RecursiveMode, Result, Watcher};
use std::collections::{HashMap, HashSet};
use std::fs::{self, File};
use std::env::current_dir;
use std::fs::{self, canonicalize, File};
use std::io::{self, BufRead, Write};
use std::path::{Component, Path, PathBuf};
use std::sync::mpsc;
Expand Down Expand Up @@ -36,18 +37,37 @@ struct Args {
fn main() -> Result<()> {
let args = Args::parse();

let src = Path::new(&args.src);
let target = Path::new(&args.target);
let src = if args.src == "." {
&current_dir().unwrap()
} else {
Path::new(&args.src)
};
let target = if args.target == "." {
&current_dir().unwrap()
} else {
Path::new(&args.target)
};

let abs_src = fs::canonicalize(Path::new(&args.src))?;
let abs_target = fs::canonicalize(Path::new(&args.target))?;
if !target.exists() {
let res = fs::create_dir_all(target);
if res.is_err() {
eprintln!(
"The target directory {:?} does not exist and could not be created.",
target
);
return Err(res.err().unwrap().into());
}
}

let abs_src = fs::canonicalize(src)?;
let abs_target = fs::canonicalize(target)?;

let mut included_files: HashMap<PathBuf, HashSet<PathBuf>> = HashMap::new();

for file in list_of_paths(&src, &target)? {
for file in list_of_paths(&abs_src, &abs_target)? {
match process_file(
&file,
&target.join(file.clone().strip_prefix(src).unwrap()),
&target.join(file.clone().strip_prefix(&abs_src).unwrap()),
&args.include,
args.verbose,
) {
Expand Down Expand Up @@ -86,7 +106,7 @@ fn main() -> Result<()> {
let (tx, rx) = mpsc::channel::<Result<Event>>();
let mut watcher = notify::recommended_watcher(tx)?;

watcher.watch(Path::new(src), RecursiveMode::Recursive)?;
watcher.watch(Path::new(&abs_src), RecursiveMode::Recursive)?;

// Block forever, handling events as they come in
for res in rx {
Expand Down Expand Up @@ -120,28 +140,32 @@ fn main() -> Result<()> {
}
});
continue;
}
event.paths.iter().for_each(|path| {
} else {
event.paths.iter().for_each(|path| {
let path = normalize_path(path);
if args.verbose {
println!("File changed: {:?}, src: {:?}", path, abs_src);
println!("File changed: {:?}, src: {:?}, change kind:{:?}", path, abs_src, event.kind);
}
if !path.starts_with(&abs_target) {
let file = path.clone();
let relative_file = file.strip_prefix(abs_src.clone());
if relative_file.is_err() && args.verbose {
eprintln!("{:?}{:?}{:?}", src, file, relative_file.err());
}
else {
let canon_file = canonicalize(file.clone()).unwrap_or(file.clone());
let relative_file = canon_file.strip_prefix(abs_src.clone());
if relative_file.is_err() {
if args.verbose {
eprintln!("{:?}{:?}{:?}", abs_src.clone(), file, relative_file.err());
}
} else {
let relative_file = relative_file.unwrap();
let target_file = target.join(relative_file);

match process_file(&file.clone(), &target_file, &args.include, args.verbose) {
Ok(includes) => {
for included in includes.iter() {
let relative_include = included.strip_prefix(abs_src.clone());
if relative_include.is_err() && args.verbose {
eprintln!("{:?}{:?}{:?}", src, included, relative_include.err());
if relative_include.is_err() {
if args.verbose {
eprintln!("{:?}{:?}{:?}", src, included, relative_include.err());
}
} else {
included_files
.entry(relative_include.unwrap().to_path_buf())
Expand Down Expand Up @@ -177,22 +201,21 @@ fn main() -> Result<()> {
}
},
io::ErrorKind::InvalidData => {
if args.verbose{
if args.verbose {
println!("The file {:?} was included in {:?}, but contains binary data", included_file, file);
}
}
_ => {
println!("Error processing file {:?}. Error details: {:?}", included_file, e);
}

}
}
}
}
}

}
});
}
}
Err(e) => println!("Error watching for changes. Error details: {:?}", e),
}
Expand Down Expand Up @@ -250,7 +273,13 @@ pub fn process_file(
let file = File::open(path);
if file.is_err() {
let e = file.err().unwrap();
eprintln!("Error opening file for processing: {:?}, {:?}", path, e);
if e.kind() == io::ErrorKind::NotFound {
if verbose {
eprintln!("File not found: {:?}, skipping. If this looks like a temp file, it was probably deleted before we could parse and copy it.", path);
}
} else {
eprintln!("Error opening file for processing: {:?}, {:?}. ", path, e);
}
return Err(e);
}

Expand Down
22 changes: 19 additions & 3 deletions tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,25 @@ fn test_watch_functionality() {
writeln!(include_file, "This is the modified included file.").unwrap();

// Give the watcher some time to detect the change and process the file
thread::sleep(Duration::from_millis(100));

let output_content = fs::read_to_string(target_dir.join("main.txt")).unwrap();
let output_main_file = target_dir.join("main.txt");
let mut counter = 0;
while counter < 20 && !output_main_file.exists() {
thread::sleep(Duration::from_millis(100));
counter = counter + -1;
}
//Wait for the file to be updated
counter = 0;
while counter < 10
&& !fs::read_to_string(&output_main_file)
.unwrap()
.contains("This is the modified included file.")
{
thread::sleep(Duration::from_millis(100));
counter = counter + 1;
}

println!("{:?}", output_main_file);
let output_content = fs::read_to_string(output_main_file).unwrap();
println!("Output content: {}", output_content);
assert!(output_content.contains("This is the modified included file."));
assert!(output_content.contains("This is the main file."));
Expand Down
99 changes: 0 additions & 99 deletions tests/unit_tests.rs.txt

This file was deleted.