yerba 0.5.0-x86_64-linux-gnu → 0.5.1-x86_64-linux-gnu
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 +1 -1
- data/exe/x86_64-linux-gnu/yerba +0 -0
- data/lib/yerba/3.2/yerba.so +0 -0
- data/lib/yerba/3.3/yerba.so +0 -0
- data/lib/yerba/3.4/yerba.so +0 -0
- data/lib/yerba/4.0/yerba.so +0 -0
- data/lib/yerba/version.rb +1 -1
- data/rust/Cargo.lock +21 -21
- data/rust/Cargo.toml +2 -2
- data/rust/src/commands/get.rs +1 -1
- data/rust/src/commands/selectors.rs +4 -4
- data/rust/src/commands/sort.rs +1 -1
- data/rust/src/document/condition.rs +2 -2
- data/rust/src/document/delete.rs +52 -8
- data/rust/src/document/get.rs +8 -8
- data/rust/src/document/insert.rs +3 -3
- data/rust/src/document/mod.rs +22 -22
- data/rust/src/document/sort.rs +2 -2
- data/rust/src/json.rs +16 -16
- data/rust/src/lib.rs +2 -2
- data/rust/src/selector.rs +16 -0
- data/rust/src/yerbafile.rs +27 -70
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 19b6906bd8f2db29860e1dfe1cb78a80d26b8cfa30ce01a9b76de7be22568a0c
|
|
4
|
+
data.tar.gz: 618eea79126aa8456337d0c3a905dd0d782510457b16bb368fa70e1de4177df3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a49b141053cd6cc9e6803a914a9d4cd443e376b59319e5484b2c9bf139b245c7bf7be888739d179e5fb14dcd7931f95e878d1430ebd2694c25354d08fe5625ed
|
|
7
|
+
data.tar.gz: 959d1cd010d792c74b4ad0d45c815e30b3b76fd5becb7d78a1c64736ded4e41b08c8e2049f7e79912c7675f2c479656f868180b0567388a9c1864a41639f8f18
|
data/README.md
CHANGED
data/exe/x86_64-linux-gnu/yerba
CHANGED
|
Binary file
|
data/lib/yerba/3.2/yerba.so
CHANGED
|
Binary file
|
data/lib/yerba/3.3/yerba.so
CHANGED
|
Binary file
|
data/lib/yerba/3.4/yerba.so
CHANGED
|
Binary file
|
data/lib/yerba/4.0/yerba.so
CHANGED
|
Binary file
|
data/lib/yerba/version.rb
CHANGED
data/rust/Cargo.lock
CHANGED
|
@@ -739,6 +739,12 @@ version = "0.2.186"
|
|
|
739
739
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
740
740
|
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
|
|
741
741
|
|
|
742
|
+
[[package]]
|
|
743
|
+
name = "libyaml-rs"
|
|
744
|
+
version = "0.3.0"
|
|
745
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
746
|
+
checksum = "2e126dda6f34391ab7b444f9922055facc83c07a910da3eb16f1e4d9c45dc777"
|
|
747
|
+
|
|
742
748
|
[[package]]
|
|
743
749
|
name = "linux-raw-sys"
|
|
744
750
|
version = "0.12.1"
|
|
@@ -1198,19 +1204,6 @@ dependencies = [
|
|
|
1198
1204
|
"serde",
|
|
1199
1205
|
]
|
|
1200
1206
|
|
|
1201
|
-
[[package]]
|
|
1202
|
-
name = "serde_yaml"
|
|
1203
|
-
version = "0.9.34+deprecated"
|
|
1204
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1205
|
-
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
|
|
1206
|
-
dependencies = [
|
|
1207
|
-
"indexmap",
|
|
1208
|
-
"itoa",
|
|
1209
|
-
"ryu",
|
|
1210
|
-
"serde",
|
|
1211
|
-
"unsafe-libyaml",
|
|
1212
|
-
]
|
|
1213
|
-
|
|
1214
1207
|
[[package]]
|
|
1215
1208
|
name = "slab"
|
|
1216
1209
|
version = "0.4.12"
|
|
@@ -1441,12 +1434,6 @@ version = "0.2.6"
|
|
|
1441
1434
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1442
1435
|
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
|
1443
1436
|
|
|
1444
|
-
[[package]]
|
|
1445
|
-
name = "unsafe-libyaml"
|
|
1446
|
-
version = "0.2.11"
|
|
1447
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1448
|
-
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
|
|
1449
|
-
|
|
1450
1437
|
[[package]]
|
|
1451
1438
|
name = "url"
|
|
1452
1439
|
version = "2.5.8"
|
|
@@ -1770,9 +1757,22 @@ dependencies = [
|
|
|
1770
1757
|
"winnow",
|
|
1771
1758
|
]
|
|
1772
1759
|
|
|
1760
|
+
[[package]]
|
|
1761
|
+
name = "yaml_serde"
|
|
1762
|
+
version = "0.10.4"
|
|
1763
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1764
|
+
checksum = "08c7c1b1a6a7c8a6b2741a6c21a4f8918e51899b111cfa08d1288202656e3975"
|
|
1765
|
+
dependencies = [
|
|
1766
|
+
"indexmap",
|
|
1767
|
+
"itoa",
|
|
1768
|
+
"libyaml-rs",
|
|
1769
|
+
"ryu",
|
|
1770
|
+
"serde",
|
|
1771
|
+
]
|
|
1772
|
+
|
|
1773
1773
|
[[package]]
|
|
1774
1774
|
name = "yerba"
|
|
1775
|
-
version = "0.5.
|
|
1775
|
+
version = "0.5.1"
|
|
1776
1776
|
dependencies = [
|
|
1777
1777
|
"cbindgen",
|
|
1778
1778
|
"clap",
|
|
@@ -1783,9 +1783,9 @@ dependencies = [
|
|
|
1783
1783
|
"rowan",
|
|
1784
1784
|
"serde",
|
|
1785
1785
|
"serde_json",
|
|
1786
|
-
"serde_yaml",
|
|
1787
1786
|
"tempfile",
|
|
1788
1787
|
"yaml_parser",
|
|
1788
|
+
"yaml_serde",
|
|
1789
1789
|
]
|
|
1790
1790
|
|
|
1791
1791
|
[[package]]
|
data/rust/Cargo.toml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "yerba"
|
|
3
|
-
version = "0.5.
|
|
3
|
+
version = "0.5.1"
|
|
4
4
|
edition = "2021"
|
|
5
5
|
authors = ["Marco Roth <marco.roth@intergga.ch>"]
|
|
6
6
|
description = "YAML Editing and Refactoring with Better Accuracy"
|
|
@@ -24,7 +24,7 @@ yaml_parser = "0.3"
|
|
|
24
24
|
rowan = "0.16"
|
|
25
25
|
glob = "0.3"
|
|
26
26
|
serde = { version = "1", features = ["derive"] }
|
|
27
|
-
|
|
27
|
+
yaml_serde = "0.10"
|
|
28
28
|
serde_json = { version = "1", features = ["preserve_order"] }
|
|
29
29
|
clap = { version = "4", features = ["derive"] }
|
|
30
30
|
indoc = "2"
|
data/rust/src/commands/get.rs
CHANGED
|
@@ -112,7 +112,7 @@ impl Args {
|
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
let (values, selectors, lines): (Vec<
|
|
115
|
+
let (values, selectors, lines): (Vec<yaml_serde::Value>, Vec<String>, Vec<usize>) = if select_fields.is_some() {
|
|
116
116
|
if let Some(condition) = &normalized_condition {
|
|
117
117
|
let triples = document.filter_with_selectors(&search_path_string, condition);
|
|
118
118
|
let (values, rest): (Vec<_>, Vec<_>) = triples.into_iter().map(|(v, s, l)| (v, (s, l))).unzip();
|
|
@@ -116,11 +116,11 @@ impl Args {
|
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
fn collect_selectors(value: &
|
|
119
|
+
fn collect_selectors(value: &yaml_serde::Value, prefix: &str, selectors: &mut BTreeMap<String, SelectorInfo>, counter: &mut usize) {
|
|
120
120
|
match value {
|
|
121
|
-
|
|
121
|
+
yaml_serde::Value::Mapping(map) => {
|
|
122
122
|
for (key, child) in map {
|
|
123
|
-
if let
|
|
123
|
+
if let yaml_serde::Value::String(key_string) = key {
|
|
124
124
|
let selector = if prefix.is_empty() {
|
|
125
125
|
key_string.clone()
|
|
126
126
|
} else {
|
|
@@ -138,7 +138,7 @@ fn collect_selectors(value: &serde_yaml::Value, prefix: &str, selectors: &mut BT
|
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
|
|
141
|
+
yaml_serde::Value::Sequence(sequence) => {
|
|
142
142
|
let bracket_prefix = format!("{}[]", prefix);
|
|
143
143
|
|
|
144
144
|
let entry = selectors.entry(bracket_prefix.clone()).or_default();
|
data/rust/src/commands/sort.rs
CHANGED
|
@@ -329,7 +329,7 @@ impl Args {
|
|
|
329
329
|
.map(|item| {
|
|
330
330
|
if by_is_scalar {
|
|
331
331
|
match item {
|
|
332
|
-
|
|
332
|
+
yaml_serde::Value::String(string) => string.clone(),
|
|
333
333
|
_ => serde_json::to_string(&yerba::json::yaml_to_json(item)).unwrap_or_default(),
|
|
334
334
|
}
|
|
335
335
|
} else {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
use super::*;
|
|
2
2
|
|
|
3
3
|
impl Document {
|
|
4
|
-
pub fn filter(&self, dot_path: &str, condition: &str) -> Vec<
|
|
4
|
+
pub fn filter(&self, dot_path: &str, condition: &str) -> Vec<yaml_serde::Value> {
|
|
5
5
|
self
|
|
6
6
|
.navigate_all_compact(dot_path)
|
|
7
7
|
.iter()
|
|
@@ -10,7 +10,7 @@ impl Document {
|
|
|
10
10
|
.collect()
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
pub fn filter_with_selectors(&self, dot_path: &str, condition: &str) -> Vec<(
|
|
13
|
+
pub fn filter_with_selectors(&self, dot_path: &str, condition: &str) -> Vec<(yaml_serde::Value, String, usize)> {
|
|
14
14
|
let source = self.root.text().to_string();
|
|
15
15
|
|
|
16
16
|
self
|
data/rust/src/document/delete.rs
CHANGED
|
@@ -35,17 +35,61 @@ impl Document {
|
|
|
35
35
|
pub fn delete(&mut self, dot_path: &str) -> Result<(), YerbaError> {
|
|
36
36
|
Self::validate_path(dot_path)?;
|
|
37
37
|
|
|
38
|
-
let
|
|
39
|
-
let
|
|
38
|
+
let selector = crate::selector::Selector::parse(dot_path);
|
|
39
|
+
let segments = selector.segments();
|
|
40
|
+
let last_segment = segments.last().ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
41
|
+
let parent_path = selector.parent_path();
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
match last_segment {
|
|
44
|
+
crate::selector::SelectorSegment::Key(last_key) => {
|
|
45
|
+
let has_wildcard = selector.has_wildcard() || selector.has_brackets();
|
|
46
|
+
let parent_nodes = self.navigate_all_compact(&parent_path);
|
|
47
|
+
|
|
48
|
+
if parent_nodes.is_empty() {
|
|
49
|
+
if has_wildcard {
|
|
50
|
+
return Ok(());
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return Err(YerbaError::SelectorNotFound(dot_path.to_string()));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if parent_nodes.len() == 1 && !has_wildcard {
|
|
57
|
+
let map = parent_nodes[0]
|
|
58
|
+
.descendants()
|
|
59
|
+
.find_map(BlockMap::cast)
|
|
60
|
+
.ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
61
|
+
|
|
62
|
+
let entry = find_entry_by_key(&map, last_key).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
63
|
+
|
|
64
|
+
return self.remove_node(entry.syntax());
|
|
65
|
+
}
|
|
45
66
|
|
|
46
|
-
|
|
67
|
+
let mut ranges: Vec<TextRange> = Vec::new();
|
|
47
68
|
|
|
48
|
-
|
|
69
|
+
for parent_node in &parent_nodes {
|
|
70
|
+
if let Some(map) = parent_node.descendants().find_map(BlockMap::cast) {
|
|
71
|
+
if let Some(entry) = find_entry_by_key(&map, last_key) {
|
|
72
|
+
ranges.push(removal_range(entry.syntax()));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if ranges.is_empty() {
|
|
78
|
+
return Ok(());
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
ranges.reverse();
|
|
82
|
+
|
|
83
|
+
for range in ranges {
|
|
84
|
+
self.apply_edit(range, "")?;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
Ok(())
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
crate::selector::SelectorSegment::Index(index) => self.remove_at(&parent_path, *index),
|
|
91
|
+
crate::selector::SelectorSegment::AllItems => Err(YerbaError::SelectorNotFound(dot_path.to_string())),
|
|
92
|
+
}
|
|
49
93
|
}
|
|
50
94
|
|
|
51
95
|
pub fn remove(&mut self, dot_path: &str, value: &str) -> Result<(), YerbaError> {
|
data/rust/src/document/get.rs
CHANGED
|
@@ -278,7 +278,7 @@ impl Document {
|
|
|
278
278
|
.collect()
|
|
279
279
|
}
|
|
280
280
|
|
|
281
|
-
pub fn get_value(&self, dot_path: &str) -> Option<
|
|
281
|
+
pub fn get_value(&self, dot_path: &str) -> Option<yaml_serde::Value> {
|
|
282
282
|
if dot_path.is_empty() {
|
|
283
283
|
return Some(node_to_yaml_value(&self.root));
|
|
284
284
|
}
|
|
@@ -292,15 +292,15 @@ impl Document {
|
|
|
292
292
|
return None;
|
|
293
293
|
}
|
|
294
294
|
|
|
295
|
-
let values: Vec<
|
|
295
|
+
let values: Vec<yaml_serde::Value> = padded
|
|
296
296
|
.iter()
|
|
297
297
|
.map(|maybe_node| match maybe_node {
|
|
298
298
|
Some(node) => node_to_yaml_value(node),
|
|
299
|
-
None =>
|
|
299
|
+
None => yaml_serde::Value::Null,
|
|
300
300
|
})
|
|
301
301
|
.collect();
|
|
302
302
|
|
|
303
|
-
Some(
|
|
303
|
+
Some(yaml_serde::Value::Sequence(values))
|
|
304
304
|
} else {
|
|
305
305
|
let nodes = self.navigate_all_compact(dot_path);
|
|
306
306
|
|
|
@@ -312,13 +312,13 @@ impl Document {
|
|
|
312
312
|
return Some(node_to_yaml_value(&nodes[0]));
|
|
313
313
|
}
|
|
314
314
|
|
|
315
|
-
let values: Vec<
|
|
315
|
+
let values: Vec<yaml_serde::Value> = nodes.iter().map(node_to_yaml_value).collect();
|
|
316
316
|
|
|
317
|
-
Some(
|
|
317
|
+
Some(yaml_serde::Value::Sequence(values))
|
|
318
318
|
}
|
|
319
319
|
}
|
|
320
320
|
|
|
321
|
-
pub fn get_values(&self, dot_path: &str) -> Vec<
|
|
321
|
+
pub fn get_values(&self, dot_path: &str) -> Vec<yaml_serde::Value> {
|
|
322
322
|
let parsed = crate::selector::Selector::parse(dot_path);
|
|
323
323
|
|
|
324
324
|
if parsed.has_wildcard() {
|
|
@@ -327,7 +327,7 @@ impl Document {
|
|
|
327
327
|
.iter()
|
|
328
328
|
.map(|maybe_node| match maybe_node {
|
|
329
329
|
Some(node) => node_to_yaml_value(node),
|
|
330
|
-
None =>
|
|
330
|
+
None => yaml_serde::Value::Null,
|
|
331
331
|
})
|
|
332
332
|
.collect()
|
|
333
333
|
} else {
|
data/rust/src/document/insert.rs
CHANGED
|
@@ -22,9 +22,9 @@ impl Document {
|
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
if let Some(
|
|
26
|
-
if let Some(
|
|
27
|
-
if let Some((
|
|
25
|
+
if let Some(yaml_serde::Value::Sequence(sequence)) = self.get_value(dot_path).as_ref() {
|
|
26
|
+
if let Some(yaml_serde::Value::Mapping(map)) = sequence.first() {
|
|
27
|
+
if let Some((yaml_serde::Value::String(key_name), _)) = map.iter().next() {
|
|
28
28
|
let deep_path = if dot_path.is_empty() {
|
|
29
29
|
format!("[].{}", key_name)
|
|
30
30
|
} else {
|
data/rust/src/document/mod.rs
CHANGED
|
@@ -445,11 +445,11 @@ pub(crate) fn compute_location(source: &str, start_offset: usize, end_offset: us
|
|
|
445
445
|
}
|
|
446
446
|
}
|
|
447
447
|
|
|
448
|
-
pub fn collect_selectors(value: &
|
|
448
|
+
pub fn collect_selectors(value: &yaml_serde::Value, prefix: &str, selectors: &mut Vec<String>) {
|
|
449
449
|
match value {
|
|
450
|
-
|
|
450
|
+
yaml_serde::Value::Mapping(map) => {
|
|
451
451
|
for (key, child) in map {
|
|
452
|
-
if let
|
|
452
|
+
if let yaml_serde::Value::String(key_string) = key {
|
|
453
453
|
let selector = if prefix.is_empty() {
|
|
454
454
|
key_string.clone()
|
|
455
455
|
} else {
|
|
@@ -462,7 +462,7 @@ pub fn collect_selectors(value: &serde_yaml::Value, prefix: &str, selectors: &mu
|
|
|
462
462
|
}
|
|
463
463
|
}
|
|
464
464
|
|
|
465
|
-
|
|
465
|
+
yaml_serde::Value::Sequence(sequence) => {
|
|
466
466
|
let bracket_prefix = format!("{}[]", prefix);
|
|
467
467
|
selectors.push(bracket_prefix.clone());
|
|
468
468
|
|
|
@@ -475,21 +475,21 @@ pub fn collect_selectors(value: &serde_yaml::Value, prefix: &str, selectors: &mu
|
|
|
475
475
|
}
|
|
476
476
|
}
|
|
477
477
|
|
|
478
|
-
pub(crate) fn node_to_yaml_value(node: &SyntaxNode) ->
|
|
478
|
+
pub(crate) fn node_to_yaml_value(node: &SyntaxNode) -> yaml_serde::Value {
|
|
479
479
|
if let Some(sequence) = node.descendants().find_map(BlockSeq::cast) {
|
|
480
480
|
let map_position = node.descendants().find_map(BlockMap::cast).map(|map| map.syntax().text_range().start());
|
|
481
481
|
|
|
482
482
|
let sequence_position = sequence.syntax().text_range().start();
|
|
483
483
|
|
|
484
484
|
if map_position.is_none() || sequence_position <= map_position.unwrap() {
|
|
485
|
-
let values: Vec<
|
|
485
|
+
let values: Vec<yaml_serde::Value> = sequence.entries().map(|entry| node_to_yaml_value(entry.syntax())).collect();
|
|
486
486
|
|
|
487
|
-
return
|
|
487
|
+
return yaml_serde::Value::Sequence(values);
|
|
488
488
|
}
|
|
489
489
|
}
|
|
490
490
|
|
|
491
491
|
if let Some(map) = node.descendants().find_map(BlockMap::cast) {
|
|
492
|
-
let mut mapping =
|
|
492
|
+
let mut mapping = yaml_serde::Mapping::new();
|
|
493
493
|
|
|
494
494
|
for entry in map.entries() {
|
|
495
495
|
let key = entry.key().and_then(|key_node| extract_scalar_text(key_node.syntax())).unwrap_or_default();
|
|
@@ -497,18 +497,18 @@ pub(crate) fn node_to_yaml_value(node: &SyntaxNode) -> serde_yaml::Value {
|
|
|
497
497
|
let value = entry
|
|
498
498
|
.value()
|
|
499
499
|
.map(|value_node| node_to_yaml_value(value_node.syntax()))
|
|
500
|
-
.unwrap_or(
|
|
500
|
+
.unwrap_or(yaml_serde::Value::Null);
|
|
501
501
|
|
|
502
|
-
mapping.insert(
|
|
502
|
+
mapping.insert(yaml_serde::Value::String(key), value);
|
|
503
503
|
}
|
|
504
504
|
|
|
505
|
-
return
|
|
505
|
+
return yaml_serde::Value::Mapping(mapping);
|
|
506
506
|
}
|
|
507
507
|
|
|
508
508
|
if let Some(sequence) = node.descendants().find_map(BlockSeq::cast) {
|
|
509
|
-
let values: Vec<
|
|
509
|
+
let values: Vec<yaml_serde::Value> = sequence.entries().map(|entry| node_to_yaml_value(entry.syntax())).collect();
|
|
510
510
|
|
|
511
|
-
return
|
|
511
|
+
return yaml_serde::Value::Sequence(values);
|
|
512
512
|
}
|
|
513
513
|
|
|
514
514
|
if let Some(block_scalar) = node.descendants().find(|child| child.kind() == SyntaxKind::BLOCK_SCALAR) {
|
|
@@ -521,35 +521,35 @@ pub(crate) fn node_to_yaml_value(node: &SyntaxNode) -> serde_yaml::Value {
|
|
|
521
521
|
|
|
522
522
|
let text = dedent_block_scalar(&text);
|
|
523
523
|
|
|
524
|
-
return
|
|
524
|
+
return yaml_serde::Value::String(text);
|
|
525
525
|
}
|
|
526
526
|
|
|
527
527
|
if let Some(scalar) = extract_scalar(node) {
|
|
528
528
|
use crate::syntax::{detect_yaml_type, is_yaml_truthy, YerbaValueType};
|
|
529
529
|
|
|
530
530
|
return match detect_yaml_type(&scalar) {
|
|
531
|
-
YerbaValueType::Null =>
|
|
532
|
-
YerbaValueType::Boolean =>
|
|
531
|
+
YerbaValueType::Null => yaml_serde::Value::Null,
|
|
532
|
+
YerbaValueType::Boolean => yaml_serde::Value::Bool(is_yaml_truthy(&scalar.text)),
|
|
533
533
|
|
|
534
534
|
YerbaValueType::Integer => scalar
|
|
535
535
|
.text
|
|
536
536
|
.parse::<i64>()
|
|
537
|
-
.map(|n|
|
|
538
|
-
.unwrap_or(
|
|
537
|
+
.map(|n| yaml_serde::Value::Number(yaml_serde::Number::from(n)))
|
|
538
|
+
.unwrap_or(yaml_serde::Value::String(scalar.text)),
|
|
539
539
|
|
|
540
540
|
YerbaValueType::Float => scalar
|
|
541
541
|
.text
|
|
542
542
|
.parse::<f64>()
|
|
543
|
-
.map(|n|
|
|
544
|
-
.unwrap_or(
|
|
543
|
+
.map(|n| yaml_serde::Value::Number(yaml_serde::Number::from(n)))
|
|
544
|
+
.unwrap_or(yaml_serde::Value::String(scalar.text)),
|
|
545
545
|
|
|
546
|
-
YerbaValueType::String =>
|
|
546
|
+
YerbaValueType::String => yaml_serde::Value::String(scalar.text),
|
|
547
547
|
};
|
|
548
548
|
}
|
|
549
549
|
|
|
550
550
|
let text = node.text().to_string();
|
|
551
551
|
|
|
552
|
-
|
|
552
|
+
yaml_serde::from_str(&text).unwrap_or(yaml_serde::Value::String(text))
|
|
553
553
|
}
|
|
554
554
|
|
|
555
555
|
pub(crate) fn parse_condition(condition: &str) -> Option<(String, &str, String)> {
|
data/rust/src/document/sort.rs
CHANGED
|
@@ -577,10 +577,10 @@ impl Document {
|
|
|
577
577
|
};
|
|
578
578
|
|
|
579
579
|
let labels: Vec<String> = match self.get_value(&items_selector) {
|
|
580
|
-
Some(
|
|
580
|
+
Some(yaml_serde::Value::Sequence(sequence)) => sequence
|
|
581
581
|
.iter()
|
|
582
582
|
.map(|value| match value {
|
|
583
|
-
|
|
583
|
+
yaml_serde::Value::String(string) => string.clone(),
|
|
584
584
|
_ => String::new(),
|
|
585
585
|
})
|
|
586
586
|
.collect(),
|
data/rust/src/json.rs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
use crate::selector::{Selector, SelectorSegment};
|
|
2
2
|
|
|
3
|
-
pub fn yaml_to_json(value: &
|
|
3
|
+
pub fn yaml_to_json(value: &yaml_serde::Value) -> serde_json::Value {
|
|
4
4
|
match value {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
yaml_serde::Value::Null => serde_json::Value::Null,
|
|
6
|
+
yaml_serde::Value::Bool(boolean) => serde_json::Value::Bool(*boolean),
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
yaml_serde::Value::Number(number) => {
|
|
9
9
|
if let Some(integer) = number.as_i64() {
|
|
10
10
|
serde_json::Value::Number(integer.into())
|
|
11
11
|
} else if let Some(float) = number.as_f64() {
|
|
@@ -15,16 +15,16 @@ pub fn yaml_to_json(value: &serde_yaml::Value) -> serde_json::Value {
|
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
yaml_serde::Value::String(string) => serde_json::Value::String(string.clone()),
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
yaml_serde::Value::Sequence(sequence) => serde_json::Value::Array(sequence.iter().map(yaml_to_json).collect()),
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
yaml_serde::Value::Mapping(mapping) => {
|
|
23
23
|
let mut map = serde_json::Map::new();
|
|
24
24
|
|
|
25
25
|
for (key, yaml_value) in mapping {
|
|
26
26
|
let json_key = match key {
|
|
27
|
-
|
|
27
|
+
yaml_serde::Value::String(string) => string.clone(),
|
|
28
28
|
_ => format!("{:?}", key),
|
|
29
29
|
};
|
|
30
30
|
|
|
@@ -34,19 +34,19 @@ pub fn yaml_to_json(value: &serde_yaml::Value) -> serde_json::Value {
|
|
|
34
34
|
serde_json::Value::Object(map)
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
yaml_serde::Value::Tagged(tagged) => yaml_to_json(&tagged.value),
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
pub fn resolve_select_field(value: &
|
|
41
|
+
pub fn resolve_select_field(value: &yaml_serde::Value, field: &str) -> serde_json::Value {
|
|
42
42
|
let parsed = Selector::parse(field);
|
|
43
43
|
let segments = parsed.segments();
|
|
44
44
|
|
|
45
45
|
if segments.len() == 1 {
|
|
46
46
|
if let SelectorSegment::Key(key) = &segments[0] {
|
|
47
|
-
if let
|
|
47
|
+
if let yaml_serde::Value::Mapping(map) = value {
|
|
48
48
|
for (map_key, yaml_value) in map {
|
|
49
|
-
if let
|
|
49
|
+
if let yaml_serde::Value::String(key_string) = map_key {
|
|
50
50
|
if key_string == key {
|
|
51
51
|
return yaml_to_json(yaml_value);
|
|
52
52
|
}
|
|
@@ -66,13 +66,13 @@ pub fn resolve_select_field(value: &serde_yaml::Value, field: &str) -> serde_jso
|
|
|
66
66
|
for current in ¤t_values {
|
|
67
67
|
match segment {
|
|
68
68
|
SelectorSegment::AllItems => {
|
|
69
|
-
if let
|
|
69
|
+
if let yaml_serde::Value::Sequence(sequence) = current {
|
|
70
70
|
next_values.extend(sequence.iter().cloned());
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
SelectorSegment::Index(index) => {
|
|
75
|
-
if let
|
|
75
|
+
if let yaml_serde::Value::Sequence(sequence) = current {
|
|
76
76
|
if let Some(item) = sequence.get(*index) {
|
|
77
77
|
next_values.push(item.clone());
|
|
78
78
|
}
|
|
@@ -80,9 +80,9 @@ pub fn resolve_select_field(value: &serde_yaml::Value, field: &str) -> serde_jso
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
SelectorSegment::Key(key) => {
|
|
83
|
-
if let
|
|
83
|
+
if let yaml_serde::Value::Mapping(map) = current {
|
|
84
84
|
for (map_key, yaml_value) in map {
|
|
85
|
-
if let
|
|
85
|
+
if let yaml_serde::Value::String(key_string) = map_key {
|
|
86
86
|
if key_string == key {
|
|
87
87
|
next_values.push(yaml_value.clone());
|
|
88
88
|
}
|
data/rust/src/lib.rs
CHANGED
|
@@ -88,10 +88,10 @@ pub fn glob_find(pattern: &str, selector: &str, condition: Option<&str>, select:
|
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
None => {
|
|
91
|
-
if let
|
|
91
|
+
if let yaml_serde::Value::Mapping(map) = value {
|
|
92
92
|
for (key, yaml_value) in map {
|
|
93
93
|
let json_key = match key {
|
|
94
|
-
|
|
94
|
+
yaml_serde::Value::String(string) => string.clone(),
|
|
95
95
|
_ => format!("{:?}", key),
|
|
96
96
|
};
|
|
97
97
|
|
data/rust/src/selector.rs
CHANGED
|
@@ -171,6 +171,22 @@ impl Selector {
|
|
|
171
171
|
|
|
172
172
|
result
|
|
173
173
|
}
|
|
174
|
+
|
|
175
|
+
pub fn parent_path(&self) -> String {
|
|
176
|
+
let segments = self.segments();
|
|
177
|
+
|
|
178
|
+
if segments.len() <= 1 {
|
|
179
|
+
return String::new();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
let parent_segments = &segments[..segments.len() - 1];
|
|
183
|
+
let parent = match self {
|
|
184
|
+
Selector::Relative(_) => Selector::Relative(parent_segments.to_vec()),
|
|
185
|
+
Selector::Absolute(_) => Selector::Absolute(parent_segments.to_vec()),
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
parent.to_selector_string()
|
|
189
|
+
}
|
|
174
190
|
}
|
|
175
191
|
|
|
176
192
|
fn parse_segments(input: &str) -> Vec<SelectorSegment> {
|
data/rust/src/yerbafile.rs
CHANGED
|
@@ -108,65 +108,65 @@ impl<'de> Deserialize<'de> for PipelineStep {
|
|
|
108
108
|
where
|
|
109
109
|
D: serde::Deserializer<'de>,
|
|
110
110
|
{
|
|
111
|
-
let mapping =
|
|
111
|
+
let mapping = yaml_serde::Mapping::deserialize(deserializer)?;
|
|
112
112
|
|
|
113
|
-
if let Some(value) = mapping.get(
|
|
114
|
-
let config: SortKeysConfig =
|
|
113
|
+
if let Some(value) = mapping.get(yaml_serde::Value::String("sort_keys".to_string())) {
|
|
114
|
+
let config: SortKeysConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
|
|
115
115
|
return Ok(PipelineStep::SortKeys(config));
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
if let Some(value) = mapping.get(
|
|
119
|
-
let config: QuoteStyleConfig =
|
|
118
|
+
if let Some(value) = mapping.get(yaml_serde::Value::String("quote_style".to_string())) {
|
|
119
|
+
let config: QuoteStyleConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
|
|
120
120
|
return Ok(PipelineStep::QuoteStyle(config));
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
if let Some(value) = mapping.get(
|
|
124
|
-
let config: SetConfig =
|
|
123
|
+
if let Some(value) = mapping.get(yaml_serde::Value::String("set".to_string())) {
|
|
124
|
+
let config: SetConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
|
|
125
125
|
return Ok(PipelineStep::Set(config));
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
if let Some(value) = mapping.get(
|
|
129
|
-
let config: InsertConfig =
|
|
128
|
+
if let Some(value) = mapping.get(yaml_serde::Value::String("insert".to_string())) {
|
|
129
|
+
let config: InsertConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
|
|
130
130
|
return Ok(PipelineStep::Insert(config));
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
if let Some(value) = mapping.get(
|
|
134
|
-
let config: DeleteConfig =
|
|
133
|
+
if let Some(value) = mapping.get(yaml_serde::Value::String("delete".to_string())) {
|
|
134
|
+
let config: DeleteConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
|
|
135
135
|
return Ok(PipelineStep::Delete(config));
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
if let Some(value) = mapping.get(
|
|
139
|
-
let config: RenameConfig =
|
|
138
|
+
if let Some(value) = mapping.get(yaml_serde::Value::String("rename".to_string())) {
|
|
139
|
+
let config: RenameConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
|
|
140
140
|
return Ok(PipelineStep::Rename(config));
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
if let Some(value) = mapping.get(
|
|
144
|
-
let config: RemoveConfig =
|
|
143
|
+
if let Some(value) = mapping.get(yaml_serde::Value::String("remove".to_string())) {
|
|
144
|
+
let config: RemoveConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
|
|
145
145
|
return Ok(PipelineStep::Remove(config));
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
if let Some(value) = mapping.get(
|
|
149
|
-
let config: BlankLinesConfig =
|
|
148
|
+
if let Some(value) = mapping.get(yaml_serde::Value::String("blank_lines".to_string())) {
|
|
149
|
+
let config: BlankLinesConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
|
|
150
150
|
return Ok(PipelineStep::BlankLines(config));
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
if let Some(value) = mapping.get(
|
|
154
|
-
let config: DirectivesConfig =
|
|
153
|
+
if let Some(value) = mapping.get(yaml_serde::Value::String("directives".to_string())) {
|
|
154
|
+
let config: DirectivesConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
|
|
155
155
|
return Ok(PipelineStep::Directives(config));
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
-
if let Some(value) = mapping.get(
|
|
159
|
-
let config: SortConfig =
|
|
158
|
+
if let Some(value) = mapping.get(yaml_serde::Value::String("sort".to_string())) {
|
|
159
|
+
let config: SortConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
|
|
160
160
|
return Ok(PipelineStep::Sort(config));
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
if let Some(value) = mapping.get(
|
|
164
|
-
let config: UniqueConfig =
|
|
163
|
+
if let Some(value) = mapping.get(yaml_serde::Value::String("unique".to_string())) {
|
|
164
|
+
let config: UniqueConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
|
|
165
165
|
return Ok(PipelineStep::Unique(config));
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
-
if let Some(value) = mapping.get(
|
|
169
|
-
let config: SchemaConfig =
|
|
168
|
+
if let Some(value) = mapping.get(yaml_serde::Value::String("schema".to_string())) {
|
|
169
|
+
let config: SchemaConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
|
|
170
170
|
return Ok(PipelineStep::Schema(config));
|
|
171
171
|
}
|
|
172
172
|
|
|
@@ -229,7 +229,7 @@ pub struct RuleResult {
|
|
|
229
229
|
impl Yerbafile {
|
|
230
230
|
pub fn load(path: impl AsRef<Path>) -> Result<Self, YerbaError> {
|
|
231
231
|
let content = fs::read_to_string(path.as_ref())?;
|
|
232
|
-
let mut yerbafile: Yerbafile =
|
|
232
|
+
let mut yerbafile: Yerbafile = yaml_serde::from_str(&content).map_err(|error| YerbaError::ParseError(format!("{}", error)))?;
|
|
233
233
|
yerbafile.directory = path.as_ref().parent().map(|p| p.to_path_buf());
|
|
234
234
|
Ok(yerbafile)
|
|
235
235
|
}
|
|
@@ -311,50 +311,6 @@ impl Yerbafile {
|
|
|
311
311
|
|
|
312
312
|
let file_strings: Vec<String> = files.iter().map(|path| path.to_string_lossy().to_string()).collect();
|
|
313
313
|
|
|
314
|
-
let mut has_validation_error = false;
|
|
315
|
-
|
|
316
|
-
for step in &rule.pipeline {
|
|
317
|
-
if let PipelineStep::SortKeys(config) = step {
|
|
318
|
-
let full_path = resolve_step_path(rule.path.as_deref(), config.path.as_deref());
|
|
319
|
-
let key_order: Vec<&str> = config.order.iter().map(|key| key.as_str()).collect();
|
|
320
|
-
|
|
321
|
-
let validation_results: Vec<RuleResult> = file_strings
|
|
322
|
-
.par_iter()
|
|
323
|
-
.filter_map(|file| {
|
|
324
|
-
let document = match Document::parse_file(file) {
|
|
325
|
-
Ok(document) => document,
|
|
326
|
-
Err(error) => {
|
|
327
|
-
return Some(RuleResult {
|
|
328
|
-
file: file.clone(),
|
|
329
|
-
changed: false,
|
|
330
|
-
error: Some(error),
|
|
331
|
-
});
|
|
332
|
-
}
|
|
333
|
-
};
|
|
334
|
-
|
|
335
|
-
if let Err(error) = document.validate_sort_keys(&full_path, &key_order) {
|
|
336
|
-
Some(RuleResult {
|
|
337
|
-
file: file.clone(),
|
|
338
|
-
changed: false,
|
|
339
|
-
error: Some(error),
|
|
340
|
-
})
|
|
341
|
-
} else {
|
|
342
|
-
None
|
|
343
|
-
}
|
|
344
|
-
})
|
|
345
|
-
.collect();
|
|
346
|
-
|
|
347
|
-
if !validation_results.is_empty() {
|
|
348
|
-
has_validation_error = true;
|
|
349
|
-
results.extend(validation_results);
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
if has_validation_error {
|
|
355
|
-
continue;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
314
|
let file_results: Vec<RuleResult> = file_strings.par_iter().map(|file| self.apply_pipeline_to_file(rule, file, write)).collect();
|
|
359
315
|
|
|
360
316
|
results.extend(file_results);
|
|
@@ -474,6 +430,7 @@ fn execute_step(document: &mut Document, step: &PipelineStep, base_path: Option<
|
|
|
474
430
|
let full_path = resolve_step_path(base_path, config.path.as_deref());
|
|
475
431
|
let key_order: Vec<&str> = config.order.iter().map(|key| key.as_str()).collect();
|
|
476
432
|
|
|
433
|
+
document.validate_sort_keys(&full_path, &key_order)?;
|
|
477
434
|
document.sort_keys(&full_path, &key_order)
|
|
478
435
|
}
|
|
479
436
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: yerba
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.1
|
|
5
5
|
platform: x86_64-linux-gnu
|
|
6
6
|
authors:
|
|
7
7
|
- Marco Roth
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-05-
|
|
11
|
+
date: 2026-05-19 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: A CLI tool for editing YAML while preserving structure, comments, and
|
|
14
14
|
format.
|