From 4ee68f9fc91b4d6f3e8602291408ac36695b205c Mon Sep 17 00:00:00 2001 From: Yaroslav Bolyukin Date: Tue, 05 May 2026 00:54:30 +0000 Subject: [PATCH] feat(cli): --no-trailing-newline --- --- a/bindings/jsonnet/src/lib.rs +++ b/bindings/jsonnet/src/lib.rs @@ -44,8 +44,8 @@ /// If this does not match `LIB_JSONNET_VERSION` /// then there is a mismatch between header and compiled library. #[unsafe(no_mangle)] -pub extern "C" fn jsonnet_version() -> &'static [u8; 12] { - b"v0.22.0-rc1\0" +pub extern "C" fn jsonnet_version() -> &'static [u8; 8] { + b"v0.22.0\0" } unsafe fn parse_path(input: &CStr) -> Cow<'_, Path> { @@ -105,6 +105,7 @@ pub struct VM { state: State, manifest_format: Box, + trailing_newline: bool, trace_format: Box, tla_args: FxHashMap, } @@ -142,6 +143,7 @@ state, manifest_format: Box::new(JsonFormat::default()), trace_format: Box::new(CompactFormat::default()), + trailing_newline: true, tla_args: FxHashMap::new(), })) } @@ -181,6 +183,12 @@ }; } +/// Enable/disable trailing newline in manifested/string output. +#[unsafe(no_mangle)] +pub extern "C" fn jsonnet_set_trailing_newline(vm: &mut VM, enable: c_int) { + vm.trailing_newline = enable != 0; +} + /// Allocate, resize, or free a buffer. This will abort if the memory cannot be allocated. It will /// only return NULL if sz was zero. /// @@ -285,7 +293,10 @@ .and_then(|val| apply_tla(&vm.tla_args, val)) .and_then(|val| val.manifest(&vm.manifest_format)) { - Ok(v) => { + Ok(mut v) => { + if vm.trailing_newline { + v.push('\n'); + } *error = 0; CString::new(&*v as &str).unwrap().into_raw() } @@ -312,7 +323,7 @@ Ok(out) } -fn multi_to_raw(multi: Vec<(IStr, IStr)>) -> *const c_char { +fn multi_to_raw(multi: Vec<(IStr, IStr)>, trailing_newline: bool) -> *const c_char { let mut out = Vec::new(); for (i, (k, v)) in multi.iter().enumerate() { if i != 0 { @@ -321,6 +332,9 @@ out.extend_from_slice(k.as_bytes()); out.push(0); out.extend_from_slice(v.as_bytes()); + if trailing_newline { + out.push(b'\n'); + } } out.push(0); out.push(0); @@ -345,7 +359,7 @@ { Ok(v) => { *error = 0; - multi_to_raw(v) + multi_to_raw(v, vm.trailing_newline) } Err(e) => { *error = 1; @@ -374,7 +388,7 @@ { Ok(v) => { *error = 0; - multi_to_raw(v) + multi_to_raw(v, vm.trailing_newline) } Err(e) => { *error = 1; @@ -396,13 +410,16 @@ Ok(out) } -fn stream_to_raw(multi: Vec) -> *const c_char { +fn stream_to_raw(multi: Vec, trailing_newline: bool) -> *const c_char { let mut out = Vec::new(); for (i, v) in multi.iter().enumerate() { if i != 0 { out.push(0); } out.extend_from_slice(v.as_bytes()); + if trailing_newline { + out.push(b'\n'); + } } out.push(0); out.push(0); @@ -427,7 +444,7 @@ { Ok(v) => { *error = 0; - stream_to_raw(v) + stream_to_raw(v, vm.trailing_newline) } Err(e) => { *error = 1; @@ -456,7 +473,7 @@ { Ok(v) => { *error = 0; - stream_to_raw(v) + stream_to_raw(v, vm.trailing_newline) } Err(e) => { *error = 1; --- a/cmds/jrsonnet/src/main.rs +++ b/cmds/jrsonnet/src/main.rs @@ -238,7 +238,7 @@ data.manifest(&manifest_format) .with_description(|| format!("manifesting {field}"))?, )?; - if manifest_format.file_trailing_newline() { + if !opts.manifest.no_trailing_newline { writeln!(file)?; } file.flush()?; --- a/crates/jrsonnet-cli/src/manifest.rs +++ b/crates/jrsonnet-cli/src/manifest.rs @@ -38,6 +38,9 @@ /// [default: 3 for json, 2 for yaml/toml] #[clap(long)] line_padding: Option, + /// No not add a trailing newline to the output + #[clap(long)] + pub no_trailing_newline: bool, /// Preserve order in object manifestification #[cfg(feature = "exp-preserve-order")] #[clap(long)] --- a/crates/jrsonnet-evaluator/src/manifest.rs +++ b/crates/jrsonnet-evaluator/src/manifest.rs @@ -11,13 +11,6 @@ self.manifest_buf(val, &mut out)?; Ok(out) } - /// When outputing to file, is it safe to append a trailing newline (I.e newline won't change - /// the meaning). - /// - /// Default implementation returns `true` - fn file_trailing_newline(&self) -> bool { - true - } } impl ManifestFormat for Box where @@ -26,10 +19,6 @@ fn manifest_buf(&self, val: Val, buf: &mut String) -> Result<()> { let inner = &**self; inner.manifest_buf(val, buf) - } - fn file_trailing_newline(&self) -> bool { - let inner = &**self; - inner.file_trailing_newline() } } impl ManifestFormat for &'_ T @@ -40,10 +29,6 @@ let inner = &**self; inner.manifest_buf(val, buf) } - fn file_trailing_newline(&self) -> bool { - let inner = &**self; - inner.file_trailing_newline() - } } pub struct BlackBoxFormat; @@ -398,9 +383,6 @@ return Ok(()); } JSON_TO_STRING.manifest_buf(val, out) - } - fn file_trailing_newline(&self) -> bool { - false } } pub struct StringFormat; @@ -414,9 +396,6 @@ }; write!(out, "{s}").unwrap(); Ok(()) - } - fn file_trailing_newline(&self) -> bool { - false } } -- gitstuff