yerba 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +492 -15
- data/ext/yerba/extconf.rb +87 -30
- data/ext/yerba/include/yerba.h +168 -0
- data/ext/yerba/yerba.c +752 -0
- data/lib/yerba/collection.rb +31 -0
- data/lib/yerba/document.rb +59 -0
- data/lib/yerba/formatting.rb +18 -0
- data/lib/yerba/location.rb +5 -0
- data/lib/yerba/map.rb +166 -0
- data/lib/yerba/scalar.rb +85 -0
- data/lib/yerba/sequence.rb +182 -0
- data/lib/yerba/version.rb +1 -1
- data/lib/yerba.rb +30 -4
- data/rust/Cargo.lock +378 -2
- data/rust/Cargo.toml +5 -1
- data/rust/build.rs +11 -0
- data/rust/cbindgen.toml +27 -0
- data/rust/src/commands/apply.rs +5 -0
- data/rust/src/commands/blank_lines.rs +58 -0
- data/rust/src/commands/check.rs +5 -0
- data/rust/src/commands/delete.rs +35 -0
- data/rust/src/commands/get.rs +194 -0
- data/rust/src/commands/init.rs +89 -0
- data/rust/src/commands/insert.rs +106 -0
- data/rust/src/commands/mate.rs +55 -0
- data/rust/src/commands/mod.rs +349 -0
- data/rust/src/commands/move_item.rs +54 -0
- data/rust/src/commands/move_key.rs +87 -0
- data/rust/src/commands/quote_style.rs +62 -0
- data/rust/src/commands/remove.rs +35 -0
- data/rust/src/commands/rename.rs +37 -0
- data/rust/src/commands/set.rs +59 -0
- data/rust/src/commands/sort.rs +52 -0
- data/rust/src/commands/sort_keys.rs +62 -0
- data/rust/src/commands/version.rs +8 -0
- data/rust/src/document.rs +764 -333
- data/rust/src/error.rs +0 -5
- data/rust/src/ffi.rs +991 -0
- data/rust/src/json.rs +49 -90
- data/rust/src/lib.rs +9 -2
- data/rust/src/main.rs +55 -843
- data/rust/src/selector.rs +241 -0
- data/rust/src/syntax.rs +97 -21
- data/rust/src/yaml_writer.rs +89 -0
- data/rust/src/yerbafile.rs +11 -126
- data/yerba.gemspec +4 -0
- metadata +33 -1
data/rust/src/yerbafile.rs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
use rayon::prelude::*;
|
|
2
2
|
use serde::Deserialize;
|
|
3
|
-
use std::collections::HashMap;
|
|
4
3
|
use std::fs;
|
|
5
4
|
use std::path::{Path, PathBuf};
|
|
6
5
|
|
|
@@ -22,7 +21,6 @@ pub struct Rule {
|
|
|
22
21
|
|
|
23
22
|
#[derive(Debug, Clone)]
|
|
24
23
|
pub enum PipelineStep {
|
|
25
|
-
Get(GetConfig),
|
|
26
24
|
SortKeys(SortKeysConfig),
|
|
27
25
|
QuoteStyle(QuoteStyleConfig),
|
|
28
26
|
Set(SetConfig),
|
|
@@ -51,21 +49,6 @@ pub struct BlankLinesConfig {
|
|
|
51
49
|
pub count: usize,
|
|
52
50
|
}
|
|
53
51
|
|
|
54
|
-
#[derive(Debug, Clone, Deserialize)]
|
|
55
|
-
pub struct GetConfig {
|
|
56
|
-
pub path: String,
|
|
57
|
-
#[serde(rename = "as")]
|
|
58
|
-
pub as_name: String,
|
|
59
|
-
#[serde(default)]
|
|
60
|
-
pub file: Option<String>,
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
#[derive(Debug, Clone)]
|
|
64
|
-
pub enum Variable {
|
|
65
|
-
Single(String),
|
|
66
|
-
List(Vec<String>),
|
|
67
|
-
}
|
|
68
|
-
|
|
69
52
|
#[derive(Debug, Clone, Deserialize)]
|
|
70
53
|
pub struct RenameConfig {
|
|
71
54
|
pub from: String,
|
|
@@ -89,11 +72,6 @@ impl<'de> Deserialize<'de> for PipelineStep {
|
|
|
89
72
|
{
|
|
90
73
|
let mapping = serde_yaml::Mapping::deserialize(deserializer)?;
|
|
91
74
|
|
|
92
|
-
if let Some(value) = mapping.get(serde_yaml::Value::String("get".to_string())) {
|
|
93
|
-
let config: GetConfig = serde_yaml::from_value(value.clone()).map_err(serde::de::Error::custom)?;
|
|
94
|
-
return Ok(PipelineStep::Get(config));
|
|
95
|
-
}
|
|
96
|
-
|
|
97
75
|
if let Some(value) = mapping.get(serde_yaml::Value::String("sort_keys".to_string())) {
|
|
98
76
|
let config: SortKeysConfig = serde_yaml::from_value(value.clone()).map_err(serde::de::Error::custom)?;
|
|
99
77
|
return Ok(PipelineStep::SortKeys(config));
|
|
@@ -140,7 +118,7 @@ impl<'de> Deserialize<'de> for PipelineStep {
|
|
|
140
118
|
}
|
|
141
119
|
|
|
142
120
|
Err(serde::de::Error::custom(
|
|
143
|
-
"unknown pipeline step: expected
|
|
121
|
+
"unknown pipeline step: expected sort_keys, quote_style, set, insert, delete, rename, remove, blank_lines, or sort",
|
|
144
122
|
))
|
|
145
123
|
}
|
|
146
124
|
}
|
|
@@ -338,10 +316,9 @@ impl Yerbafile {
|
|
|
338
316
|
|
|
339
317
|
let original = document.to_string();
|
|
340
318
|
let base_path = rule.path.as_deref();
|
|
341
|
-
let mut variables: HashMap<String, Variable> = HashMap::new();
|
|
342
319
|
|
|
343
320
|
for step in &rule.pipeline {
|
|
344
|
-
if let Err(error) = execute_step(&mut document, step, base_path
|
|
321
|
+
if let Err(error) = execute_step(&mut document, step, base_path) {
|
|
345
322
|
return RuleResult {
|
|
346
323
|
file: file.to_string(),
|
|
347
324
|
changed: false,
|
|
@@ -371,46 +348,8 @@ impl Yerbafile {
|
|
|
371
348
|
}
|
|
372
349
|
}
|
|
373
350
|
|
|
374
|
-
fn execute_step(
|
|
375
|
-
document: &mut Document,
|
|
376
|
-
step: &PipelineStep,
|
|
377
|
-
base_path: Option<&str>,
|
|
378
|
-
variables: &mut HashMap<String, Variable>,
|
|
379
|
-
) -> Result<(), YerbaError> {
|
|
351
|
+
fn execute_step(document: &mut Document, step: &PipelineStep, base_path: Option<&str>) -> Result<(), YerbaError> {
|
|
380
352
|
match step {
|
|
381
|
-
PipelineStep::Get(config) => {
|
|
382
|
-
let full_path = resolve_step_path(base_path, Some(&config.path));
|
|
383
|
-
|
|
384
|
-
if let Some(file_pattern) = &config.file {
|
|
385
|
-
let mut all_values = Vec::new();
|
|
386
|
-
|
|
387
|
-
let files =
|
|
388
|
-
glob::glob(file_pattern).map_err(|error| YerbaError::ParseError(format!("invalid glob: {}", error)))?;
|
|
389
|
-
|
|
390
|
-
for entry in files.flatten() {
|
|
391
|
-
let external_document = Document::parse_file(&entry)?;
|
|
392
|
-
all_values.extend(external_document.get_all(&config.path));
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
if all_values.len() == 1 && !config.path.contains('[') {
|
|
396
|
-
variables.insert(config.as_name.clone(), Variable::Single(all_values.remove(0)));
|
|
397
|
-
} else {
|
|
398
|
-
variables.insert(config.as_name.clone(), Variable::List(all_values));
|
|
399
|
-
}
|
|
400
|
-
} else if config.path.contains('[') {
|
|
401
|
-
let values = document.get_all(&full_path);
|
|
402
|
-
|
|
403
|
-
variables.insert(config.as_name.clone(), Variable::List(values));
|
|
404
|
-
} else {
|
|
405
|
-
let value = document
|
|
406
|
-
.get(&full_path)
|
|
407
|
-
.ok_or_else(|| YerbaError::PathNotFound(full_path.clone()))?;
|
|
408
|
-
variables.insert(config.as_name.clone(), Variable::Single(value));
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
Ok(())
|
|
412
|
-
}
|
|
413
|
-
|
|
414
353
|
PipelineStep::QuoteStyle(config) => {
|
|
415
354
|
let dot_path = config.path.as_deref();
|
|
416
355
|
|
|
@@ -436,44 +375,39 @@ fn execute_step(
|
|
|
436
375
|
|
|
437
376
|
PipelineStep::Set(config) => {
|
|
438
377
|
let full_path = resolve_step_path(base_path, Some(&config.path));
|
|
439
|
-
let resolved_value = resolve_template(&config.value, document, base_path, variables)?;
|
|
440
378
|
|
|
441
379
|
if let Some(condition) = &config.condition {
|
|
442
|
-
let resolved_condition = resolve_template(condition, document, base_path, variables)?;
|
|
443
380
|
let parent_path = full_path.rsplit_once('.').map(|(parent, _)| parent).unwrap_or("");
|
|
444
381
|
|
|
445
|
-
if !document.evaluate_condition(parent_path,
|
|
382
|
+
if !document.evaluate_condition(parent_path, condition) {
|
|
446
383
|
return Ok(());
|
|
447
384
|
}
|
|
448
385
|
}
|
|
449
386
|
|
|
450
|
-
document.set(&full_path, &
|
|
387
|
+
document.set(&full_path, &config.value)
|
|
451
388
|
}
|
|
452
389
|
|
|
453
390
|
PipelineStep::Insert(config) => {
|
|
454
391
|
let full_path = resolve_step_path(base_path, Some(&config.path));
|
|
455
|
-
let resolved_value = resolve_template(&config.value, document, base_path, variables)?;
|
|
456
392
|
|
|
457
393
|
if let Some(condition) = &config.condition {
|
|
458
|
-
let resolved_condition = resolve_template(condition, document, base_path, variables)?;
|
|
459
394
|
let parent_path = full_path.rsplit_once('.').map(|(parent, _)| parent).unwrap_or("");
|
|
460
395
|
|
|
461
|
-
if !document.evaluate_condition(parent_path,
|
|
396
|
+
if !document.evaluate_condition(parent_path, condition) {
|
|
462
397
|
return Ok(());
|
|
463
398
|
}
|
|
464
399
|
}
|
|
465
400
|
|
|
466
|
-
document.insert_into(&full_path, &
|
|
401
|
+
document.insert_into(&full_path, &config.value, crate::InsertPosition::Last)
|
|
467
402
|
}
|
|
468
403
|
|
|
469
404
|
PipelineStep::Delete(config) => {
|
|
470
405
|
let full_path = resolve_step_path(base_path, Some(&config.path));
|
|
471
406
|
|
|
472
407
|
if let Some(condition) = &config.condition {
|
|
473
|
-
let resolved_condition = resolve_template(condition, document, base_path, variables)?;
|
|
474
408
|
let parent_path = full_path.rsplit_once('.').map(|(parent, _)| parent).unwrap_or("");
|
|
475
409
|
|
|
476
|
-
if !document.evaluate_condition(parent_path,
|
|
410
|
+
if !document.evaluate_condition(parent_path, condition) {
|
|
477
411
|
return Ok(());
|
|
478
412
|
}
|
|
479
413
|
}
|
|
@@ -485,10 +419,9 @@ fn execute_step(
|
|
|
485
419
|
let full_path = resolve_step_path(base_path, Some(&config.from));
|
|
486
420
|
|
|
487
421
|
if let Some(condition) = &config.condition {
|
|
488
|
-
let resolved_condition = resolve_template(condition, document, base_path, variables)?;
|
|
489
422
|
let parent_path = full_path.rsplit_once('.').map(|(parent, _)| parent).unwrap_or("");
|
|
490
423
|
|
|
491
|
-
if !document.evaluate_condition(parent_path,
|
|
424
|
+
if !document.evaluate_condition(parent_path, condition) {
|
|
492
425
|
return Ok(());
|
|
493
426
|
}
|
|
494
427
|
}
|
|
@@ -498,18 +431,16 @@ fn execute_step(
|
|
|
498
431
|
|
|
499
432
|
PipelineStep::Remove(config) => {
|
|
500
433
|
let full_path = resolve_step_path(base_path, Some(&config.path));
|
|
501
|
-
let resolved_value = resolve_template(&config.value, document, base_path, variables)?;
|
|
502
434
|
|
|
503
435
|
if let Some(condition) = &config.condition {
|
|
504
|
-
let resolved_condition = resolve_template(condition, document, base_path, variables)?;
|
|
505
436
|
let parent_path = full_path.rsplit_once('.').map(|(parent, _)| parent).unwrap_or("");
|
|
506
437
|
|
|
507
|
-
if !document.evaluate_condition(parent_path,
|
|
438
|
+
if !document.evaluate_condition(parent_path, condition) {
|
|
508
439
|
return Ok(());
|
|
509
440
|
}
|
|
510
441
|
}
|
|
511
442
|
|
|
512
|
-
document.remove(&full_path, &
|
|
443
|
+
document.remove(&full_path, &config.value)
|
|
513
444
|
}
|
|
514
445
|
|
|
515
446
|
PipelineStep::BlankLines(config) => {
|
|
@@ -531,52 +462,6 @@ fn execute_step(
|
|
|
531
462
|
}
|
|
532
463
|
}
|
|
533
464
|
|
|
534
|
-
pub fn resolve_template(
|
|
535
|
-
template: &str,
|
|
536
|
-
document: &Document,
|
|
537
|
-
base_path: Option<&str>,
|
|
538
|
-
variables: &HashMap<String, Variable>,
|
|
539
|
-
) -> Result<String, YerbaError> {
|
|
540
|
-
if !template.contains("${") {
|
|
541
|
-
return Ok(template.to_string());
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
let mut result = String::new();
|
|
545
|
-
let mut rest = template;
|
|
546
|
-
|
|
547
|
-
while let Some(start) = rest.find("${") {
|
|
548
|
-
result.push_str(&rest[..start]);
|
|
549
|
-
|
|
550
|
-
let after_dollar = &rest[start + 2..];
|
|
551
|
-
|
|
552
|
-
let end = after_dollar
|
|
553
|
-
.find('}')
|
|
554
|
-
.ok_or_else(|| YerbaError::ParseError("unclosed ${ in template".to_string()))?;
|
|
555
|
-
|
|
556
|
-
let reference = &after_dollar[..end];
|
|
557
|
-
|
|
558
|
-
let resolved = if let Some(variable) = variables.get(reference) {
|
|
559
|
-
match variable {
|
|
560
|
-
Variable::Single(value) => value.clone(),
|
|
561
|
-
Variable::List(values) => values.join(", "),
|
|
562
|
-
}
|
|
563
|
-
} else {
|
|
564
|
-
let full_path = resolve_step_path(base_path, Some(reference));
|
|
565
|
-
|
|
566
|
-
document
|
|
567
|
-
.get(&full_path)
|
|
568
|
-
.ok_or_else(|| YerbaError::ReferenceNotFound(reference.to_string()))?
|
|
569
|
-
};
|
|
570
|
-
|
|
571
|
-
result.push_str(&resolved);
|
|
572
|
-
rest = &after_dollar[end + 1..];
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
result.push_str(rest);
|
|
576
|
-
|
|
577
|
-
Ok(result)
|
|
578
|
-
}
|
|
579
|
-
|
|
580
465
|
fn resolve_step_path(base_path: Option<&str>, step_path: Option<&str>) -> String {
|
|
581
466
|
let base = base_path.unwrap_or("");
|
|
582
467
|
let step = step_path.unwrap_or("");
|
data/yerba.gemspec
CHANGED
|
@@ -28,6 +28,10 @@ Gem::Specification.new do |spec|
|
|
|
28
28
|
"sig/**/*.rbs",
|
|
29
29
|
"exe/yerba",
|
|
30
30
|
"ext/yerba/extconf.rb",
|
|
31
|
+
"ext/yerba/yerba.c",
|
|
32
|
+
"ext/yerba/include/**/*.h",
|
|
33
|
+
"rust/build.rs",
|
|
34
|
+
"rust/cbindgen.toml",
|
|
31
35
|
"rust/Cargo.toml",
|
|
32
36
|
"rust/Cargo.lock",
|
|
33
37
|
"rust/src/**/*.rs",
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: yerba
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Marco Roth
|
|
@@ -23,18 +23,50 @@ files:
|
|
|
23
23
|
- README.md
|
|
24
24
|
- exe/yerba
|
|
25
25
|
- ext/yerba/extconf.rb
|
|
26
|
+
- ext/yerba/include/yerba.h
|
|
27
|
+
- ext/yerba/yerba.c
|
|
26
28
|
- lib/yerba.rb
|
|
29
|
+
- lib/yerba/collection.rb
|
|
30
|
+
- lib/yerba/document.rb
|
|
31
|
+
- lib/yerba/formatting.rb
|
|
32
|
+
- lib/yerba/location.rb
|
|
33
|
+
- lib/yerba/map.rb
|
|
34
|
+
- lib/yerba/scalar.rb
|
|
35
|
+
- lib/yerba/sequence.rb
|
|
27
36
|
- lib/yerba/version.rb
|
|
28
37
|
- rust/Cargo.lock
|
|
29
38
|
- rust/Cargo.toml
|
|
39
|
+
- rust/build.rs
|
|
40
|
+
- rust/cbindgen.toml
|
|
30
41
|
- rust/rustfmt.toml
|
|
42
|
+
- rust/src/commands/apply.rs
|
|
43
|
+
- rust/src/commands/blank_lines.rs
|
|
44
|
+
- rust/src/commands/check.rs
|
|
45
|
+
- rust/src/commands/delete.rs
|
|
46
|
+
- rust/src/commands/get.rs
|
|
47
|
+
- rust/src/commands/init.rs
|
|
48
|
+
- rust/src/commands/insert.rs
|
|
49
|
+
- rust/src/commands/mate.rs
|
|
50
|
+
- rust/src/commands/mod.rs
|
|
51
|
+
- rust/src/commands/move_item.rs
|
|
52
|
+
- rust/src/commands/move_key.rs
|
|
53
|
+
- rust/src/commands/quote_style.rs
|
|
54
|
+
- rust/src/commands/remove.rs
|
|
55
|
+
- rust/src/commands/rename.rs
|
|
56
|
+
- rust/src/commands/set.rs
|
|
57
|
+
- rust/src/commands/sort.rs
|
|
58
|
+
- rust/src/commands/sort_keys.rs
|
|
59
|
+
- rust/src/commands/version.rs
|
|
31
60
|
- rust/src/document.rs
|
|
32
61
|
- rust/src/error.rs
|
|
62
|
+
- rust/src/ffi.rs
|
|
33
63
|
- rust/src/json.rs
|
|
34
64
|
- rust/src/lib.rs
|
|
35
65
|
- rust/src/main.rs
|
|
36
66
|
- rust/src/quote_style.rs
|
|
67
|
+
- rust/src/selector.rs
|
|
37
68
|
- rust/src/syntax.rs
|
|
69
|
+
- rust/src/yaml_writer.rs
|
|
38
70
|
- rust/src/yerbafile.rs
|
|
39
71
|
- sig/yerba.rbs
|
|
40
72
|
- yerba.gemspec
|