mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-30 04:57:54 -06:00
Scripts: leave a script out of Recent Script Files when its path can't be made absolute
Services::full_path now returns None when the working directory can't be read, instead of the relative path. file.runScript still runs the script but does not add it to the list, so a later working directory can't make the entry open a different file.
This commit is contained in:
@@ -152,8 +152,8 @@ impl Services for WebServices {
|
||||
false
|
||||
}
|
||||
/// The table's keys are the paths themselves.
|
||||
fn full_path(&self, path: &str) -> String {
|
||||
path.to_string()
|
||||
fn full_path(&self, path: &str) -> Option<String> {
|
||||
Some(path.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -465,7 +465,9 @@ fn run_script(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let name = std::path::Path::new(path).file_name().map(|n| n.to_string_lossy().to_string()).unwrap_or_else(|| path.to_string());
|
||||
let out = run_js(s, &code, path, false)?;
|
||||
let result = report_js(s, &name, out)?;
|
||||
remember_script(s, crate::prefs::RecentScript::Path(full));
|
||||
if let Some(full) = full {
|
||||
remember_script(s, crate::prefs::RecentScript::Path(full));
|
||||
}
|
||||
return Ok(result);
|
||||
}
|
||||
let mut script_path = None;
|
||||
@@ -473,7 +475,7 @@ fn run_script(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
(Some(Value::Array(a)), _) => a.clone(),
|
||||
(_, Some(path)) => {
|
||||
let bytes = s.services.read_file(path).map_err(|e| EngineError::Other(format!("cannot read {path}: {e}")))?;
|
||||
script_path = Some(s.services.full_path(path));
|
||||
script_path = s.services.full_path(path);
|
||||
let text = String::from_utf8_lossy(&bytes).to_string();
|
||||
match serde_json::from_str::<Value>(&text) {
|
||||
Ok(Value::Array(a)) => a,
|
||||
|
||||
@@ -661,11 +661,40 @@ mod tests {
|
||||
fn write_file(&self, path: &str, data: &[u8]) -> std::io::Result<()> {
|
||||
std::fs::write(self.at(path), data)
|
||||
}
|
||||
fn full_path(&self, path: &str) -> String {
|
||||
self.at(path).to_string_lossy().into_owned()
|
||||
fn full_path(&self, path: &str) -> Option<String> {
|
||||
Some(self.at(path).to_string_lossy().into_owned())
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads from a folder but can't make paths absolute.
|
||||
struct NoFullPath(PathBuf);
|
||||
|
||||
impl crate::Services for NoFullPath {
|
||||
fn read_file(&self, path: &str) -> std::io::Result<Vec<u8>> {
|
||||
std::fs::read(self.0.join(path))
|
||||
}
|
||||
fn write_file(&self, path: &str, data: &[u8]) -> std::io::Result<()> {
|
||||
std::fs::write(self.0.join(path), data)
|
||||
}
|
||||
fn full_path(&self, _path: &str) -> Option<String> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// A script whose path can't be made absolute still runs, and Recent Script Files does not
|
||||
/// keep its relative path.
|
||||
#[test]
|
||||
fn unresolved_script_paths_are_not_remembered() {
|
||||
let (mut s, root) = session_in_tmp("recent-unresolved");
|
||||
std::fs::write(root.join("Tool.jsx"), "a").unwrap();
|
||||
std::fs::write(root.join("steps.jsonl"), "[]").unwrap();
|
||||
s.services = Arc::new(NoFullPath(root.clone()));
|
||||
assert_eq!(s.execute("file.runScript", json!({"path": "Tool.jsx"})).unwrap()["ran"], "a");
|
||||
s.execute("file.runScript", json!({"path": "steps.jsonl"})).unwrap();
|
||||
assert!(s.prefs.recent_scripts.is_empty(), "{:?}", s.prefs.recent_scripts);
|
||||
let _ = std::fs::remove_dir_all(&root);
|
||||
}
|
||||
|
||||
/// A script run from a relative path runs the same file again from Recent Script Files after
|
||||
/// the working directory changes, and two scripts with the same file name show their paths.
|
||||
#[test]
|
||||
@@ -694,7 +723,7 @@ mod tests {
|
||||
#[test]
|
||||
fn native_full_paths_are_absolute() {
|
||||
use crate::Services;
|
||||
assert!(std::path::Path::new(&crate::FsServices.full_path("Tool.jsx")).is_absolute());
|
||||
assert!(crate::FsServices.full_path("Tool.jsx").is_some_and(|p| std::path::Path::new(&p).is_absolute()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -39,9 +39,10 @@ pub trait Services: Send + Sync {
|
||||
}
|
||||
/// `path` as a list of recent files keeps it (File ▸ Scripts ▸ Recent Script Files): a
|
||||
/// relative path is made absolute against the working directory, so it opens the same file
|
||||
/// after the working directory changes.
|
||||
fn full_path(&self, path: &str) -> String {
|
||||
std::path::absolute(path).map(|p| p.to_string_lossy().into_owned()).unwrap_or_else(|_| path.to_string())
|
||||
/// after the working directory changes. `None` when the path can't be made absolute (the
|
||||
/// working directory can't be read); the script is then not added to the list.
|
||||
fn full_path(&self, path: &str) -> Option<String> {
|
||||
std::path::absolute(path).ok().map(|p| p.to_string_lossy().into_owned())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user