mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-24 10:09:32 -06:00
Merge #1906: xtask bench: run on Windows (scenario commands from an args file, os error 206) (@ded-achtung)
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
//! effectcraft-cli exec <command-id> [--params JSON] run one command
|
||||
//! effectcraft-cli exec --list [--filter TEXT] [--schemas] list engine commands (as `commands`)
|
||||
//! effectcraft-cli run <id> <json> [<id> <json> …] run several commands in order
|
||||
//! effectcraft-cli run --args-file F the same, one argument per line of F
|
||||
//! effectcraft-cli props <comp> <layer> [--flat] [--time S] a layer's property tree (with paths)
|
||||
//! effectcraft-cli get <comp> <layer> <path> [--time S] read a property
|
||||
//! effectcraft-cli set <comp> <layer> <path> <value> [--time S] [--expression E]
|
||||
@@ -96,6 +97,7 @@ const USAGE: &str = "usage: effectcraft-cli <info|commands|exec|run|props|get|se
|
||||
commands [--filter TEXT] [--enabled] list engine commands
|
||||
exec <command-id> [--params JSON] run one engine command (exec --list: list them, as `commands`)
|
||||
run <id> <json> [<id> <json> ...] run several commands in order
|
||||
run --args-file F the same, one argument per line of F (no command-line length limit)
|
||||
props <comp> <layer> [--flat] [--time S] a layer's property tree with paths
|
||||
get <comp> <layer> <path> [--time S] read a property
|
||||
set <comp> <layer> <path> <value> [--time S] [--expression E]
|
||||
@@ -148,6 +150,7 @@ const VALUED: &[&str] = &[
|
||||
"--expression",
|
||||
"--depth",
|
||||
"--eval",
|
||||
"--args-file",
|
||||
// render
|
||||
"--template",
|
||||
"--values",
|
||||
@@ -515,10 +518,15 @@ fn run(cmd: &str, args: &Args, json_out: bool) -> Result<(), Failure> {
|
||||
emit(&with_saved(r, saved), json_out);
|
||||
}
|
||||
"run" => {
|
||||
if args.pos.is_empty() {
|
||||
let mut pairs = args.pos.clone();
|
||||
// Windows caps a command line at 32 767 characters: long batches come from a file.
|
||||
if let Some(f) = args.opt("--args-file") {
|
||||
let text = std::fs::read_to_string(f).map_err(|e| Failure::Usage(format!("--args-file {f}: {e}")))?;
|
||||
pairs.extend(text.lines().map(str::trim).filter(|l| !l.is_empty()).map(String::from));
|
||||
}
|
||||
if pairs.is_empty() {
|
||||
return usage_err("run needs <command-id> [<json>] pairs");
|
||||
}
|
||||
let pairs = args.pos.clone();
|
||||
let mut b = backend(args, true)?;
|
||||
let mut results = vec![];
|
||||
let mut i = 0;
|
||||
|
||||
@@ -110,6 +110,29 @@ fn exec_set_get_with_saved_project() {
|
||||
assert_eq!(v[1]["result"]["time"], v[0]["result"]["time"], "{v}");
|
||||
}
|
||||
|
||||
/// `run --args-file` reads its command / params pairs from a file, one per line: a batch longer
|
||||
/// than a Windows command line (32 767 characters, os error 206) still runs.
|
||||
#[test]
|
||||
fn run_reads_arguments_from_a_file() {
|
||||
let proj = tmp("args-file.ecproj");
|
||||
let p = proj.to_str().unwrap();
|
||||
let mut lines = vec!["comp.new".to_string(), json!({"name": "A", "width": 64, "height": 64}).to_string()];
|
||||
for i in 0..400 {
|
||||
lines.push("layer.newSolid".into());
|
||||
lines.push(json!({"width": 8, "height": 8, "name": format!("Solid with a long name to pass the limit {i:04}")}).to_string());
|
||||
lines.push(String::new());
|
||||
}
|
||||
let text = lines.join("\n");
|
||||
assert!(text.len() > 32_767);
|
||||
let file = tmp("args-file.txt");
|
||||
std::fs::write(&file, text).unwrap();
|
||||
let v = ok_json(&["run", "--args-file", file.to_str().unwrap(), "--empty", "--save-as", p]);
|
||||
assert_eq!(v["result"].as_array().map(Vec::len), Some(401), "{v}");
|
||||
let out = bin().args(["run", "--args-file", "no/such/file.txt", "--empty"]).output().unwrap();
|
||||
assert_eq!(out.status.code(), Some(2));
|
||||
assert!(String::from_utf8_lossy(&out.stderr).contains("--args-file no/such/file.txt"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_frame_writes_png() {
|
||||
let out = tmp("f.png");
|
||||
|
||||
+9
-6
@@ -427,15 +427,18 @@ fn footage_cmds(seq_first: &Path, clip: &Path, still: &Path) -> Cmds {
|
||||
c
|
||||
}
|
||||
|
||||
/// Run `cmds` with `effectcraft-cli --empty run … --save-as out`.
|
||||
/// Run `cmds` with `effectcraft-cli --empty run --args-file … --save-as out`: a file, because the
|
||||
/// `layers` scenario is longer than a Windows command line (32 767 characters).
|
||||
fn build_project(bin: &Path, cmds: &Cmds, out: &Path) -> Result<(), String> {
|
||||
let mut cmd = Command::new(bin);
|
||||
cmd.arg("--empty").arg("run");
|
||||
let mut lines = String::new();
|
||||
for (id, params) in cmds {
|
||||
cmd.arg(id).arg(params.to_string());
|
||||
lines.push_str(&format!("{id}\n{params}\n"));
|
||||
}
|
||||
cmd.arg("--save-as").arg(out);
|
||||
cli(&mut cmd)
|
||||
let args = out.with_extension("args");
|
||||
std::fs::write(&args, lines).map_err(|e| format!("{}: {e}", args.display()))?;
|
||||
let r = cli(Command::new(bin).arg("--empty").arg("run").arg("--args-file").arg(&args).arg("--save-as").arg(out));
|
||||
let _ = std::fs::remove_file(&args);
|
||||
r
|
||||
}
|
||||
|
||||
/// Run a CLI command quietly; on failure, the tail of its output is the error.
|
||||
|
||||
Reference in New Issue
Block a user