yerba 0.7.1-aarch64-linux-gnu → 0.7.3-aarch64-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/exe/aarch64-linux-gnu/yerba +0 -0
- data/ext/yerba/include/yerba.h +5 -0
- data/ext/yerba/yerba.c +16 -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/document.rb +21 -1
- data/lib/yerba/map.rb +4 -0
- data/lib/yerba/node.rb +6 -0
- data/lib/yerba/sequence.rb +4 -0
- data/lib/yerba/version.rb +1 -1
- data/lib/yerba.rb +1 -0
- data/rust/Cargo.lock +1 -1
- data/rust/Cargo.toml +1 -1
- data/rust/src/document/condition.rs +4 -4
- data/rust/src/document/delete.rs +8 -31
- data/rust/src/document/get.rs +10 -16
- data/rust/src/document/insert.rs +50 -144
- data/rust/src/document/mod.rs +85 -79
- data/rust/src/document/schema.rs +1 -1
- data/rust/src/document/set.rs +42 -38
- data/rust/src/document/sort.rs +150 -310
- data/rust/src/document/style.rs +78 -308
- data/rust/src/document/unique.rs +4 -5
- data/rust/src/ffi.rs +12 -0
- data/rust/src/selector.rs +3 -3
- data/rust/src/syntax.rs +63 -47
- 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: f833e343807c30f0370315dd082a4bb931ef283ab61da1917185bd993c192185
|
|
4
|
+
data.tar.gz: b6a4090bea313c06a5a7c6ac23638e8d223c3869a6d117fa4f3508260bae1245
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1bea0a8fd3cf92f0e8f814884d35b1b8ebfba4ef28498f377f3f4343e23db5cfaa50f48ac0e8dd5832f32824410ce3bdad208c60dfc97e9c74d42a5d179c83e9
|
|
7
|
+
data.tar.gz: e49bc007a98d7871b67cad0c4095512db1c28f88f1b2b2868fff0913ea4970df85a859100fba6149c7f93ce77dd42f1c27fb0cb7eef4888ec98c121633636091
|
data/exe/aarch64-linux-gnu/yerba
CHANGED
|
Binary file
|
data/ext/yerba/include/yerba.h
CHANGED
|
@@ -72,6 +72,11 @@ void yerba_document_free(struct Document *document);
|
|
|
72
72
|
|
|
73
73
|
struct YerbaGetResult yerba_document_get(const struct Document *document, const char *path);
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Caller must free with yerba_string_free.
|
|
77
|
+
*/
|
|
78
|
+
char *yerba_document_source(const struct Document *document, const char *path);
|
|
79
|
+
|
|
75
80
|
/**
|
|
76
81
|
* Caller must free with yerba_string_free.
|
|
77
82
|
*/
|
data/ext/yerba/yerba.c
CHANGED
|
@@ -119,10 +119,12 @@ static VALUE document_initialize(int argc, VALUE *argv, VALUE self) {
|
|
|
119
119
|
if (NIL_P(path)) {
|
|
120
120
|
result = yerba_document_parse("---\n");
|
|
121
121
|
rb_iv_set(self, "@path", Qnil);
|
|
122
|
+
rb_iv_set(self, "@loaded_mtime", Qnil);
|
|
122
123
|
} else {
|
|
123
124
|
const char *file_path = StringValueCStr(path);
|
|
124
125
|
result = yerba_document_parse_file(file_path);
|
|
125
126
|
rb_iv_set(self, "@path", path);
|
|
127
|
+
rb_iv_set(self, "@loaded_mtime", rb_funcall(rb_cFile, rb_intern("mtime"), 1, path));
|
|
126
128
|
}
|
|
127
129
|
|
|
128
130
|
if (!result.document) {
|
|
@@ -297,6 +299,19 @@ static VALUE document_valid_selector_p(VALUE self, VALUE path) {
|
|
|
297
299
|
return yerba_document_valid_selector(document, StringValueCStr(path)) ? Qtrue : Qfalse;
|
|
298
300
|
}
|
|
299
301
|
|
|
302
|
+
/* document.source(path) → raw YAML text of the node at path */
|
|
303
|
+
static VALUE document_source(VALUE self, VALUE path) {
|
|
304
|
+
struct Document *document = get_document(self);
|
|
305
|
+
char *text = yerba_document_source(document, StringValueCStr(path));
|
|
306
|
+
|
|
307
|
+
if (!text) return Qnil;
|
|
308
|
+
|
|
309
|
+
VALUE result = make_utf8_string(text);
|
|
310
|
+
yerba_string_free(text);
|
|
311
|
+
|
|
312
|
+
return result;
|
|
313
|
+
}
|
|
314
|
+
|
|
300
315
|
/* document.get_value(path) → parsed Ruby object (Hash/Array/String/Integer/etc) */
|
|
301
316
|
static VALUE document_get_value(VALUE self, VALUE path) {
|
|
302
317
|
struct Document *document = get_document(self);
|
|
@@ -1091,6 +1106,7 @@ void Init_yerba(void) {
|
|
|
1091
1106
|
rb_define_method(rb_cDocument, "blank_lines", document_blank_lines, 2);
|
|
1092
1107
|
rb_define_method(rb_cDocument, "apply_yerbafile", document_apply_yerbafile, -1);
|
|
1093
1108
|
rb_define_method(rb_cDocument, "validate_schema", document_validate_schema, -1);
|
|
1109
|
+
rb_define_method(rb_cDocument, "source", document_source, 1);
|
|
1094
1110
|
rb_define_method(rb_cDocument, "to_s", document_to_s, 0);
|
|
1095
1111
|
rb_define_method(rb_cDocument, "write!", document_save, 0);
|
|
1096
1112
|
rb_define_method(rb_cDocument, "changed?", document_changed_p, 0);
|
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/document.rb
CHANGED
|
@@ -64,9 +64,16 @@ module Yerba
|
|
|
64
64
|
|
|
65
65
|
def save_to!(path)
|
|
66
66
|
@path = path
|
|
67
|
+
@loaded_mtime = nil
|
|
67
68
|
save!
|
|
68
69
|
end
|
|
69
70
|
|
|
71
|
+
def stale?
|
|
72
|
+
return false unless @path && @loaded_mtime
|
|
73
|
+
|
|
74
|
+
File.mtime(@path) != @loaded_mtime
|
|
75
|
+
end
|
|
76
|
+
|
|
70
77
|
def dig(*keys)
|
|
71
78
|
keys.reduce(self) { |node, key| node.nil? ? nil : node[key] }
|
|
72
79
|
end
|
|
@@ -106,15 +113,18 @@ module Yerba
|
|
|
106
113
|
end
|
|
107
114
|
|
|
108
115
|
def save!(apply: false)
|
|
116
|
+
check_stale!
|
|
109
117
|
Yerbafile.apply!(self, apply) if apply
|
|
110
118
|
write!
|
|
111
|
-
|
|
119
|
+
@loaded_mtime = File.mtime(@path) if @path
|
|
112
120
|
self
|
|
113
121
|
end
|
|
114
122
|
|
|
115
123
|
def apply!(yerbafile = nil)
|
|
124
|
+
check_stale!
|
|
116
125
|
apply(yerbafile)
|
|
117
126
|
write! if changed?
|
|
127
|
+
@loaded_mtime = File.mtime(@path) if @path
|
|
118
128
|
|
|
119
129
|
self
|
|
120
130
|
end
|
|
@@ -157,6 +167,16 @@ module Yerba
|
|
|
157
167
|
raise Yerba::SelectorNotFoundError, message
|
|
158
168
|
end
|
|
159
169
|
|
|
170
|
+
private
|
|
171
|
+
|
|
172
|
+
def check_stale!
|
|
173
|
+
return unless stale?
|
|
174
|
+
|
|
175
|
+
raise Yerba::StaleFileError, "#{@path} was modified externally since it was loaded"
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
public
|
|
179
|
+
|
|
160
180
|
def inspect
|
|
161
181
|
if path
|
|
162
182
|
"#<Yerba::Document path=#{path.inspect}>"
|
data/lib/yerba/map.rb
CHANGED
data/lib/yerba/node.rb
CHANGED
|
@@ -20,6 +20,12 @@ module Yerba
|
|
|
20
20
|
!@document.nil? || !@file_path.nil?
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
+
def source
|
|
24
|
+
return nil unless connected? && @selector
|
|
25
|
+
|
|
26
|
+
document.source(@selector)
|
|
27
|
+
end
|
|
28
|
+
|
|
23
29
|
module ClassMethods
|
|
24
30
|
def from_document(document, selector, location = nil, key = nil, **attributes)
|
|
25
31
|
instance = allocate
|
data/lib/yerba/sequence.rb
CHANGED
data/lib/yerba/version.rb
CHANGED
data/lib/yerba.rb
CHANGED
|
@@ -30,6 +30,7 @@ module Yerba
|
|
|
30
30
|
class ExecutableNotFoundError < StandardError; end
|
|
31
31
|
class CompilationError < StandardError; end
|
|
32
32
|
class SelectorNotFoundError < StandardError; end
|
|
33
|
+
class StaleFileError < StandardError; end
|
|
33
34
|
|
|
34
35
|
GEM_NAME = "yerba"
|
|
35
36
|
EXECUTABLE_NAME = "yerba"
|
data/rust/Cargo.lock
CHANGED
data/rust/Cargo.toml
CHANGED
|
@@ -11,7 +11,7 @@ impl Document {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
pub fn filter_with_selectors(&self, dot_path: &str, condition: &str) -> Vec<(yaml_serde::Value, String, usize)> {
|
|
14
|
-
let source = self.
|
|
14
|
+
let source = self.source_text();
|
|
15
15
|
|
|
16
16
|
self
|
|
17
17
|
.navigate_all_compact(dot_path)
|
|
@@ -19,7 +19,7 @@ impl Document {
|
|
|
19
19
|
.filter(|node| self.evaluate_condition_on_node(node, condition))
|
|
20
20
|
.map(|node| {
|
|
21
21
|
let offset: usize = node.text_range().start().into();
|
|
22
|
-
let line = source
|
|
22
|
+
let line = line_at(&source, offset);
|
|
23
23
|
|
|
24
24
|
(node_to_yaml_value(node), super::get::node_selector(node), line)
|
|
25
25
|
})
|
|
@@ -52,7 +52,7 @@ impl Document {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
for node in &target_nodes {
|
|
55
|
-
if let Some(sequence) = node
|
|
55
|
+
if let Some(sequence) = find_block_sequence(node) {
|
|
56
56
|
for entry in sequence.entries() {
|
|
57
57
|
if let Some(text) = entry.flow().and_then(|flow| extract_scalar_text(flow.syntax())) {
|
|
58
58
|
if text == right {
|
|
@@ -67,7 +67,7 @@ impl Document {
|
|
|
67
67
|
}
|
|
68
68
|
"not_contains" => {
|
|
69
69
|
for node in &target_nodes {
|
|
70
|
-
if let Some(sequence) = node
|
|
70
|
+
if let Some(sequence) = find_block_sequence(node) {
|
|
71
71
|
for entry in sequence.entries() {
|
|
72
72
|
if let Some(text) = entry.flow().and_then(|flow| extract_scalar_text(flow.syntax())) {
|
|
73
73
|
if text == right {
|
data/rust/src/document/delete.rs
CHANGED
|
@@ -13,10 +13,7 @@ impl Document {
|
|
|
13
13
|
let (parent_path, source_key) = source_path.rsplit_once('.').unwrap_or(("", source_path));
|
|
14
14
|
let parent_node = self.navigate(parent_path)?;
|
|
15
15
|
|
|
16
|
-
let map = parent_node
|
|
17
|
-
.descendants()
|
|
18
|
-
.find_map(BlockMap::cast)
|
|
19
|
-
.ok_or_else(|| YerbaError::SelectorNotFound(source_path.to_string()))?;
|
|
16
|
+
let map = find_block_map(&parent_node).ok_or_else(|| YerbaError::SelectorNotFound(source_path.to_string()))?;
|
|
20
17
|
|
|
21
18
|
let entry = find_entry_by_key(&map, source_key).ok_or_else(|| YerbaError::SelectorNotFound(source_path.to_string()))?;
|
|
22
19
|
let key_node = entry.key().ok_or_else(|| YerbaError::SelectorNotFound(source_path.to_string()))?;
|
|
@@ -46,10 +43,7 @@ impl Document {
|
|
|
46
43
|
|
|
47
44
|
if parent_path.is_empty() && !has_wildcard {
|
|
48
45
|
let parent_node = self.navigate(&parent_path)?;
|
|
49
|
-
let map = parent_node
|
|
50
|
-
.descendants()
|
|
51
|
-
.find_map(BlockMap::cast)
|
|
52
|
-
.ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
46
|
+
let map = find_block_map(&parent_node).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
53
47
|
|
|
54
48
|
let entry = find_entry_by_key(&map, last_key).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
55
49
|
|
|
@@ -67,10 +61,7 @@ impl Document {
|
|
|
67
61
|
}
|
|
68
62
|
|
|
69
63
|
if parent_nodes.len() == 1 && !has_wildcard {
|
|
70
|
-
let map = parent_nodes[0]
|
|
71
|
-
.descendants()
|
|
72
|
-
.find_map(BlockMap::cast)
|
|
73
|
-
.ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
64
|
+
let map = find_block_map(&parent_nodes[0]).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
74
65
|
|
|
75
66
|
let entry = find_entry_by_key(&map, last_key).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
76
67
|
|
|
@@ -80,24 +71,16 @@ impl Document {
|
|
|
80
71
|
let mut ranges: Vec<TextRange> = Vec::new();
|
|
81
72
|
|
|
82
73
|
for parent_node in &parent_nodes {
|
|
83
|
-
if let Some(map) = parent_node
|
|
74
|
+
if let Some(map) = find_block_map(parent_node) {
|
|
84
75
|
if let Some(entry) = find_entry_by_key(&map, last_key) {
|
|
85
76
|
ranges.push(removal_range(entry.syntax()));
|
|
86
77
|
}
|
|
87
78
|
}
|
|
88
79
|
}
|
|
89
80
|
|
|
90
|
-
|
|
91
|
-
return Ok(());
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
ranges.reverse();
|
|
95
|
-
|
|
96
|
-
for range in ranges {
|
|
97
|
-
self.apply_edit(range, "")?;
|
|
98
|
-
}
|
|
81
|
+
let edits = ranges.into_iter().map(|range| (range, String::new())).collect();
|
|
99
82
|
|
|
100
|
-
|
|
83
|
+
self.apply_edits(edits)
|
|
101
84
|
}
|
|
102
85
|
|
|
103
86
|
crate::selector::SelectorSegment::Index(index) => self.remove_at(&parent_path, *index),
|
|
@@ -108,10 +91,7 @@ impl Document {
|
|
|
108
91
|
pub fn remove(&mut self, dot_path: &str, value: &str) -> Result<(), YerbaError> {
|
|
109
92
|
let current_node = self.navigate(dot_path)?;
|
|
110
93
|
|
|
111
|
-
let sequence = current_node
|
|
112
|
-
.descendants()
|
|
113
|
-
.find_map(BlockSeq::cast)
|
|
114
|
-
.ok_or_else(|| YerbaError::NotASequence(dot_path.to_string()))?;
|
|
94
|
+
let sequence = find_block_sequence(¤t_node).ok_or_else(|| YerbaError::NotASequence(dot_path.to_string()))?;
|
|
115
95
|
|
|
116
96
|
let target_entry = sequence
|
|
117
97
|
.entries()
|
|
@@ -132,10 +112,7 @@ impl Document {
|
|
|
132
112
|
|
|
133
113
|
let current_node = self.navigate(dot_path)?;
|
|
134
114
|
|
|
135
|
-
let sequence = current_node
|
|
136
|
-
.descendants()
|
|
137
|
-
.find_map(BlockSeq::cast)
|
|
138
|
-
.ok_or_else(|| YerbaError::NotASequence(dot_path.to_string()))?;
|
|
115
|
+
let sequence = find_block_sequence(¤t_node).ok_or_else(|| YerbaError::NotASequence(dot_path.to_string()))?;
|
|
139
116
|
|
|
140
117
|
let entries: Vec<_> = sequence.entries().collect();
|
|
141
118
|
|
data/rust/src/document/get.rs
CHANGED
|
@@ -83,7 +83,7 @@ impl Document {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
pub fn get_all_located(&self, dot_path: &str) -> Vec<LocatedNode> {
|
|
86
|
-
let source = self.
|
|
86
|
+
let source = self.source_text();
|
|
87
87
|
let file_path = self.path.as_ref().map(|p| p.to_string_lossy().to_string());
|
|
88
88
|
|
|
89
89
|
self
|
|
@@ -91,7 +91,7 @@ impl Document {
|
|
|
91
91
|
.iter()
|
|
92
92
|
.map(|node| {
|
|
93
93
|
let offset: usize = node.text_range().start().into();
|
|
94
|
-
let line = source
|
|
94
|
+
let line = line_at(&source, offset);
|
|
95
95
|
let selector = node_selector(node);
|
|
96
96
|
let is_scalar = !node
|
|
97
97
|
.descendants()
|
|
@@ -108,13 +108,8 @@ impl Document {
|
|
|
108
108
|
let node_type = if is_scalar {
|
|
109
109
|
"scalar"
|
|
110
110
|
} else {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
match (map_pos, seq_pos) {
|
|
115
|
-
(Some(m), Some(s)) if s < m => "sequence",
|
|
116
|
-
(Some(_), _) => "map",
|
|
117
|
-
(None, Some(_)) => "sequence",
|
|
111
|
+
match first_collection(node) {
|
|
112
|
+
Some(FirstCollection::Sequence(_)) => "sequence",
|
|
118
113
|
_ => "map",
|
|
119
114
|
}
|
|
120
115
|
};
|
|
@@ -142,7 +137,7 @@ impl Document {
|
|
|
142
137
|
|
|
143
138
|
pub fn get_node_info(&self, dot_path: &str) -> NodeInfo {
|
|
144
139
|
let selector = crate::selector::Selector::parse(dot_path);
|
|
145
|
-
let source = self.
|
|
140
|
+
let source = self.source_text();
|
|
146
141
|
|
|
147
142
|
let (location, key_name, key_location) = self.resolve_location(dot_path, &source);
|
|
148
143
|
|
|
@@ -364,7 +359,7 @@ impl Document {
|
|
|
364
359
|
self.navigate(parent_path).ok()?
|
|
365
360
|
};
|
|
366
361
|
|
|
367
|
-
let map = parent_node
|
|
362
|
+
let map = find_block_map(&parent_node)?;
|
|
368
363
|
|
|
369
364
|
find_entry_by_key(&map, last_key).map(|entry| entry.syntax().clone())
|
|
370
365
|
}
|
|
@@ -375,7 +370,7 @@ impl Document {
|
|
|
375
370
|
Err(_) => return Vec::new(),
|
|
376
371
|
};
|
|
377
372
|
|
|
378
|
-
let sequence = match current_node
|
|
373
|
+
let sequence = match find_block_sequence(¤t_node) {
|
|
379
374
|
Some(sequence) => sequence,
|
|
380
375
|
None => return Vec::new(),
|
|
381
376
|
};
|
|
@@ -403,17 +398,16 @@ impl Document {
|
|
|
403
398
|
pub fn get_sequence_indent(&self, dot_path: &str) -> Option<&'static str> {
|
|
404
399
|
let current_node = self.navigate(dot_path).ok()?;
|
|
405
400
|
|
|
406
|
-
let sequence = current_node
|
|
401
|
+
let sequence = find_block_sequence(¤t_node)?;
|
|
407
402
|
let first_entry = sequence.entries().next()?;
|
|
408
403
|
|
|
409
404
|
let entry_indent = preceding_whitespace_indent(first_entry.syntax());
|
|
410
405
|
|
|
411
406
|
let entry_node = current_node.ancestors().find(|ancestor| ancestor.kind() == SyntaxKind::BLOCK_MAP_ENTRY)?;
|
|
412
407
|
|
|
413
|
-
let source = self.
|
|
408
|
+
let source = self.source_text();
|
|
414
409
|
let entry_start: usize = entry_node.text_range().start().into();
|
|
415
|
-
let
|
|
416
|
-
let key_indent = &source[line_start..entry_start];
|
|
410
|
+
let key_indent = &source[line_start_at(&source, entry_start)..entry_start];
|
|
417
411
|
|
|
418
412
|
if entry_indent.len() > key_indent.len() {
|
|
419
413
|
Some("indented")
|