difftreelog
feat(cli) --no-trailing-newline
in: master
4 files changed
bindings/jsonnet/src/lib.rsdiffbeforeafterboth--- 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<dyn ManifestFormat>,
+ trailing_newline: bool,
trace_format: Box<dyn TraceFormat>,
tla_args: FxHashMap<IStr, TlaArg>,
}
@@ -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<IStr>) -> *const c_char {
+fn stream_to_raw(multi: Vec<IStr>, 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;
cmds/jrsonnet/src/main.rsdiffbeforeafterboth--- 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()?;
crates/jrsonnet-cli/src/manifest.rsdiffbeforeafterboth1use std::path::PathBuf;23use clap::{Parser, ValueEnum};4use jrsonnet_evaluator::manifest::{5 JsonFormat, ManifestFormat, StringFormat, ToStringFormat, YamlStreamFormat,6};7use jrsonnet_stdlib::{IniFormat, TomlFormat, XmlJsonmlFormat, YamlFormat};89#[derive(Clone, Copy, ValueEnum)]10pub enum ManifestFormatName {11 /// Expect string as output, and write them directly12 String,13 Json,14 Yaml,15 Toml,16 XmlJsonml,17 Ini,18}1920#[derive(Parser)]21#[clap(next_help_heading = "MANIFESTIFICATION OUTPUT")]22pub struct ManifestOpts {23 /// Output format, wraps resulting value to corresponding std.manifest call24 ///25 /// [default: json, yaml when -y is used]26 #[clap(long, short = 'f')]27 format: Option<ManifestFormatName>,28 /// Expect plain string as output.29 /// Mutually exclusive with `--format`30 #[clap(long, short = 'S', conflicts_with = "format")]31 string: bool,32 /// Write output as YAML stream, can be used with --format json/yaml33 #[clap(long, short = 'y', conflicts_with = "string")]34 yaml_stream: bool,35 /// Number of spaces to pad output manifest with.36 /// `0` for hard tabs, `-1` for single line output37 ///38 /// [default: 3 for json, 2 for yaml/toml]39 #[clap(long)]40 line_padding: Option<usize>,41 /// Preserve order in object manifestification42 #[cfg(feature = "exp-preserve-order")]43 #[clap(long)]44 pub preserve_order: bool,45}46impl ManifestOpts {47 pub fn manifest_format(&self) -> Box<dyn ManifestFormat> {48 let format: Box<dyn ManifestFormat> = if self.string {49 Box::new(StringFormat)50 } else {51 #[cfg(feature = "exp-preserve-order")]52 let preserve_order = self.preserve_order;53 let format = match self.format {54 Some(v) => v,55 None if self.yaml_stream => ManifestFormatName::Yaml,56 None => ManifestFormatName::Json,57 };58 match format {59 ManifestFormatName::String => Box::new(ToStringFormat),60 ManifestFormatName::Json => Box::new(JsonFormat::cli(61 self.line_padding.unwrap_or(3),62 #[cfg(feature = "exp-preserve-order")]63 preserve_order,64 )),65 ManifestFormatName::Yaml => Box::new(YamlFormat::cli(66 self.line_padding.unwrap_or(2),67 #[cfg(feature = "exp-preserve-order")]68 preserve_order,69 )),70 ManifestFormatName::Toml => Box::new(TomlFormat::cli(71 self.line_padding.unwrap_or(2),72 #[cfg(feature = "exp-preserve-order")]73 preserve_order,74 )),75 ManifestFormatName::XmlJsonml => Box::new(XmlJsonmlFormat::cli()),76 ManifestFormatName::Ini => Box::new(IniFormat::cli(77 #[cfg(feature = "exp-preserve-order")]78 preserve_order,79 )),80 }81 };82 if self.yaml_stream {83 Box::new(YamlStreamFormat::cli(format))84 } else {85 format86 }87 }88}8990#[derive(Parser)]91pub struct OutputOpts {92 /// Write to the output file rather than stdout93 #[clap(long, short = 'o')]94 pub output_file: Option<PathBuf>,95 /// Automatically creates all parent directories for files96 #[clap(long, short = 'c')]97 pub create_output_dirs: bool,98 /// Write multiple files to the directory, list files on stdout99 #[clap(long, short = 'm')]100 pub multi: Option<PathBuf>,101}1use std::path::PathBuf;23use clap::{Parser, ValueEnum};4use jrsonnet_evaluator::manifest::{5 JsonFormat, ManifestFormat, StringFormat, ToStringFormat, YamlStreamFormat,6};7use jrsonnet_stdlib::{IniFormat, TomlFormat, XmlJsonmlFormat, YamlFormat};89#[derive(Clone, Copy, ValueEnum)]10pub enum ManifestFormatName {11 /// Expect string as output, and write them directly12 String,13 Json,14 Yaml,15 Toml,16 XmlJsonml,17 Ini,18}1920#[derive(Parser)]21#[clap(next_help_heading = "MANIFESTIFICATION OUTPUT")]22pub struct ManifestOpts {23 /// Output format, wraps resulting value to corresponding std.manifest call24 ///25 /// [default: json, yaml when -y is used]26 #[clap(long, short = 'f')]27 format: Option<ManifestFormatName>,28 /// Expect plain string as output.29 /// Mutually exclusive with `--format`30 #[clap(long, short = 'S', conflicts_with = "format")]31 string: bool,32 /// Write output as YAML stream, can be used with --format json/yaml33 #[clap(long, short = 'y', conflicts_with = "string")]34 yaml_stream: bool,35 /// Number of spaces to pad output manifest with.36 /// `0` for hard tabs, `-1` for single line output37 ///38 /// [default: 3 for json, 2 for yaml/toml]39 #[clap(long)]40 line_padding: Option<usize>,41 /// No not add a trailing newline to the output42 #[clap(long)]43 pub no_trailing_newline: bool,44 /// Preserve order in object manifestification45 #[cfg(feature = "exp-preserve-order")]46 #[clap(long)]47 pub preserve_order: bool,48}49impl ManifestOpts {50 pub fn manifest_format(&self) -> Box<dyn ManifestFormat> {51 let format: Box<dyn ManifestFormat> = if self.string {52 Box::new(StringFormat)53 } else {54 #[cfg(feature = "exp-preserve-order")]55 let preserve_order = self.preserve_order;56 let format = match self.format {57 Some(v) => v,58 None if self.yaml_stream => ManifestFormatName::Yaml,59 None => ManifestFormatName::Json,60 };61 match format {62 ManifestFormatName::String => Box::new(ToStringFormat),63 ManifestFormatName::Json => Box::new(JsonFormat::cli(64 self.line_padding.unwrap_or(3),65 #[cfg(feature = "exp-preserve-order")]66 preserve_order,67 )),68 ManifestFormatName::Yaml => Box::new(YamlFormat::cli(69 self.line_padding.unwrap_or(2),70 #[cfg(feature = "exp-preserve-order")]71 preserve_order,72 )),73 ManifestFormatName::Toml => Box::new(TomlFormat::cli(74 self.line_padding.unwrap_or(2),75 #[cfg(feature = "exp-preserve-order")]76 preserve_order,77 )),78 ManifestFormatName::XmlJsonml => Box::new(XmlJsonmlFormat::cli()),79 ManifestFormatName::Ini => Box::new(IniFormat::cli(80 #[cfg(feature = "exp-preserve-order")]81 preserve_order,82 )),83 }84 };85 if self.yaml_stream {86 Box::new(YamlStreamFormat::cli(format))87 } else {88 format89 }90 }91}9293#[derive(Parser)]94pub struct OutputOpts {95 /// Write to the output file rather than stdout96 #[clap(long, short = 'o')]97 pub output_file: Option<PathBuf>,98 /// Automatically creates all parent directories for files99 #[clap(long, short = 'c')]100 pub create_output_dirs: bool,101 /// Write multiple files to the directory, list files on stdout102 #[clap(long, short = 'm')]103 pub multi: Option<PathBuf>,104}crates/jrsonnet-evaluator/src/manifest.rsdiffbeforeafterboth--- 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<T> ManifestFormat for Box<T>
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<T> 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
}
}