From cf4864a9cd4e0d840fef429d45b2f724b187c233 Mon Sep 17 00:00:00 2001 From: David Date: Sun, 14 Jul 2024 09:19:09 +0100 Subject: [PATCH] JSON format output keeps braces on same line (issue #13326) (#13352) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description This is a minor breaking change to JSON output syntax/style of the `to json` command. This fixes #13326 by setting `braces_same_line` to true when creating a new `HjsonFormatter`. This then simply tells `HjsonFormatter` to keep the braces on the same line when outputting which is what I expected nu's `to json` command to do. There are almost no changes to nushell itself, all changes are contained within `nu-json` crate (minus any documentation updates). Oh, almost forgot to mention, to get the tests compiling, I added fancy_regex as a _dev_ dependency to nu-json. I could look into eliminating that if desirable. # User-Facing Changes **Breaking Change** nushell now outputs the desired result using the reproduction command from the issue: ``` echo '{"version": "v0.4.4","notes": "blablabla","pub_date": "2024-05-04T16:05:00Z","platforms":{"windows-x86_64":{"signature": "blablabla","url": "https://blablabla"}}}' | from json | to json ``` outputs: ``` { "version": "v0.4.4", "notes": "blablabla", "pub_date": "2024-05-04T16:05:00Z", "platforms": { "windows-x86_64": { "signature": "blablabla", "url": "https://blablabla" } } } ``` whereas previously it would push the opening braces onto a new line: ``` { "version": "v0.4.4", "notes": "blablabla", "pub_date": "2024-05-04T16:05:00Z", "platforms": { "windows-x86_64": { "signature": "blablabla", "url": "https://blablabla" } } } ``` # Tests + Formatting toolkit check pr mostly passes - there are regrettably some tests not passing on my windows machine _before making any changes_ (I may look into this as a separate issue) I have re-enabled the [hjson tests](https://github.com/nushell/nushell/blob/main/crates/nu-json/tests/main.rs). This is done in the second commit 🙂 They have a crucial difference to what they were previously asserting: * nu-json outputs in json syntax, not hjson syntax I think this is desirable, but I'm not aware of the history of these tests. # After Submitting I suspect there `to json` command examples will need updating to match, haven't checked yet! --- Cargo.lock | 3 +++ crates/nu-json/Cargo.toml | 13 +++++++++---- crates/nu-json/src/ser.rs | 2 +- crates/nu-json/tests/main.rs | 27 ++++++++------------------- 4 files changed, 21 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c8bfe4ab4e..2247e462fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3195,7 +3195,10 @@ dependencies = [ name = "nu-json" version = "0.95.1" dependencies = [ + "fancy-regex", "linked-hash-map", + "nu-path", + "nu-test-support", "num-traits", "serde", "serde_json", diff --git a/crates/nu-json/Cargo.toml b/crates/nu-json/Cargo.toml index 04c39bdac5..a3b61042b1 100644 --- a/crates/nu-json/Cargo.toml +++ b/crates/nu-json/Cargo.toml @@ -1,5 +1,8 @@ [package] -authors = ["The Nushell Project Developers", "Christian Zangl "] +authors = [ + "The Nushell Project Developers", + "Christian Zangl ", +] description = "Fork of serde-hjson" repository = "https://github.com/nushell/nushell/tree/main/crates/nu-json" edition = "2021" @@ -19,9 +22,11 @@ default = ["preserve_order"] [dependencies] linked-hash-map = { version = "0.5", optional = true } num-traits = { workspace = true } -serde = { workspace = true } +serde = { workspace = true } serde_json = { workspace = true } [dev-dependencies] -# nu-path = { path="../nu-path", version = "0.95.1" } -# serde_json = "1.0" \ No newline at end of file +nu-test-support = { path = "../nu-test-support", version = "0.95.1" } +nu-path = { path = "../nu-path", version = "0.95.1" } +serde_json = "1.0" +fancy-regex = "0.13.0" diff --git a/crates/nu-json/src/ser.rs b/crates/nu-json/src/ser.rs index d9df1aea56..4b15740602 100644 --- a/crates/nu-json/src/ser.rs +++ b/crates/nu-json/src/ser.rs @@ -714,7 +714,7 @@ impl<'a> HjsonFormatter<'a> { stack: Vec::new(), at_colon: false, indent, - braces_same_line: false, + braces_same_line: true, } } } diff --git a/crates/nu-json/tests/main.rs b/crates/nu-json/tests/main.rs index c209bc0a52..0ac3e403e2 100644 --- a/crates/nu-json/tests/main.rs +++ b/crates/nu-json/tests/main.rs @@ -1,7 +1,5 @@ -// FIXME: re-enable tests -/* -use nu_json::Value; use fancy_regex::Regex; +use nu_json::Value; use std::fs; use std::io; use std::path::{Path, PathBuf}; @@ -11,7 +9,7 @@ fn txt(text: &str) -> String { #[cfg(windows)] { - out.replace("\r\n", "").replace("\n", "") + out.replace("\r\n", "").replace('\n', "") } #[cfg(not(windows))] @@ -21,15 +19,7 @@ fn txt(text: &str) -> String { } fn hjson_expectations() -> PathBuf { - let assets = nu_test_support::fs::assets().join("nu_json"); - - nu_path::canonicalize(assets.clone()).unwrap_or_else(|e| { - panic!( - "Couldn't canonicalize hjson assets path {}: {:?}", - assets.display(), - e - ) - }) + nu_test_support::fs::assets().join("nu_json") } fn get_test_content(name: &str) -> io::Result { @@ -50,7 +40,7 @@ fn get_result_content(name: &str) -> io::Result<(String, String)> { let p1 = format!("{}/{}_result.json", expectations.display(), name); let p2 = format!("{}/{}_result.hjson", expectations.display(), name); - Ok((fs::read_to_string(&p1)?, fs::read_to_string(&p2)?)) + Ok((fs::read_to_string(p1)?, fs::read_to_string(p2)?)) } macro_rules! run_test { @@ -73,7 +63,8 @@ macro_rules! run_test { let actual_hjson = txt(&actual_hjson); let actual_json = $fix(serde_json::to_string_pretty(&udata).unwrap()); let actual_json = txt(&actual_json); - if rhjson != actual_hjson { + // nu_json::to_string now outputs json instead of hjson! + if rjson != actual_hjson { println!( "{:?}\n---hjson expected\n{}\n---hjson actual\n{}\n---\n", name, rhjson, actual_hjson @@ -85,7 +76,7 @@ macro_rules! run_test { name, rjson, actual_json ); } - assert!(rhjson == actual_hjson && rjson == actual_json); + assert!(rjson == actual_hjson && rjson == actual_json); } }}; } @@ -198,7 +189,7 @@ fn test_hjson() { let missing = all .into_iter() - .filter(|x| done.iter().find(|y| &x == y) == None) + .filter(|x| !done.iter().any(|y| x == y)) .collect::>(); if !missing.is_empty() { @@ -208,5 +199,3 @@ fn test_hjson() { panic!(); } } - -*/