diff --git a/Cargo.lock b/Cargo.lock index 1c972d43..f6997017 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1239,7 +1239,6 @@ version = "0.20.9" dependencies = [ "ansi_term", "anyhow", - "atty", "clap", "ctor", "ctrlc", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 97c6a129..4d38eecc 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -27,7 +27,6 @@ wasm = ["tree-sitter/wasm", "tree-sitter-loader/wasm"] [dependencies] ansi_term = "0.12.1" anyhow = "1.0.72" -atty = "0.2.14" clap = "2.32" ctrlc = { version = "3.4.0", features = ["termination"] } difference = "2.0.0" diff --git a/cli/src/generate/dsl.js b/cli/src/generate/dsl.js index 4fdfbef1..22286329 100644 --- a/cli/src/generate/dsl.js +++ b/cli/src/generate/dsl.js @@ -385,7 +385,7 @@ function grammar(baseGrammar, options) { throw new Error("Grammar must have at least one rule."); } - return {name, word, rules, extras, conflicts, precedences, externals, inline, supertypes}; + return { name, word, rules, extras, conflicts, precedences, externals, inline, supertypes }; } function checkArguments(ruleCount, caller, callerName, suffix = '') { @@ -419,4 +419,4 @@ global.grammar = grammar; global.field = field; const result = require(process.env.TREE_SITTER_GRAMMAR_PATH); -console.log(JSON.stringify(result, null, 2)); +process.stdout.write(JSON.stringify(result, null, null)); diff --git a/cli/src/generate/mod.rs b/cli/src/generate/mod.rs index 70a7a12f..cf8206e9 100644 --- a/cli/src/generate/mod.rs +++ b/cli/src/generate/mod.rs @@ -209,13 +209,36 @@ fn load_js_grammar_file(grammar_path: &Path, js_runtime: Option<&str>) -> Result .with_context(|| "Failed to read output from node")?; match output.status.code() { None => panic!("Node process was killed"), - Some(0) => {} - Some(code) => return Err(anyhow!("Node process exited with status {code}")), + Some(0) => { + let stdout = + String::from_utf8(output.stdout).with_context(|| "Got invalid UTF8 from node")?; + + let mut node_output = ""; + let mut grammar_json = &stdout[..]; + + if let Some(pos) = stdout.rfind('\n') { + // If there's a newline, split the last line from the rest of the output + node_output = &stdout[..pos]; + grammar_json = &stdout[pos + 1..]; + } + + // If we got any output from the node process that isn't the grammar JSON + if !node_output.is_empty() { + let mut stdout = std::io::stdout().lock(); + stdout.write_all(node_output.as_bytes())?; + stdout.write_all(b"\n")?; + stdout.flush()?; + } + + Ok(serde_json::to_string_pretty( + &serde_json::from_str::(grammar_json) + .with_context(|| "Failed to parse grammar JSON")?, + ) + .with_context(|| "Failed to serialize grammar JSON")? + + "\n") + } + Some(code) => Err(anyhow!("Node process exited with status {code}")), } - let mut result = - String::from_utf8(output.stdout).with_context(|| "Got invalid UTF8 from node")?; - result.push('\n'); - Ok(result) } fn write_file(path: &Path, body: impl AsRef<[u8]>) -> Result<()> {