difftreelog
chore rename executable to jrsonnet
in: master
6 files changed
cmds/jrsonnet/Cargo.tomldiffbeforeafterboth--- /dev/null
+++ b/cmds/jrsonnet/Cargo.toml
@@ -0,0 +1,17 @@
+[package]
+name = "jrsonnet"
+version = "0.1.0"
+authors = ["Лач <iam@lach.pw>"]
+edition = "2018"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+jsonnet-evaluator = { path = "../../crates/jsonnet-evaluator" }
+jsonnet-parser = { path = "../../crates/jsonnet-parser" }
+annotate-snippets = "0.8.0"
+
+[dependencies.clap]
+version = "3.0.0-beta.1"
+default-features = false
+features = ["std", "derive"]
cmds/jrsonnet/src/location.rsdiffbeforeafterbothno changes
cmds/jrsonnet/src/main.rsdiffbeforeafterboth--- /dev/null
+++ b/cmds/jrsonnet/src/main.rs
@@ -0,0 +1,269 @@
+pub mod location;
+
+use clap::Clap;
+use jsonnet_evaluator::{EvaluationState, LocError, StackTrace, Val};
+use location::{offset_to_location, CodeLocation};
+use std::env::current_dir;
+use std::{path::PathBuf, str::FromStr};
+
+enum Format {
+ None,
+ Json,
+ Yaml,
+}
+
+impl FromStr for Format {
+ type Err = &'static str;
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ Ok(match s {
+ "none" => Format::None,
+ "json" => Format::Json,
+ "yaml" => Format::Yaml,
+ _ => return Err("no such format"),
+ })
+ }
+}
+
+#[derive(PartialEq)]
+enum TraceFormat {
+ CppJsonnet,
+ GoJsonnet,
+ Custom,
+}
+impl FromStr for TraceFormat {
+ type Err = &'static str;
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ Ok(match s {
+ "cpp" => TraceFormat::CppJsonnet,
+ "go" => TraceFormat::GoJsonnet,
+ "default" => TraceFormat::Custom,
+ _ => return Err("no such format"),
+ })
+ }
+}
+
+#[derive(Clap)]
+#[clap(version = "0.1.0", author = "Lach <iam@lach.pw>")]
+struct Opts {
+ #[clap(long, about = "Disable global std variable")]
+ no_stdlib: bool,
+ #[clap(long, about = "Add external string")]
+ ext_str: Option<Vec<String>>,
+ #[clap(long, about = "Add external string from code")]
+ ext_code: Option<Vec<String>>,
+ #[clap(long, about = "Add TLA")]
+ tla_str: Option<Vec<String>>,
+ #[clap(long, about = "Add TLA from code")]
+ tla_code: Option<Vec<String>>,
+ #[clap(long, short = "f", default_value = "json", possible_values = &["none", "json", "yaml"], about = "Output format, wraps resulting value to corresponding std.manifest call")]
+ format: Format,
+ #[clap(long, default_value = "default", possible_values = &["cpp", "go", "default"], about = "Emulated needed stacktrace display")]
+ trace_format: TraceFormat,
+
+ #[clap(
+ long,
+ short = "s",
+ default_value = "200",
+ about = "Number of allowed stack frames"
+ )]
+ max_stack: usize,
+ #[clap(
+ long,
+ short = "t",
+ default_value = "20",
+ about = "Max length of stack trace before cropping"
+ )]
+ max_trace: usize,
+
+ #[clap(about = "File to compile", index = 1)]
+ input: String,
+}
+
+fn main() {
+ let opts: Opts = Opts::parse();
+ let evaluator = jsonnet_evaluator::EvaluationState::default();
+ if !opts.no_stdlib {
+ evaluator.add_stdlib();
+ }
+ let mut input = current_dir().unwrap();
+ input.push(opts.input.clone());
+ let code_string = String::from_utf8(std::fs::read(opts.input.clone()).unwrap()).unwrap();
+ if let Err(e) = evaluator.add_file(input.clone(), code_string.clone()) {
+ print_syntax_error(e, &input, &code_string);
+ std::process::exit(2);
+ }
+ let result = evaluator.evaluate_file(&input);
+ match result {
+ Ok(v) => {
+ let v = match opts.format {
+ Format::Json => {
+ if opts.no_stdlib {
+ evaluator.add_stdlib();
+ }
+ evaluator.add_global("__tmp__to_json__".to_owned(), v);
+ let v = evaluator
+ .parse_evaluate_raw("std.manifestJsonEx(__tmp__to_json__, \" \")");
+ match v {
+ Ok(v) => v,
+ Err(err) => {
+ print_error(&err, evaluator, &opts);
+ std::process::exit(2);
+ }
+ }
+ }
+ Format::Yaml => {
+ if opts.no_stdlib {
+ evaluator.add_stdlib();
+ }
+ evaluator.add_global("__tmp__to_yaml__".to_owned(), v);
+ let v = evaluator
+ .parse_evaluate_raw("std.manifestYamlDoc(__tmp__to_yaml__, \" \")");
+ match v {
+ Ok(v) => v,
+ Err(err) => {
+ print_error(&err, evaluator, &opts);
+ std::process::exit(2);
+ }
+ }
+ }
+ _ => v,
+ };
+ match v {
+ Val::Str(s) => println!("{}", s),
+ Val::Num(n) => println!("{}", n),
+ _v => eprintln!(
+ "jsonnet output is not a string.\nDid you forgot to set --format, or wrap your data with std.manifestJson?"
+ ),
+ }
+ }
+ Err(err) => {
+ print_error(&err, evaluator, &opts);
+ }
+ }
+}
+
+fn print_error(err: &LocError, evaluator: EvaluationState, opts: &Opts) {
+ println!("Error: {:?}", err.0);
+ print_trace(&(err.1), evaluator, &opts);
+}
+
+fn print_syntax_error(error: jsonnet_parser::ParseError, file: &PathBuf, code: &str) {
+ use annotate_snippets::{
+ display_list::{DisplayList, FormatOptions},
+ snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation},
+ };
+ //&("Expected: ".to_owned() + error.expected)
+ let origin = file.to_str().unwrap();
+ let error_message = format!("Expected: {}", error.expected);
+ let snippet = Snippet {
+ opt: FormatOptions {
+ color: true,
+ ..Default::default()
+ },
+ title: Some(Annotation {
+ label: Some(&error_message),
+ id: None,
+ annotation_type: AnnotationType::Error,
+ }),
+ footer: vec![],
+ slices: vec![Slice {
+ source: &code,
+ line_start: 1,
+ origin: Some(origin),
+ fold: false,
+ annotations: vec![SourceAnnotation {
+ label: "At this position",
+ annotation_type: AnnotationType::Error,
+ range: (error.location.offset, error.location.offset + 1),
+ }],
+ }],
+ };
+
+ let dl = DisplayList::from(snippet);
+ println!("{}", dl);
+}
+
+fn print_trace(trace: &StackTrace, evaluator: EvaluationState, opts: &Opts) {
+ use annotate_snippets::{
+ display_list::{DisplayList, FormatOptions},
+ snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation},
+ };
+ for item in trace.0.iter() {
+ let desc = &item.1;
+ if (item.0).1.is_none() {
+ continue;
+ }
+ let source = (item.0).1.clone().unwrap();
+ let code = evaluator.get_source(&source.0);
+ if code.is_none() {
+ continue;
+ }
+ let code = code.unwrap();
+ let start_end = offset_to_location(&code, &[source.1, source.2]);
+ if opts.trace_format == TraceFormat::Custom {
+ let source_fragment: String = code
+ .chars()
+ .skip(start_end[0].line_start_offset)
+ .take(start_end[1].line_end_offset - start_end[0].line_start_offset)
+ .collect();
+ let snippet = Snippet {
+ opt: FormatOptions {
+ color: true,
+ ..Default::default()
+ },
+ title: Some(Annotation {
+ label: Some(&item.1),
+ id: None,
+ annotation_type: AnnotationType::Error,
+ }),
+ footer: vec![],
+ slices: vec![Slice {
+ source: &source_fragment,
+ line_start: start_end[0].line,
+ origin: Some(&source.0.to_str().unwrap()),
+ fold: false,
+ annotations: vec![SourceAnnotation {
+ label: desc,
+ annotation_type: AnnotationType::Error,
+ range: (
+ source.1 - start_end[0].line_start_offset,
+ source.2 - start_end[0].line_start_offset,
+ ),
+ }],
+ }],
+ };
+
+ let dl = DisplayList::from(snippet);
+ println!("{}", dl);
+ } else {
+ print_jsonnet_pair(
+ source.0.to_str().unwrap(),
+ &start_end[0],
+ &start_end[1],
+ opts.trace_format == TraceFormat::GoJsonnet,
+ );
+ }
+ }
+}
+
+fn print_jsonnet_pair(file: &str, start: &CodeLocation, end: &CodeLocation, is_go: bool) {
+ if is_go {
+ print!(" ");
+ } else {
+ print!(" ");
+ }
+ print!("{}:", file);
+ if start.line == end.line {
+ // IDK why, but this is the behavior original jsonnet cpp impl shows
+ if start.column == end.column || !is_go && start.column + 1 == end.column {
+ println!("{}:{}", start.line, end.column)
+ } else {
+ println!("{}:{}-{}", start.line, start.column, end.column);
+ }
+ } else {
+ println!(
+ "({}:{})-({}:{})",
+ start.line, end.column, start.line, end.column
+ );
+ }
+}
cmds/jsonnet/Cargo.tomldiffbeforeafterboth--- a/cmds/jsonnet/Cargo.toml
+++ /dev/null
@@ -1,17 +0,0 @@
-[package]
-name = "jsonnet"
-version = "0.1.0"
-authors = ["Лач <iam@lach.pw>"]
-edition = "2018"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-jsonnet-evaluator = { path = "../../crates/jsonnet-evaluator" }
-jsonnet-parser = { path = "../../crates/jsonnet-parser" }
-annotate-snippets = "0.8.0"
-
-[dependencies.clap]
-version = "3.0.0-beta.1"
-default-features = false
-features = ["std", "derive"]
cmds/jsonnet/src/location.rsdiffbeforeafterboth--- a/cmds/jsonnet/src/location.rs
+++ /dev/null
@@ -1,99 +0,0 @@
-#[derive(Clone, PartialEq, Debug)]
-pub struct CodeLocation {
- pub line: usize,
- pub column: usize,
-
- pub line_start_offset: usize,
- pub line_end_offset: usize,
-}
-
-pub fn offset_to_location(file: &str, offsets: &[usize]) -> Vec<CodeLocation> {
- if offsets.is_empty() {
- return vec![];
- }
- let mut line = 1;
- let mut column = 0;
- let max_offset = *offsets.iter().max().unwrap();
-
- let mut offset_map = offsets
- .iter()
- .enumerate()
- .map(|(pos, offset)| (*offset, pos))
- .collect::<Vec<_>>();
- offset_map.sort_by_key(|v| v.0);
- offset_map.reverse();
-
- let mut out = vec![
- CodeLocation {
- column: 0,
- line: 0,
- line_start_offset: 0,
- line_end_offset: 0
- };
- offsets.len()
- ];
- let mut with_no_known_line_ending = vec![];
- let mut this_line_offset = 0;
- for (pos, ch) in file.chars().enumerate() {
- column += 1;
- match offset_map.last() {
- Some(x) if x.0 == pos => {
- let out_idx = x.1;
- with_no_known_line_ending.push(out_idx);
- out[out_idx].line = line;
- out[out_idx].column = column;
- out[out_idx].line_start_offset = this_line_offset + 1;
- offset_map.pop();
- }
- _ => {}
- }
- if ch == '\n' {
- line += 1;
- column = 0;
-
- for idx in with_no_known_line_ending.drain(..) {
- out[idx].line_end_offset = pos;
- }
- this_line_offset = pos;
-
- if pos == max_offset + 1 {
- break;
- }
- }
- }
- let file_end = file.chars().count();
- for idx in with_no_known_line_ending {
- out[idx].line_end_offset = file_end;
- }
-
- out
-}
-
-#[cfg(test)]
-pub mod tests {
- use super::{offset_to_location, CodeLocation};
-
- #[test]
- fn test() {
- assert_eq!(
- offset_to_location(
- "hello world\n_______________________________________________________",
- &[0, 14]
- ),
- vec![
- CodeLocation {
- line: 1,
- column: 1,
- line_start_offset: 0,
- line_end_offset: 11
- },
- CodeLocation {
- line: 2,
- column: 3,
- line_start_offset: 11,
- line_end_offset: 67
- }
- ]
- )
- }
-}
cmds/jsonnet/src/main.rsdiffbeforeafterboth--- a/cmds/jsonnet/src/main.rs
+++ /dev/null
@@ -1,269 +0,0 @@
-pub mod location;
-
-use clap::Clap;
-use jsonnet_evaluator::{EvaluationState, LocError, StackTrace, Val};
-use location::{offset_to_location, CodeLocation};
-use std::env::current_dir;
-use std::{path::PathBuf, str::FromStr};
-
-enum Format {
- None,
- Json,
- Yaml,
-}
-
-impl FromStr for Format {
- type Err = &'static str;
- fn from_str(s: &str) -> Result<Self, Self::Err> {
- Ok(match s {
- "none" => Format::None,
- "json" => Format::Json,
- "yaml" => Format::Yaml,
- _ => return Err("no such format"),
- })
- }
-}
-
-#[derive(PartialEq)]
-enum TraceFormat {
- CppJsonnet,
- GoJsonnet,
- Custom,
-}
-impl FromStr for TraceFormat {
- type Err = &'static str;
- fn from_str(s: &str) -> Result<Self, Self::Err> {
- Ok(match s {
- "cpp" => TraceFormat::CppJsonnet,
- "go" => TraceFormat::GoJsonnet,
- "default" => TraceFormat::Custom,
- _ => return Err("no such format"),
- })
- }
-}
-
-#[derive(Clap)]
-#[clap(version = "0.1.0", author = "Lach <iam@lach.pw>")]
-struct Opts {
- #[clap(long, about = "Disable global std variable")]
- no_stdlib: bool,
- #[clap(long, about = "Add external string")]
- ext_str: Option<Vec<String>>,
- #[clap(long, about = "Add external string from code")]
- ext_code: Option<Vec<String>>,
- #[clap(long, about = "Add TLA")]
- tla_str: Option<Vec<String>>,
- #[clap(long, about = "Add TLA from code")]
- tla_code: Option<Vec<String>>,
- #[clap(long, short = "f", default_value = "json", possible_values = &["none", "json", "yaml"], about = "Output format, wraps resulting value to corresponding std.manifest call")]
- format: Format,
- #[clap(long, default_value = "default", possible_values = &["cpp", "go", "default"], about = "Emulated needed stacktrace display")]
- trace_format: TraceFormat,
-
- #[clap(
- long,
- short = "s",
- default_value = "200",
- about = "Number of allowed stack frames"
- )]
- max_stack: usize,
- #[clap(
- long,
- short = "t",
- default_value = "20",
- about = "Max length of stack trace before cropping"
- )]
- max_trace: usize,
-
- #[clap(about = "File to compile", index = 1)]
- input: String,
-}
-
-fn main() {
- let opts: Opts = Opts::parse();
- let evaluator = jsonnet_evaluator::EvaluationState::default();
- if !opts.no_stdlib {
- evaluator.add_stdlib();
- }
- let mut input = current_dir().unwrap();
- input.push(opts.input.clone());
- let code_string = String::from_utf8(std::fs::read(opts.input.clone()).unwrap()).unwrap();
- if let Err(e) = evaluator.add_file(input.clone(), code_string.clone()) {
- print_syntax_error(e, &input, &code_string);
- std::process::exit(2);
- }
- let result = evaluator.evaluate_file(&input);
- match result {
- Ok(v) => {
- let v = match opts.format {
- Format::Json => {
- if opts.no_stdlib {
- evaluator.add_stdlib();
- }
- evaluator.add_global("__tmp__to_json__".to_owned(), v);
- let v = evaluator
- .parse_evaluate_raw("std.manifestJsonEx(__tmp__to_json__, \" \")");
- match v {
- Ok(v) => v,
- Err(err) => {
- print_error(&err, evaluator, &opts);
- std::process::exit(2);
- }
- }
- }
- Format::Yaml => {
- if opts.no_stdlib {
- evaluator.add_stdlib();
- }
- evaluator.add_global("__tmp__to_yaml__".to_owned(), v);
- let v = evaluator
- .parse_evaluate_raw("std.manifestYamlDoc(__tmp__to_yaml__, \" \")");
- match v {
- Ok(v) => v,
- Err(err) => {
- print_error(&err, evaluator, &opts);
- std::process::exit(2);
- }
- }
- }
- _ => v,
- };
- match v {
- Val::Str(s) => println!("{}", s),
- Val::Num(n) => println!("{}", n),
- _v => eprintln!(
- "jsonnet output is not a string.\nDid you forgot to set --format, or wrap your data with std.manifestJson?"
- ),
- }
- }
- Err(err) => {
- print_error(&err, evaluator, &opts);
- }
- }
-}
-
-fn print_error(err: &LocError, evaluator: EvaluationState, opts: &Opts) {
- println!("Error: {:?}", err.0);
- print_trace(&(err.1), evaluator, &opts);
-}
-
-fn print_syntax_error(error: jsonnet_parser::ParseError, file: &PathBuf, code: &str) {
- use annotate_snippets::{
- display_list::{DisplayList, FormatOptions},
- snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation},
- };
- //&("Expected: ".to_owned() + error.expected)
- let origin = file.to_str().unwrap();
- let error_message = format!("Expected: {}", error.expected);
- let snippet = Snippet {
- opt: FormatOptions {
- color: true,
- ..Default::default()
- },
- title: Some(Annotation {
- label: Some(&error_message),
- id: None,
- annotation_type: AnnotationType::Error,
- }),
- footer: vec![],
- slices: vec![Slice {
- source: &code,
- line_start: 1,
- origin: Some(origin),
- fold: false,
- annotations: vec![SourceAnnotation {
- label: "At this position",
- annotation_type: AnnotationType::Error,
- range: (error.location.offset, error.location.offset + 1),
- }],
- }],
- };
-
- let dl = DisplayList::from(snippet);
- println!("{}", dl);
-}
-
-fn print_trace(trace: &StackTrace, evaluator: EvaluationState, opts: &Opts) {
- use annotate_snippets::{
- display_list::{DisplayList, FormatOptions},
- snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation},
- };
- for item in trace.0.iter() {
- let desc = &item.1;
- if (item.0).1.is_none() {
- continue;
- }
- let source = (item.0).1.clone().unwrap();
- let code = evaluator.get_source(&source.0);
- if code.is_none() {
- continue;
- }
- let code = code.unwrap();
- let start_end = offset_to_location(&code, &[source.1, source.2]);
- if opts.trace_format == TraceFormat::Custom {
- let source_fragment: String = code
- .chars()
- .skip(start_end[0].line_start_offset)
- .take(start_end[1].line_end_offset - start_end[0].line_start_offset)
- .collect();
- let snippet = Snippet {
- opt: FormatOptions {
- color: true,
- ..Default::default()
- },
- title: Some(Annotation {
- label: Some(&item.1),
- id: None,
- annotation_type: AnnotationType::Error,
- }),
- footer: vec![],
- slices: vec![Slice {
- source: &source_fragment,
- line_start: start_end[0].line,
- origin: Some(&source.0.to_str().unwrap()),
- fold: false,
- annotations: vec![SourceAnnotation {
- label: desc,
- annotation_type: AnnotationType::Error,
- range: (
- source.1 - start_end[0].line_start_offset,
- source.2 - start_end[0].line_start_offset,
- ),
- }],
- }],
- };
-
- let dl = DisplayList::from(snippet);
- println!("{}", dl);
- } else {
- print_jsonnet_pair(
- source.0.to_str().unwrap(),
- &start_end[0],
- &start_end[1],
- opts.trace_format == TraceFormat::GoJsonnet,
- );
- }
- }
-}
-
-fn print_jsonnet_pair(file: &str, start: &CodeLocation, end: &CodeLocation, is_go: bool) {
- if is_go {
- print!(" ");
- } else {
- print!(" ");
- }
- print!("{}:", file);
- if start.line == end.line {
- // IDK why, but this is the behavior original jsonnet cpp impl shows
- if start.column == end.column || !is_go && start.column + 1 == end.column {
- println!("{}:{}", start.line, end.column)
- } else {
- println!("{}:{}-{}", start.line, start.column, end.column);
- }
- } else {
- println!(
- "({}:{})-({}:{})",
- start.line, end.column, start.line, end.column
- );
- }
-}