CLI: props prints an enum's label next to its number (#2928)

The text listing printed enum values as bare numbers, which are 0-based
where After Effects scripting counts from 1, so Range Selector Shape 2
read as Ramp Up was Ramp Down. Print the label from the property's
options, as props --json already lists them: "0 (Square)".
This commit is contained in:
JonRC committed 2026-11-02 23:52:47 -03:00
1 parent 7870b5916a
commit 34b3795c00
2 files changed
+41 -1

No files matched your search

+11 -1
View File
@@ -690,7 +690,7 @@ fn run(cmd: &str, args: &Args, json_out: bool) -> Result<(), Failure> {
if let Some(e) = p.get("expression").and_then(Value::as_str) {
extra += &format!(" expr: {e}");
}
say!(" {:<44} {:<8} {}{extra}", p["path"].as_str().unwrap_or(""), p["type"].as_str().unwrap_or(""), p["value"]);
say!(" {:<44} {:<8} {}{extra}", p["path"].as_str().unwrap_or(""), p["type"].as_str().unwrap_or(""), value_text(p));
}
}
}
@@ -1539,6 +1539,16 @@ fn bench_gpu(s: &Session, args: &Args) -> Result<(), Failure> {
Ok(())
}
/// A flat property's value for the text listing: an enum's number with the label `options` gives it
/// (#2928), since the numbers are 0-based where After Effects scripting counts from 1.
fn value_text(p: &Value) -> String {
let label = p["options"].as_array().and_then(|o| o.iter().find(|o| o["value"] == p["value"])).and_then(|o| o["label"].as_str());
match label {
Some(l) => format!("{} ({l})", p["value"]),
None => p["value"].to_string(),
}
}
#[cfg(test)]
mod tests {
use super::*;
+30
View File
@@ -110,6 +110,36 @@ fn exec_set_get_with_saved_project() {
assert_eq!(v[1]["result"]["time"], v[0]["result"]["time"], "{v}");
}
/// #2928: the text listing gives an enum's label next to its number (0-based, unlike After
/// Effects scripting), the way `props --json` lists its `options`.
#[test]
fn props_lists_enum_labels() {
let proj = tmp("enum-labels.ecproj");
let p = proj.to_str().unwrap();
let anim = r#"{"layer":"t","properties":["opacity"]}"#;
ok_json(&[
"run",
"comp.new",
r#"{"name":"T","width":64,"height":36}"#,
"layer.newText",
r#"{"text":"AB","name":"t"}"#,
"layer.addTextAnimator",
anim,
"--empty",
"--save-as",
p,
]);
ok_json(&["set", "T", "t", "text/animators/animator/selectors/rangeSelector/advanced/shape", "1", p, "--save"]);
let out = bin().args(["props", "T", "t", p]).output().unwrap();
let text = String::from_utf8_lossy(&out.stdout);
let shape = text.lines().find(|l| l.contains("advanced/shape")).unwrap_or_else(|| panic!("no shape line in:\n{text}"));
assert!(shape.trim_end().ends_with("enum 1 (Ramp Up)"), "{shape}");
let units = text.lines().find(|l| l.contains("advanced/units")).unwrap_or_default();
assert!(units.trim_end().ends_with("0 (Percentage)"), "{units}");
let size = text.lines().find(|l| l.contains("transform/opacity")).unwrap_or_default();
assert!(size.trim_end().ends_with("100.0"), "a number without options stays bare: {size}");
}
/// `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]