yerba 0.3.0-aarch64-linux-gnu → 0.4.1-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/README.md +93 -8
- data/exe/aarch64-linux-gnu/yerba +0 -0
- data/ext/yerba/extconf.rb +22 -3
- data/ext/yerba/include/yerba.h +32 -9
- data/ext/yerba/yerba.c +133 -25
- 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/collection.rb +35 -0
- data/lib/yerba/document.rb +45 -3
- data/lib/yerba/query_result.rb +50 -0
- data/lib/yerba/sequence.rb +187 -1
- data/lib/yerba/version.rb +1 -1
- data/lib/yerba/yerbafile.rb +45 -0
- data/lib/yerba.rb +2 -0
- data/rust/Cargo.lock +3 -1
- data/rust/Cargo.toml +3 -2
- data/rust/cbindgen.toml +1 -0
- data/rust/rustfmt.toml +1 -1
- data/rust/src/commands/apply.rs +11 -2
- data/rust/src/commands/blank_lines.rs +1 -4
- data/rust/src/commands/check.rs +11 -2
- data/rust/src/commands/directives.rs +61 -0
- data/rust/src/commands/get.rs +5 -22
- data/rust/src/commands/mod.rs +16 -18
- data/rust/src/commands/quote_style.rs +12 -6
- data/rust/src/commands/selectors.rs +3 -19
- data/rust/src/commands/sort.rs +22 -157
- data/rust/src/didyoumean.rs +2 -4
- data/rust/src/document/condition.rs +139 -0
- data/rust/src/document/delete.rs +91 -0
- data/rust/src/document/get.rs +262 -0
- data/rust/src/document/insert.rs +384 -0
- data/rust/src/document/mod.rs +784 -0
- data/rust/src/document/set.rs +100 -0
- data/rust/src/document/sort.rs +639 -0
- data/rust/src/document/style.rs +473 -0
- data/rust/src/error.rs +24 -6
- data/rust/src/ffi.rs +272 -518
- data/rust/src/json.rs +1 -7
- data/rust/src/lib.rs +88 -2
- data/rust/src/main.rs +2 -0
- data/rust/src/quote_style.rs +83 -7
- data/rust/src/selector.rs +2 -7
- data/rust/src/syntax.rs +41 -21
- data/rust/src/yerbafile.rs +86 -19
- metadata +13 -3
- data/rust/src/document.rs +0 -2304
data/lib/yerba/document.rb
CHANGED
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
module Yerba
|
|
4
4
|
class Document
|
|
5
|
+
ROOT_SELECTOR = ""
|
|
6
|
+
|
|
5
7
|
def root
|
|
6
|
-
self[
|
|
8
|
+
self[ROOT_SELECTOR]
|
|
7
9
|
end
|
|
8
10
|
|
|
9
11
|
def map?
|
|
@@ -15,11 +17,11 @@ module Yerba
|
|
|
15
17
|
end
|
|
16
18
|
|
|
17
19
|
def to_h
|
|
18
|
-
get_value(
|
|
20
|
+
get_value(ROOT_SELECTOR)
|
|
19
21
|
end
|
|
20
22
|
|
|
21
23
|
def to_a
|
|
22
|
-
get_value(
|
|
24
|
+
get_value(ROOT_SELECTOR)
|
|
23
25
|
end
|
|
24
26
|
|
|
25
27
|
def to_yaml
|
|
@@ -48,6 +50,46 @@ module Yerba
|
|
|
48
50
|
end
|
|
49
51
|
end
|
|
50
52
|
|
|
53
|
+
def find_by(...)
|
|
54
|
+
root.find_by(...)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def where(...)
|
|
58
|
+
root.where(...)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def pluck(...)
|
|
62
|
+
root.pluck(...)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def <<(item)
|
|
66
|
+
root << item
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def concat(items)
|
|
70
|
+
root.concat(items)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def save!(apply: false)
|
|
74
|
+
Yerbafile.apply!(self, apply) if apply
|
|
75
|
+
write!
|
|
76
|
+
|
|
77
|
+
self
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def apply!(yerbafile = nil)
|
|
81
|
+
apply(yerbafile)
|
|
82
|
+
write! if changed?
|
|
83
|
+
|
|
84
|
+
self
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def apply(yerbafile = nil)
|
|
88
|
+
Yerbafile.apply!(self, yerbafile)
|
|
89
|
+
|
|
90
|
+
self
|
|
91
|
+
end
|
|
92
|
+
|
|
51
93
|
def inspect
|
|
52
94
|
if path
|
|
53
95
|
"#<Yerba::Document path=#{path.inspect}>"
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yerba
|
|
4
|
+
class QueryResult
|
|
5
|
+
include Enumerable
|
|
6
|
+
|
|
7
|
+
def initialize(sequence, indices)
|
|
8
|
+
@sequence = sequence
|
|
9
|
+
@indices = indices
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def each
|
|
13
|
+
return enum_for(:each) unless block_given?
|
|
14
|
+
|
|
15
|
+
@indices.each { |index| yield @sequence[index] }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def [](position)
|
|
19
|
+
index = @indices[position]
|
|
20
|
+
|
|
21
|
+
@sequence[index] if index
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def first
|
|
25
|
+
self[0]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def last
|
|
29
|
+
self[-1]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def length
|
|
33
|
+
@indices.length
|
|
34
|
+
end
|
|
35
|
+
alias size length
|
|
36
|
+
alias count length
|
|
37
|
+
|
|
38
|
+
def empty?
|
|
39
|
+
@indices.empty?
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def indices
|
|
43
|
+
@indices.dup
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def inspect
|
|
47
|
+
"#<Yerba::QueryResult length=#{length}>"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
data/lib/yerba/sequence.rb
CHANGED
|
@@ -55,10 +55,121 @@ module Yerba
|
|
|
55
55
|
self
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
+
def concat(items)
|
|
59
|
+
if @document
|
|
60
|
+
hashes = items.map do |item|
|
|
61
|
+
case item
|
|
62
|
+
when Map then item.to_hash
|
|
63
|
+
when Hash then item
|
|
64
|
+
else { value: item.to_s }
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
@document.insert_objects(@selector, hashes)
|
|
69
|
+
else
|
|
70
|
+
@data.concat(items)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
self
|
|
74
|
+
end
|
|
75
|
+
|
|
58
76
|
def each
|
|
59
77
|
return enum_for(:each) unless block_given?
|
|
60
78
|
|
|
61
|
-
length.times { |
|
|
79
|
+
length.times { |index| yield self[index] }
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def find_by(selector = nil, value = nil, **criteria)
|
|
83
|
+
index = index_of(selector, value, **criteria)
|
|
84
|
+
|
|
85
|
+
self[index] if index
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def where(selector = nil, value = nil, **criteria)
|
|
89
|
+
QueryResult.new(self, indices_of(selector, value, **criteria))
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def pluck(*fields)
|
|
93
|
+
return [] unless @document
|
|
94
|
+
|
|
95
|
+
all_values = @document.get_value(@selector)
|
|
96
|
+
return [] unless all_values.is_a?(Array)
|
|
97
|
+
|
|
98
|
+
if fields.length == 1
|
|
99
|
+
|
|
100
|
+
all_values.map { |item| item.is_a?(Hash) ? item[fields.first.to_s] : item }
|
|
101
|
+
else
|
|
102
|
+
|
|
103
|
+
all_values.map { |item| fields.map(&:to_s).map { |field| item.is_a?(Hash) ? item[field] : nil } }
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def index_of(selector = nil, value = nil, **criteria)
|
|
108
|
+
if selector && value.nil? && criteria.empty?
|
|
109
|
+
values = @document&.get("#{@selector}[]")
|
|
110
|
+
|
|
111
|
+
return values.index(selector) if values.is_a?(Array)
|
|
112
|
+
|
|
113
|
+
return nil
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
criteria[selector] = value if selector && value
|
|
117
|
+
pairs = expand_nested_criteria(criteria)
|
|
118
|
+
|
|
119
|
+
indices = nil
|
|
120
|
+
|
|
121
|
+
pairs.each do |field, expected|
|
|
122
|
+
field_string = field.to_s
|
|
123
|
+
|
|
124
|
+
if field_string.include?("[]")
|
|
125
|
+
matching = nested_indices_for(field_string, expected)
|
|
126
|
+
else
|
|
127
|
+
values = @document&.get("#{@selector}[].#{field_string}")
|
|
128
|
+
|
|
129
|
+
next unless values.is_a?(Array)
|
|
130
|
+
|
|
131
|
+
matching = values.each_with_index.filter_map { |actual, index| index if actual == expected }
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
indices = indices ? indices & matching : matching
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
indices&.first
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def indices_of(selector = nil, value = nil, **criteria)
|
|
141
|
+
if selector && value.nil? && criteria.empty?
|
|
142
|
+
values = @document&.get("#{@selector}[]")
|
|
143
|
+
|
|
144
|
+
if values.is_a?(Array)
|
|
145
|
+
return values.each_with_index.filter_map { |actual, index| index if actual == selector }
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
return []
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
criteria[selector] = value if selector && value
|
|
152
|
+
pairs = expand_nested_criteria(criteria)
|
|
153
|
+
|
|
154
|
+
indices = nil
|
|
155
|
+
|
|
156
|
+
pairs.each do |field, expected|
|
|
157
|
+
field_string = field.to_s
|
|
158
|
+
|
|
159
|
+
if field_string.include?("[]")
|
|
160
|
+
matching = nested_indices_for(field_string, expected)
|
|
161
|
+
else
|
|
162
|
+
values = @document&.get("#{@selector}[].#{field_string}")
|
|
163
|
+
|
|
164
|
+
next unless values.is_a?(Array)
|
|
165
|
+
|
|
166
|
+
matching = values.each_with_index.filter_map { |actual, index| index if actual == expected }
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
indices = indices ? indices & matching : matching
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
indices || []
|
|
62
173
|
end
|
|
63
174
|
|
|
64
175
|
def length
|
|
@@ -69,6 +180,7 @@ module Yerba
|
|
|
69
180
|
scalar_items.length
|
|
70
181
|
else
|
|
71
182
|
data = @document.get_value(@selector)
|
|
183
|
+
|
|
72
184
|
data.is_a?(Array) ? data.length : 0
|
|
73
185
|
end
|
|
74
186
|
else
|
|
@@ -156,6 +268,79 @@ module Yerba
|
|
|
156
268
|
|
|
157
269
|
private
|
|
158
270
|
|
|
271
|
+
def expand_nested_criteria(criteria)
|
|
272
|
+
expanded = []
|
|
273
|
+
|
|
274
|
+
criteria.each do |field, value|
|
|
275
|
+
if value.is_a?(Hash)
|
|
276
|
+
flatten_hash("#{field}[]", value).each do |path, leaf_value|
|
|
277
|
+
expanded << [path, leaf_value]
|
|
278
|
+
end
|
|
279
|
+
elsif value.is_a?(Array)
|
|
280
|
+
value.each do |item|
|
|
281
|
+
expanded << ["#{field}[]", item]
|
|
282
|
+
end
|
|
283
|
+
else
|
|
284
|
+
expanded << [field, value]
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
expanded
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def flatten_hash(prefix, hash)
|
|
292
|
+
result = {}
|
|
293
|
+
|
|
294
|
+
hash.each do |key, value|
|
|
295
|
+
path = "#{prefix}.#{key}"
|
|
296
|
+
|
|
297
|
+
if value.is_a?(Hash)
|
|
298
|
+
flatten_hash("#{path}[]", value).each { |nested_path, leaf| result[nested_path] = leaf }
|
|
299
|
+
else
|
|
300
|
+
result[path] = value
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
result
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
def nested_indices_for(field, expected)
|
|
308
|
+
all_values = @document&.get_value(@selector)
|
|
309
|
+
return [] unless all_values.is_a?(Array)
|
|
310
|
+
|
|
311
|
+
all_values.each_with_index.filter_map do |item, index|
|
|
312
|
+
next unless item.is_a?(Hash)
|
|
313
|
+
|
|
314
|
+
nested_values = dig_values(item, field)
|
|
315
|
+
index if nested_values.include?(expected)
|
|
316
|
+
end
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
def dig_values(hash, path)
|
|
320
|
+
parts = path.split(".")
|
|
321
|
+
current = [hash]
|
|
322
|
+
|
|
323
|
+
parts.each do |part|
|
|
324
|
+
next_values = []
|
|
325
|
+
|
|
326
|
+
current.each do |value|
|
|
327
|
+
if part == "[]" && value.is_a?(Array)
|
|
328
|
+
next_values.concat(value)
|
|
329
|
+
elsif part.end_with?("[]")
|
|
330
|
+
key = part.chomp("[]")
|
|
331
|
+
child = value.is_a?(Hash) ? value[key] : nil
|
|
332
|
+
next_values.concat(child) if child.is_a?(Array)
|
|
333
|
+
elsif value.is_a?(Hash)
|
|
334
|
+
next_values << value[part] if value.key?(part)
|
|
335
|
+
end
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
current = next_values
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
current
|
|
342
|
+
end
|
|
343
|
+
|
|
159
344
|
def format_for_insert(value)
|
|
160
345
|
Formatting.quote(value, detect_quote_style)
|
|
161
346
|
end
|
|
@@ -172,6 +357,7 @@ module Yerba
|
|
|
172
357
|
result
|
|
173
358
|
else
|
|
174
359
|
data = @document.get_value(@selector)
|
|
360
|
+
|
|
175
361
|
data.is_a?(Array) ? data : []
|
|
176
362
|
end
|
|
177
363
|
else
|
data/lib/yerba/version.rb
CHANGED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yerba
|
|
4
|
+
class Yerbafile
|
|
5
|
+
attr_reader :path
|
|
6
|
+
|
|
7
|
+
def initialize(path)
|
|
8
|
+
@path = File.expand_path(path)
|
|
9
|
+
|
|
10
|
+
raise Yerba::Error, "Yerbafile not found: #{path}" unless File.exist?(@path)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.find(directory = Dir.pwd)
|
|
14
|
+
path = locate(directory)
|
|
15
|
+
|
|
16
|
+
path ? new(path) : nil
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.find!(directory = Dir.pwd)
|
|
20
|
+
find(directory) || raise(Yerba::Error, "No Yerbafile found")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.resolve(yerbafile = nil)
|
|
24
|
+
case yerbafile
|
|
25
|
+
when Yerbafile then yerbafile
|
|
26
|
+
when String then new(yerbafile)
|
|
27
|
+
when true, nil then find!
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.apply!(document, yerbafile = nil)
|
|
32
|
+
resolve(yerbafile).apply(document)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def apply(document)
|
|
36
|
+
document.apply_yerbafile(@path)
|
|
37
|
+
|
|
38
|
+
document
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def inspect
|
|
42
|
+
"#<Yerba::Yerbafile path=#{@path.inspect}>"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
data/lib/yerba.rb
CHANGED
|
@@ -8,8 +8,10 @@ require_relative "yerba/formatting"
|
|
|
8
8
|
require_relative "yerba/scalar"
|
|
9
9
|
require_relative "yerba/map"
|
|
10
10
|
require_relative "yerba/sequence"
|
|
11
|
+
require_relative "yerba/query_result"
|
|
11
12
|
require_relative "yerba/document"
|
|
12
13
|
require_relative "yerba/collection"
|
|
14
|
+
require_relative "yerba/yerbafile"
|
|
13
15
|
|
|
14
16
|
begin
|
|
15
17
|
major, minor, = RUBY_VERSION.split(".")
|
data/rust/Cargo.lock
CHANGED
|
@@ -472,6 +472,7 @@ version = "1.0.149"
|
|
|
472
472
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
473
473
|
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
|
|
474
474
|
dependencies = [
|
|
475
|
+
"indexmap",
|
|
475
476
|
"itoa",
|
|
476
477
|
"memchr",
|
|
477
478
|
"serde",
|
|
@@ -784,7 +785,7 @@ dependencies = [
|
|
|
784
785
|
|
|
785
786
|
[[package]]
|
|
786
787
|
name = "yerba"
|
|
787
|
-
version = "0.
|
|
788
|
+
version = "0.4.1"
|
|
788
789
|
dependencies = [
|
|
789
790
|
"cbindgen",
|
|
790
791
|
"clap",
|
|
@@ -795,6 +796,7 @@ dependencies = [
|
|
|
795
796
|
"serde",
|
|
796
797
|
"serde_json",
|
|
797
798
|
"serde_yaml",
|
|
799
|
+
"tempfile",
|
|
798
800
|
"yaml_parser",
|
|
799
801
|
]
|
|
800
802
|
|
data/rust/Cargo.toml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "yerba"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.4.1"
|
|
4
4
|
edition = "2021"
|
|
5
5
|
authors = ["Marco Roth <marco.roth@intergga.ch>"]
|
|
6
6
|
description = "YAML Editing and Refactoring with Better Accuracy"
|
|
@@ -25,7 +25,7 @@ rowan = "0.16"
|
|
|
25
25
|
glob = "0.3"
|
|
26
26
|
serde = { version = "1", features = ["derive"] }
|
|
27
27
|
serde_yaml = "0.9"
|
|
28
|
-
serde_json = "1"
|
|
28
|
+
serde_json = { version = "1", features = ["preserve_order"] }
|
|
29
29
|
clap = { version = "4", features = ["derive"] }
|
|
30
30
|
indoc = "2"
|
|
31
31
|
rayon = "1"
|
|
@@ -34,3 +34,4 @@ rayon = "1"
|
|
|
34
34
|
cbindgen = "0.28"
|
|
35
35
|
|
|
36
36
|
[dev-dependencies]
|
|
37
|
+
tempfile = "3"
|
data/rust/cbindgen.toml
CHANGED
data/rust/rustfmt.toml
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
tab_spaces = 2
|
|
2
|
-
max_width =
|
|
2
|
+
max_width = 160
|
data/rust/src/commands/apply.rs
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
use super::run_yerbafile;
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
#[derive(clap::Args)]
|
|
4
|
+
#[command(about = "Apply Yerbafile rules to all matching files (or specific files)")]
|
|
5
|
+
pub struct Args {
|
|
6
|
+
/// Specific files to apply rules to (applies to all if omitted)
|
|
7
|
+
files: Vec<String>,
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
impl Args {
|
|
11
|
+
pub fn run(self) {
|
|
12
|
+
run_yerbafile(true, self.files);
|
|
13
|
+
}
|
|
5
14
|
}
|
|
@@ -39,10 +39,7 @@ impl Args {
|
|
|
39
39
|
} else {
|
|
40
40
|
use super::color::*;
|
|
41
41
|
|
|
42
|
-
eprintln!(
|
|
43
|
-
"{RED}Error:{RESET} expected a number for blank line count, got '{}'",
|
|
44
|
-
self.first
|
|
45
|
-
);
|
|
42
|
+
eprintln!("{RED}Error:{RESET} expected a number for blank line count, got '{}'", self.first);
|
|
46
43
|
|
|
47
44
|
std::process::exit(1);
|
|
48
45
|
};
|
data/rust/src/commands/check.rs
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
use super::run_yerbafile;
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
#[derive(clap::Args)]
|
|
4
|
+
#[command(about = "Check if files match Yerbafile rules (exits 1 if changes needed)")]
|
|
5
|
+
pub struct Args {
|
|
6
|
+
/// Specific files to check (checks all if omitted)
|
|
7
|
+
files: Vec<String>,
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
impl Args {
|
|
11
|
+
pub fn run(self) {
|
|
12
|
+
run_yerbafile(false, self.files);
|
|
13
|
+
}
|
|
5
14
|
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
use std::sync::LazyLock;
|
|
2
|
+
|
|
3
|
+
use indoc::indoc;
|
|
4
|
+
|
|
5
|
+
use super::colorize_examples;
|
|
6
|
+
use super::{output, parse_file, resolve_files};
|
|
7
|
+
|
|
8
|
+
static EXAMPLES: LazyLock<String> = LazyLock::new(|| {
|
|
9
|
+
colorize_examples(indoc! {r#"
|
|
10
|
+
yerba directives config.yml --ensure
|
|
11
|
+
yerba directives config.yml --remove
|
|
12
|
+
yerba directives "data/**/*.yml" --ensure
|
|
13
|
+
yerba directives config.yml --ensure --dry-run
|
|
14
|
+
"#})
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
#[derive(clap::Args)]
|
|
18
|
+
#[command(
|
|
19
|
+
about = "Add or remove the document start marker (---)",
|
|
20
|
+
arg_required_else_help = true,
|
|
21
|
+
after_help = EXAMPLES.as_str()
|
|
22
|
+
)]
|
|
23
|
+
pub struct Args {
|
|
24
|
+
file: String,
|
|
25
|
+
/// Add --- if missing
|
|
26
|
+
#[arg(long)]
|
|
27
|
+
ensure: bool,
|
|
28
|
+
/// Remove --- if present
|
|
29
|
+
#[arg(long)]
|
|
30
|
+
remove: bool,
|
|
31
|
+
#[arg(long)]
|
|
32
|
+
dry_run: bool,
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
impl Args {
|
|
36
|
+
pub fn run(self) {
|
|
37
|
+
if !self.ensure && !self.remove {
|
|
38
|
+
use super::color::*;
|
|
39
|
+
eprintln!("{RED}Error:{RESET} specify --ensure or --remove");
|
|
40
|
+
std::process::exit(1);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if self.ensure && self.remove {
|
|
44
|
+
use super::color::*;
|
|
45
|
+
eprintln!("{RED}Error:{RESET} --ensure and --remove are mutually exclusive");
|
|
46
|
+
std::process::exit(1);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
for resolved_file in resolve_files(&self.file) {
|
|
50
|
+
let mut document = parse_file(&resolved_file);
|
|
51
|
+
|
|
52
|
+
if self.ensure {
|
|
53
|
+
let _ = document.ensure_directives();
|
|
54
|
+
} else if self.remove {
|
|
55
|
+
let _ = document.remove_directives();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
output(&resolved_file, &document, self.dry_run);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
data/rust/src/commands/get.rs
CHANGED
|
@@ -77,10 +77,7 @@ impl Args {
|
|
|
77
77
|
|
|
78
78
|
use super::color::*;
|
|
79
79
|
|
|
80
|
-
eprintln!(
|
|
81
|
-
"{RED}Error:{RESET} selector \"{}\" not found in {}",
|
|
82
|
-
self.selector, resolved_file
|
|
83
|
-
);
|
|
80
|
+
eprintln!("{RED}Error:{RESET} selector \"{}\" not found in {}", self.selector, resolved_file);
|
|
84
81
|
|
|
85
82
|
show_similar_selectors(resolved_file, &document, &self.selector);
|
|
86
83
|
process::exit(1);
|
|
@@ -97,11 +94,7 @@ impl Args {
|
|
|
97
94
|
|
|
98
95
|
if !document.exists(&full_selector) {
|
|
99
96
|
use super::color::*;
|
|
100
|
-
eprintln!(
|
|
101
|
-
"{RED}Error:{RESET} select field \"{}\" not found in {}",
|
|
102
|
-
field.trim(),
|
|
103
|
-
resolved_file
|
|
104
|
-
);
|
|
97
|
+
eprintln!("{RED}Error:{RESET} select field \"{}\" not found in {}", field.trim(), resolved_file);
|
|
105
98
|
show_similar_selectors(resolved_file, &document, &full_selector);
|
|
106
99
|
process::exit(1);
|
|
107
100
|
}
|
|
@@ -175,23 +168,13 @@ impl Args {
|
|
|
175
168
|
}
|
|
176
169
|
}
|
|
177
170
|
} else if all_results.len() == 1 {
|
|
178
|
-
println!(
|
|
179
|
-
"{}",
|
|
180
|
-
serde_json::to_string_pretty(&all_results[0]).unwrap_or_else(|_| "null".to_string())
|
|
181
|
-
);
|
|
171
|
+
println!("{}", serde_json::to_string_pretty(&all_results[0]).unwrap_or_else(|_| "null".to_string()));
|
|
182
172
|
} else {
|
|
183
|
-
println!(
|
|
184
|
-
"{}",
|
|
185
|
-
serde_json::to_string_pretty(&all_results).unwrap_or_else(|_| "[]".to_string())
|
|
186
|
-
);
|
|
173
|
+
println!("{}", serde_json::to_string_pretty(&all_results).unwrap_or_else(|_| "[]".to_string()));
|
|
187
174
|
}
|
|
188
175
|
}
|
|
189
176
|
|
|
190
|
-
fn resolve_search_scope(
|
|
191
|
-
&self,
|
|
192
|
-
selector: &yerba::Selector,
|
|
193
|
-
condition_path: Option<&yerba::Selector>,
|
|
194
|
-
) -> (yerba::Selector, Option<yerba::Selector>) {
|
|
177
|
+
fn resolve_search_scope(&self, selector: &yerba::Selector, condition_path: Option<&yerba::Selector>) -> (yerba::Selector, Option<yerba::Selector>) {
|
|
195
178
|
if let Some(condition) = condition_path {
|
|
196
179
|
if condition.is_relative() {
|
|
197
180
|
let (container, field) = selector.split_at_last_bracket();
|