summaryrefslogtreecommitdiff
path: root/subplotlib/src/steplibrary/files.rs
diff options
context:
space:
mode:
Diffstat (limited to 'subplotlib/src/steplibrary/files.rs')
-rw-r--r--subplotlib/src/steplibrary/files.rs83
1 files changed, 46 insertions, 37 deletions
diff --git a/subplotlib/src/steplibrary/files.rs b/subplotlib/src/steplibrary/files.rs
index 09cde56..8abe546 100644
--- a/subplotlib/src/steplibrary/files.rs
+++ b/subplotlib/src/steplibrary/files.rs
@@ -7,7 +7,7 @@ use std::collections::{HashMap, HashSet};
use std::ffi::OsString;
use std::fs::{self, Metadata, OpenOptions};
use std::io::{self, Write};
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
use std::time::{Duration, SystemTime};
use filetime::FileTime;
@@ -31,7 +31,7 @@ pub use super::datadir::Datadir;
/// Because files can typically only be named in Subplot documents, we assume they
/// all have names which can be rendered as utf-8 strings.
pub struct Files {
- metadata: HashMap<String, Metadata>,
+ metadata: HashMap<PathBuf, Metadata>,
}
impl ContextElement for Files {
@@ -50,7 +50,7 @@ impl ContextElement for Files {
#[step]
#[context(Datadir)]
pub fn create_from_embedded(context: &ScenarioContext, embedded_file: SubplotDataFile) {
- let filename_on_disk = format!("{}", embedded_file.name().display());
+ let filename_on_disk = PathBuf::from(format!("{}", embedded_file.name().display()));
create_from_embedded_with_other_name::call(context, &filename_on_disk, embedded_file)?;
}
@@ -63,7 +63,7 @@ pub fn create_from_embedded(context: &ScenarioContext, embedded_file: SubplotDat
#[step]
pub fn create_from_embedded_with_other_name(
context: &Datadir,
- filename_on_disk: &str,
+ filename_on_disk: &Path,
embedded_file: SubplotDataFile,
) {
let filename_on_disk = PathBuf::from(filename_on_disk);
@@ -86,7 +86,7 @@ pub fn create_from_embedded_with_other_name(
/// Sets the modification time for the given filename to the provided mtime.
/// If the file does not exist, it will be created.
#[step]
-pub fn touch_with_timestamp(context: &Datadir, filename: &str, mtime: &str) {
+pub fn touch_with_timestamp(context: &Datadir, filename: &Path, mtime: &str) {
let fd = format_description!(
"[year]-[month]-[day] [hour]:[minute]:[second] [offset_hour]:[offset_minute]"
);
@@ -112,7 +112,7 @@ pub fn touch_with_timestamp(context: &Datadir, filename: &str, mtime: &str) {
///
/// Create/replace the given file with the given content.
#[step]
-pub fn create_from_text(context: &Datadir, text: &str, filename: &str) {
+pub fn create_from_text(context: &Datadir, text: &str, filename: &Path) {
context.open_write(filename)?.write_all(text.as_bytes())?;
}
@@ -125,7 +125,7 @@ pub fn create_from_text(context: &Datadir, text: &str, filename: &str) {
#[step]
#[context(Datadir)]
#[context(Files)]
-pub fn remember_metadata(context: &ScenarioContext, filename: &str) {
+pub fn remember_metadata(context: &ScenarioContext, filename: &Path) {
let full_path = context.with(
|context: &Datadir| context.canonicalise_filename(filename),
false,
@@ -147,7 +147,7 @@ pub fn remember_metadata(context: &ScenarioContext, filename: &str) {
/// This will create the named file if it does not exist, and then it will ensure that the
/// file's modification time is set to the current time.
#[step]
-pub fn touch(context: &Datadir, filename: &str) {
+pub fn touch(context: &Datadir, filename: &Path) {
let full_path = context.canonicalise_filename(filename)?;
let now = FileTime::now();
// If the file doesn't exist, create it
@@ -167,13 +167,13 @@ pub fn touch(context: &Datadir, filename: &str) {
///
/// This simple step will succeed if the given filename exists in some sense.
#[step]
-pub fn file_exists(context: &Datadir, filename: &str) {
+pub fn file_exists(context: &Datadir, filename: &Path) {
let full_path = context.canonicalise_filename(filename)?;
match fs::metadata(full_path) {
Ok(_) => (),
Err(e) => {
if matches!(e.kind(), io::ErrorKind::NotFound) {
- throw!(format!("file '{}' was not found", filename))
+ throw!(format!("file '{}' was not found", filename.display()))
} else {
throw!(e);
}
@@ -187,11 +187,14 @@ pub fn file_exists(context: &Datadir, filename: &str) {
///
/// This simple step will succeed if the given filename does not exist in any sense.
#[step]
-pub fn file_does_not_exist(context: &Datadir, filename: &str) {
+pub fn file_does_not_exist(context: &Datadir, filename: &Path) {
let full_path = context.canonicalise_filename(filename)?;
match fs::metadata(full_path) {
Ok(_) => {
- throw!(format!("file '{}' was unexpectedly found", filename))
+ throw!(format!(
+ "file '{}' was unexpectedly found",
+ filename.display()
+ ))
}
Err(e) => {
if !matches!(e.kind(), io::ErrorKind::NotFound) {
@@ -229,11 +232,11 @@ pub fn only_these_exist(context: &Datadir, filenames: &str) {
/// This will load the content of the named file and ensure it contains the given string.
/// Note: this assumes everything is utf-8 encoded. If not, things will fail.
#[step]
-pub fn file_contains(context: &Datadir, filename: &str, data: &str) {
+pub fn file_contains(context: &Datadir, filename: &Path, data: &str) {
let full_path = context.canonicalise_filename(filename)?;
let body = fs::read_to_string(full_path)?;
if !body.contains(data) {
- println!("file {} contains:\n{}", filename, body);
+ println!("file {} contains:\n{}", filename.display(), body);
throw!("expected file content not found");
}
}
@@ -245,11 +248,11 @@ pub fn file_contains(context: &Datadir, filename: &str, data: &str) {
/// This will load the content of the named file and ensure it lacks the given string.
/// Note: this assumes everything is utf-8 encoded. If not, things will fail.
#[step]
-pub fn file_doesnt_contain(context: &Datadir, filename: &str, data: &str) {
+pub fn file_doesnt_contain(context: &Datadir, filename: &Path, data: &str) {
let full_path = context.canonicalise_filename(filename)?;
let body = fs::read_to_string(full_path)?;
if body.contains(data) {
- println!("file {} contains:\n{}", filename, body);
+ println!("file {} contains:\n{}", filename.display(), body);
throw!("unexpected file content found");
}
}
@@ -262,12 +265,12 @@ pub fn file_doesnt_contain(context: &Datadir, filename: &str, data: &str) {
/// matches the given regular expression. This step will fail if the file is not utf-8
/// encoded, or if the regex fails to compile
#[step]
-pub fn file_matches_regex(context: &Datadir, filename: &str, regex: &str) {
+pub fn file_matches_regex(context: &Datadir, filename: &Path, regex: &str) {
let full_path = context.canonicalise_filename(filename)?;
let regex = Regex::new(regex)?;
let body = fs::read_to_string(full_path)?;
if !regex.is_match(&body) {
- println!("file {} contains:\n{}", filename, body);
+ println!("file {} contains:\n{}", filename.display(), body);
throw!("file content does not match given regex");
}
}
@@ -278,7 +281,7 @@ pub fn file_matches_regex(context: &Datadir, filename: &str, regex: &str) {
///
/// This loads the content of the given two files as **bytes** and checks they mach.
#[step]
-pub fn file_match(context: &Datadir, filename1: &str, filename2: &str) {
+pub fn file_match(context: &Datadir, filename1: &Path, filename2: &Path) {
let full_path1 = context.canonicalise_filename(filename1)?;
let full_path2 = context.canonicalise_filename(filename2)?;
let body1 = fs::read(full_path1)?;
@@ -286,12 +289,12 @@ pub fn file_match(context: &Datadir, filename1: &str, filename2: &str) {
if body1 != body2 {
println!(
"file {} contains:\n{}",
- filename1,
+ filename1.display(),
String::from_utf8_lossy(&body1)
);
println!(
"file {} contains:\n{}",
- filename2,
+ filename2.display(),
String::from_utf8_lossy(&body2)
);
throw!("file contents do not match each other");
@@ -312,7 +315,7 @@ pub fn file_match(context: &Datadir, filename1: &str, filename2: &str) {
#[step]
#[context(Datadir)]
#[context(Files)]
-pub fn has_remembered_metadata(context: &ScenarioContext, filename: &str) {
+pub fn has_remembered_metadata(context: &ScenarioContext, filename: &Path) {
let full_path = context.with(
|context: &Datadir| context.canonicalise_filename(filename),
false,
@@ -327,10 +330,13 @@ pub fn has_remembered_metadata(context: &ScenarioContext, filename: &str) {
|| metadata.len() != remembered.len()
|| metadata.is_file() != remembered.is_file()
{
- throw!(format!("metadata change detected for {}", filename));
+ throw!(format!(
+ "metadata change detected for {}",
+ filename.display()
+ ));
}
} else {
- throw!(format!("no remembered metadata for {}", filename));
+ throw!(format!("no remembered metadata for {}", filename.display()));
}
}
@@ -348,7 +354,7 @@ pub fn has_remembered_metadata(context: &ScenarioContext, filename: &str) {
#[step]
#[context(Datadir)]
#[context(Files)]
-pub fn has_different_metadata(context: &ScenarioContext, filename: &str) {
+pub fn has_different_metadata(context: &ScenarioContext, filename: &Path) {
let full_path = context.with(
|context: &Datadir| context.canonicalise_filename(filename),
false,
@@ -363,10 +369,13 @@ pub fn has_different_metadata(context: &ScenarioContext, filename: &str) {
&& metadata.len() == remembered.len()
&& metadata.is_file() == remembered.is_file()
{
- throw!(format!("metadata change not detected for {}", filename));
+ throw!(format!(
+ "metadata change not detected for {}",
+ filename.display()
+ ));
}
} else {
- throw!(format!("no remembered metadata for {}", filename));
+ throw!(format!("no remembered metadata for {}", filename.display()));
}
}
@@ -376,13 +385,13 @@ pub fn has_different_metadata(context: &ScenarioContext, filename: &str) {
///
/// Specifically this checks that the given file has been modified in the past 5 seconds.
#[step]
-pub fn mtime_is_recent(context: &Datadir, filename: &str) {
+pub fn mtime_is_recent(context: &Datadir, filename: &Path) {
let full_path = context.canonicalise_filename(filename)?;
let metadata = fs::metadata(full_path)?;
let mtime = metadata.modified()?;
let diff = SystemTime::now().duration_since(mtime)?;
if diff > (Duration::from_secs(5)) {
- throw!(format!("{} is older than 5 seconds", filename));
+ throw!(format!("{} is older than 5 seconds", filename.display()));
}
}
@@ -392,13 +401,13 @@ pub fn mtime_is_recent(context: &Datadir, filename: &str) {
///
/// Specifically this checks that the file was modified at least 39 years ago.
#[step]
-pub fn mtime_is_ancient(context: &Datadir, filename: &str) {
+pub fn mtime_is_ancient(context: &Datadir, filename: &Path) {
let full_path = context.canonicalise_filename(filename)?;
let metadata = fs::metadata(full_path)?;
let mtime = metadata.modified()?;
let diff = SystemTime::now().duration_since(mtime)?;
if diff < (Duration::from_secs(39 * 365 * 24 * 3600)) {
- throw!(format!("{} is younger than 39 years", filename));
+ throw!(format!("{} is younger than 39 years", filename.display()));
}
}
@@ -408,7 +417,7 @@ pub fn mtime_is_ancient(context: &Datadir, filename: &str) {
///
/// This is the equivalent of `mkdir -p` within the data directory for the scenario.
#[step]
-pub fn make_directory(context: &Datadir, path: &str) {
+pub fn make_directory(context: &Datadir, path: &Path) {
context.create_dir_all(path)?;
}
@@ -418,7 +427,7 @@ pub fn make_directory(context: &Datadir, path: &str) {
///
/// This is the equivalent of `rm -rf` within the data directory for the scenario.
#[step]
-pub fn remove_directory(context: &Datadir, path: &str) {
+pub fn remove_directory(context: &Datadir, path: &Path) {
let full_path = context.canonicalise_filename(path)?;
remove_dir_all::remove_dir_all(full_path)?;
}
@@ -430,7 +439,7 @@ pub fn remove_directory(context: &Datadir, path: &str) {
/// This ensures that the given path exists in the data directory for the scenario and
/// that it is a directory itself.
#[step]
-pub fn path_exists(context: &Datadir, path: &str) {
+pub fn path_exists(context: &Datadir, path: &Path) {
let full_path = context.canonicalise_filename(path)?;
if !fs::metadata(&full_path)?.is_dir() {
throw!(format!(
@@ -447,7 +456,7 @@ pub fn path_exists(context: &Datadir, path: &str) {
/// This ensures that the given path does not exist in the data directory. If it exists
/// and is not a directory, then this will also fail.
#[step]
-pub fn path_does_not_exist(context: &Datadir, path: &str) {
+pub fn path_does_not_exist(context: &Datadir, path: &Path) {
let full_path = context.canonicalise_filename(path)?;
match fs::metadata(&full_path) {
Ok(_) => throw!(format!("{} exists", full_path.display())),
@@ -466,7 +475,7 @@ pub fn path_does_not_exist(context: &Datadir, path: &str) {
/// This checks that the given path inside the data directory exists and is an
/// empty directory itself.
#[step]
-pub fn path_is_empty(context: &Datadir, path: &str) {
+pub fn path_is_empty(context: &Datadir, path: &Path) {
let full_path = context.canonicalise_filename(path)?;
let mut iter = fs::read_dir(&full_path)?;
match iter.next() {
@@ -484,7 +493,7 @@ pub fn path_is_empty(context: &Datadir, path: &str) {
/// directory itself. The step also asserts that the given directory contains at least
/// one entry.
#[step]
-pub fn path_is_not_empty(context: &Datadir, path: &str) {
+pub fn path_is_not_empty(context: &Datadir, path: &Path) {
let full_path = context.canonicalise_filename(path)?;
let mut iter = fs::read_dir(&full_path)?;
match iter.next() {