cocoapods-core 0.33.1 → 0.34.0.rc1
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/lib/cocoapods-core/dependency.rb +1 -1
- data/lib/cocoapods-core/gem_version.rb +1 -1
- data/lib/cocoapods-core/http.rb +4 -3
- data/lib/cocoapods-core/lockfile.rb +16 -15
- data/lib/cocoapods-core/podfile/dsl.rb +61 -3
- data/lib/cocoapods-core/podfile/target_definition.rb +100 -1
- data/lib/cocoapods-core/podfile.rb +9 -2
- data/lib/cocoapods-core/requirement.rb +1 -1
- data/lib/cocoapods-core/source/abstract_data_provider.rb +3 -3
- data/lib/cocoapods-core/source/aggregate.rb +17 -31
- data/lib/cocoapods-core/specification/consumer.rb +2 -2
- data/lib/cocoapods-core/specification/dsl/attribute_support.rb +4 -4
- data/lib/cocoapods-core/specification/dsl/deprecations.rb +0 -37
- data/lib/cocoapods-core/specification/dsl.rb +11 -19
- data/lib/cocoapods-core/specification/json.rb +2 -2
- data/lib/cocoapods-core/specification/linter/analyzer.rb +89 -20
- data/lib/cocoapods-core/specification/linter/result.rb +1 -1
- data/lib/cocoapods-core/specification/linter.rb +19 -2
- data/lib/cocoapods-core/specification/root_attribute_accessors.rb +7 -0
- data/lib/cocoapods-core/specification/set/presenter.rb +22 -0
- data/lib/cocoapods-core/specification/set/statistics.rb +3 -3
- data/lib/cocoapods-core/specification/set.rb +1 -1
- data/lib/cocoapods-core/specification.rb +5 -5
- data/lib/cocoapods-core/yaml_helper.rb +72 -11
- data/lib/cocoapods-core.rb +1 -1
- metadata +27 -27
@@ -38,7 +38,6 @@ module Pod
|
|
38
38
|
# spec.source = { :git => 'https://github.com/tonymillion/Reachability.git', :tag => 'v3.1.0' }
|
39
39
|
# spec.source_files = 'Reachability.{h,m}'
|
40
40
|
# spec.framework = 'SystemConfiguration'
|
41
|
-
# spec.requires_arc = true
|
42
41
|
# end
|
43
42
|
#
|
44
43
|
module DSL
|
@@ -179,6 +178,8 @@ module Pod
|
|
179
178
|
# Unless the source contains a file named `LICENSE.*` or `LICENCE.*`,
|
180
179
|
# the path of the license file **or** the integral text of the notice
|
181
180
|
# commonly used for the license type must be specified.
|
181
|
+
# If a license file is specified, it either must be without a file
|
182
|
+
# extensions or be one of `txt`, `md`, or `markdown`.
|
182
183
|
#
|
183
184
|
# This information is used by CocoaPods to generate acknowledgement
|
184
185
|
# files (markdown and plist) which can be used in the acknowledgements
|
@@ -245,17 +246,12 @@ module Pod
|
|
245
246
|
# @example Specifying a Git source with a tag. This is how most OSS Podspecs work.
|
246
247
|
#
|
247
248
|
# spec.source = { :git => 'https://github.com/AFNetworking/AFNetworking.git',
|
248
|
-
# :tag =>
|
249
|
+
# :tag => spec.version.to_s }
|
249
250
|
#
|
250
|
-
# @example Using
|
251
|
+
# @example Using a tag prefixed with 'v' and submodules.
|
251
252
|
#
|
252
|
-
# spec.source = { :git => 'https://github.com/
|
253
|
-
# :
|
254
|
-
#
|
255
|
-
# @example Using the version of the Pod to identify the Git branch.
|
256
|
-
#
|
257
|
-
# spec.source = { :git => 'https://github.com/AFNetworking/AFNetworking.git',
|
258
|
-
# :branch => "orta_fixes"}
|
253
|
+
# spec.source = { :git => 'https://github.com/typhoon-framework/Typhoon.git',
|
254
|
+
# :tag => "v#{spec.version}", :submodules => true }
|
259
255
|
#
|
260
256
|
# @example Using Subversion with a tag.
|
261
257
|
#
|
@@ -525,7 +521,7 @@ module Pod
|
|
525
521
|
# @param [String] args
|
526
522
|
# The deployment target of the platform.
|
527
523
|
#
|
528
|
-
def deployment_target=(*
|
524
|
+
def deployment_target=(*_args)
|
529
525
|
raise Informative, 'The deployment target can be declared only per ' \
|
530
526
|
'platform.'
|
531
527
|
end
|
@@ -599,24 +595,20 @@ module Pod
|
|
599
595
|
|
600
596
|
# @!method requires_arc=(flag)
|
601
597
|
#
|
602
|
-
#
|
598
|
+
# Whether the library requires ARC to be compiled. If true the
|
603
599
|
# `-fobjc-arc` flag will be added to the compiler flags.
|
604
|
-
#
|
605
|
-
# ---
|
606
|
-
#
|
607
|
-
# The default value of this attribute is __transitioning__ from `false`
|
608
|
-
# to `true`, and in the meanwhile this attribute is always required.
|
600
|
+
# The default value of this attribute is __transitioning__ is `true`.
|
609
601
|
#
|
610
602
|
# @example
|
611
603
|
#
|
612
|
-
# spec.requires_arc =
|
604
|
+
# spec.requires_arc = false
|
613
605
|
#
|
614
606
|
# @param [Bool] flag
|
615
607
|
# whether the source files require ARC.
|
616
608
|
#
|
617
609
|
attribute :requires_arc,
|
618
610
|
:types => [TrueClass, FalseClass],
|
619
|
-
:default_value =>
|
611
|
+
:default_value => true,
|
620
612
|
:inherited => true
|
621
613
|
|
622
614
|
#------------------#
|
@@ -5,7 +5,7 @@ module Pod
|
|
5
5
|
#
|
6
6
|
def to_json(*a)
|
7
7
|
require 'json'
|
8
|
-
to_hash.to_json(*a)
|
8
|
+
to_hash.to_json(*a) << "\n"
|
9
9
|
end
|
10
10
|
|
11
11
|
#-----------------------------------------------------------------------#
|
@@ -16,7 +16,7 @@ module Pod
|
|
16
16
|
def to_hash
|
17
17
|
hash = attributes_hash.dup
|
18
18
|
unless subspecs.empty?
|
19
|
-
hash['subspecs'] = subspecs.map
|
19
|
+
hash['subspecs'] = subspecs.map(&:to_hash)
|
20
20
|
end
|
21
21
|
hash
|
22
22
|
end
|
@@ -12,8 +12,8 @@ module Pod
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def analyze
|
15
|
+
check_attributes
|
15
16
|
validate_file_patterns
|
16
|
-
check_tmp_arc_not_nil
|
17
17
|
check_if_spec_is_empty
|
18
18
|
end
|
19
19
|
|
@@ -21,6 +21,46 @@ module Pod
|
|
21
21
|
|
22
22
|
attr_reader :consumer
|
23
23
|
|
24
|
+
# Checks the attributes hash for any unknown key which might be the
|
25
|
+
# result of a misspelling in a JSON file.
|
26
|
+
#
|
27
|
+
# @note Sub-keys are not checked per-platform as
|
28
|
+
# there is no attribute supporting this combination.
|
29
|
+
#
|
30
|
+
# @note The keys of sub-keys are not checked as they are only used by
|
31
|
+
# the `source` attribute and they are subject
|
32
|
+
# to change according to the support in the
|
33
|
+
# `cocoapods-downloader` gem.
|
34
|
+
#
|
35
|
+
def check_attributes
|
36
|
+
attributes_keys = Pod::Specification::DSL.attributes.keys.map(&:to_s)
|
37
|
+
platform_keys = Specification::DSL::PLATFORMS.map(&:to_s)
|
38
|
+
valid_keys = attributes_keys + platform_keys
|
39
|
+
attributes_hash = consumer.spec.attributes_hash
|
40
|
+
keys = attributes_hash.keys
|
41
|
+
Specification::DSL::PLATFORMS.each do |platform|
|
42
|
+
if attributes_hash[platform.to_s]
|
43
|
+
keys += attributes_hash[platform.to_s].keys
|
44
|
+
end
|
45
|
+
end
|
46
|
+
unknown_keys = keys - valid_keys
|
47
|
+
|
48
|
+
unknown_keys.each do |key|
|
49
|
+
warning "Unrecognized `#{key}` key"
|
50
|
+
end
|
51
|
+
|
52
|
+
Pod::Specification::DSL.attributes.each do |_key, attribute|
|
53
|
+
if attribute.keys && attribute.name != :platforms
|
54
|
+
if attribute.root_only?
|
55
|
+
value = consumer.spec.send(attribute.name)
|
56
|
+
else
|
57
|
+
value = consumer.send(attribute.name)
|
58
|
+
end
|
59
|
+
validate_attribute_value(attribute, value) if value
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
24
64
|
# Checks the attributes that represent file patterns.
|
25
65
|
#
|
26
66
|
# @todo Check the attributes hash directly.
|
@@ -41,25 +81,6 @@ module Pod
|
|
41
81
|
end
|
42
82
|
end
|
43
83
|
|
44
|
-
# @todo remove after the switch to true
|
45
|
-
#
|
46
|
-
def check_tmp_arc_not_nil
|
47
|
-
spec = consumer.spec
|
48
|
-
declared = false
|
49
|
-
loop do
|
50
|
-
declared = true unless spec.attributes_hash['requires_arc'].nil?
|
51
|
-
declared = true unless spec.attributes_hash[consumer.platform_name.to_s].nil?
|
52
|
-
spec = spec.parent
|
53
|
-
break unless spec
|
54
|
-
end
|
55
|
-
|
56
|
-
unless declared
|
57
|
-
warning '[requires_arc] A value for `requires_arc` should be' \
|
58
|
-
' specified until the ' \
|
59
|
-
'migration to a `true` default.'
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
84
|
# Check empty subspec attributes
|
64
85
|
#
|
65
86
|
def check_if_spec_is_empty
|
@@ -75,6 +96,54 @@ module Pod
|
|
75
96
|
'or subspecs).'
|
76
97
|
end
|
77
98
|
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
# Validates the given value for the given attribute.
|
103
|
+
#
|
104
|
+
# @param [Spec::DSL::Attribute] attribute
|
105
|
+
# The attribute.
|
106
|
+
#
|
107
|
+
# @param [Spec::DSL::Attribute] value
|
108
|
+
# The value of the attribute.
|
109
|
+
#
|
110
|
+
def validate_attribute_value(attribute, value)
|
111
|
+
if attribute.keys.is_a?(Array)
|
112
|
+
validate_attribute_array_keys(attribute, value)
|
113
|
+
elsif attribute.keys.is_a?(Hash)
|
114
|
+
validate_attribute_hash_keys(attribute, value)
|
115
|
+
else
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def validate_attribute_array_keys(attribute, value)
|
120
|
+
unknown_keys = value.keys.map(&:to_s) - attribute.keys.map(&:to_s)
|
121
|
+
unknown_keys.each do |unknown_key|
|
122
|
+
warning "Unrecognized `#{unknown_key}` key for " \
|
123
|
+
"`#{attribute.name}` attribute"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def validate_attribute_hash_keys(attribute, value)
|
128
|
+
major_keys = value.keys & attribute.keys.keys
|
129
|
+
if major_keys.count.zero?
|
130
|
+
warning "Missing primary key for `#{attribute.name}` " \
|
131
|
+
'attribute. The acceptable ones are: ' \
|
132
|
+
"`#{attribute.keys.keys.map(&:to_s).sort.join(', ')}`"
|
133
|
+
elsif major_keys.count == 1
|
134
|
+
acceptable = attribute.keys[major_keys.first]
|
135
|
+
unknown = value.keys - major_keys - acceptable
|
136
|
+
unless unknown.empty?
|
137
|
+
warning "Incompatible `#{unknown.sort.join(', ')}` key(s) " \
|
138
|
+
"with `#{major_keys.first}` primary key for " \
|
139
|
+
"`#{attribute.name}` attribute"
|
140
|
+
end
|
141
|
+
else
|
142
|
+
sorted_keys = major_keys.map(&:to_s).sort
|
143
|
+
warning "Incompatible `#{sorted_keys.join(', ')}` keys for " \
|
144
|
+
"`#{attribute.name}` attribute"
|
145
|
+
end
|
146
|
+
end
|
78
147
|
end
|
79
148
|
end
|
80
149
|
end
|
@@ -31,7 +31,7 @@ module Pod
|
|
31
31
|
@file = Pathname.new(spec_or_path)
|
32
32
|
begin
|
33
33
|
@spec = Specification.from_file(@file)
|
34
|
-
rescue
|
34
|
+
rescue => e
|
35
35
|
@spec = nil
|
36
36
|
@raise_message = e.message
|
37
37
|
end
|
@@ -166,7 +166,7 @@ module Pod
|
|
166
166
|
|
167
167
|
# Performs validations related to the `name` attribute.
|
168
168
|
#
|
169
|
-
def _validate_name(
|
169
|
+
def _validate_name(_n)
|
170
170
|
if spec.name && file
|
171
171
|
acceptable_names = [
|
172
172
|
spec.root.name + '.podspec',
|
@@ -273,6 +273,7 @@ module Pod
|
|
273
273
|
#
|
274
274
|
def _validate_license(l)
|
275
275
|
type = l[:type]
|
276
|
+
file = l[:file]
|
276
277
|
if type.nil?
|
277
278
|
warning '[license] Missing license type.'
|
278
279
|
end
|
@@ -282,6 +283,9 @@ module Pod
|
|
282
283
|
if type && type =~ /\(example\)/
|
283
284
|
error '[license] Sample license type.'
|
284
285
|
end
|
286
|
+
if file && Pathname.new(file).extname !~ /^(txt|md|markdown|)$/i
|
287
|
+
error '[license] Invalid file type'
|
288
|
+
end
|
285
289
|
end
|
286
290
|
|
287
291
|
# Performs validations related to the `source` attribute.
|
@@ -311,6 +315,7 @@ module Pod
|
|
311
315
|
end
|
312
316
|
|
313
317
|
perform_github_source_checks(s)
|
318
|
+
check_git_ssh_source(s)
|
314
319
|
end
|
315
320
|
|
316
321
|
# Performs validations related to github sources.
|
@@ -338,6 +343,18 @@ module Pod
|
|
338
343
|
end
|
339
344
|
end
|
340
345
|
|
346
|
+
# Performs validations related to SSH sources
|
347
|
+
#
|
348
|
+
def check_git_ssh_source(s)
|
349
|
+
if git = s[:git]
|
350
|
+
if git =~ /\w+\@(\w|\.)+\:(\/\w+)*/
|
351
|
+
warning '[source] Git SSH URLs will NOT work for people behind' \
|
352
|
+
'firewalls configured to only allow HTTP, therefor HTTPS is' \
|
353
|
+
'preferred.'
|
354
|
+
end
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
341
358
|
# Performs validations related to the `social_media_url` attribute.
|
342
359
|
#
|
343
360
|
def _validate_social_media_url(s)
|
@@ -158,6 +158,13 @@ module Pod
|
|
158
158
|
attributes_hash['deprecated_in_favor_of']
|
159
159
|
end
|
160
160
|
|
161
|
+
# @return [Bool] Wether the pod is deprecated either in favor of some other
|
162
|
+
# pod or simply deprecated.
|
163
|
+
#
|
164
|
+
def deprecated?
|
165
|
+
deprecated || !deprecated_in_favor_of.nil?
|
166
|
+
end
|
167
|
+
|
161
168
|
#---------------------------------------------------------------------#
|
162
169
|
|
163
170
|
private
|
@@ -123,6 +123,28 @@ module Pod
|
|
123
123
|
spec.description || spec.summary
|
124
124
|
end
|
125
125
|
|
126
|
+
# @return [String] A string that describes the deprecation of the pod.
|
127
|
+
# If the pod is deprecated in favor of another pod it will contain
|
128
|
+
# information about that. If the pod is not deprecated returns nil.
|
129
|
+
#
|
130
|
+
# @example Output example
|
131
|
+
#
|
132
|
+
# "[DEPRECATED]"
|
133
|
+
# "[DEPRECATED in favor of NewAwesomePod]"
|
134
|
+
#
|
135
|
+
def deprecation_description
|
136
|
+
if spec.deprecated?
|
137
|
+
description = '[DEPRECATED'
|
138
|
+
if spec.deprecated_in_favor_of.nil?
|
139
|
+
description += ']'
|
140
|
+
else
|
141
|
+
description += " in favor of #{spec.deprecated_in_favor_of}]"
|
142
|
+
end
|
143
|
+
|
144
|
+
description
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
126
148
|
# @return [String] the URL of the source of the Pod.
|
127
149
|
#
|
128
150
|
def source_url
|
@@ -27,8 +27,8 @@ module Pod
|
|
27
27
|
#
|
28
28
|
# @return [Statistics] the shared statistics instance.
|
29
29
|
#
|
30
|
-
|
31
|
-
|
30
|
+
class << self
|
31
|
+
attr_writer :instance
|
32
32
|
end
|
33
33
|
|
34
34
|
# @return [Pathname] the path to the optional cache file.
|
@@ -153,7 +153,7 @@ module Pod
|
|
153
153
|
def cache
|
154
154
|
unless @cache
|
155
155
|
if cache_file && cache_file.exist?
|
156
|
-
@cache = YAMLHelper.
|
156
|
+
@cache = YAMLHelper.load_string(cache_file.read)
|
157
157
|
else
|
158
158
|
@cache = {}
|
159
159
|
end
|
@@ -94,7 +94,7 @@ module Pod
|
|
94
94
|
|
95
95
|
# TODO
|
96
96
|
#
|
97
|
-
def specification_path_for_version(
|
97
|
+
def specification_path_for_version(_version)
|
98
98
|
sources = []
|
99
99
|
versions_by_source.each do |source, source_versions|
|
100
100
|
sources << source if source_versions.include?(required_version)
|
@@ -120,12 +120,12 @@ module Pod
|
|
120
120
|
# pod.
|
121
121
|
#
|
122
122
|
def self.name_and_version_from_string(string_representation)
|
123
|
-
match_data = string_representation.match(
|
123
|
+
match_data = string_representation.match(/\A(\S*)(?: \((.+)\))?\Z/)
|
124
124
|
unless match_data
|
125
125
|
raise Informative, 'Invalid string representation for a ' \
|
126
|
-
"
|
127
|
-
'
|
128
|
-
'the version of
|
126
|
+
"specification: `#{string_representation}`. " \
|
127
|
+
'The string representation should include the name and ' \
|
128
|
+
'optionally the version of the Pod.'
|
129
129
|
end
|
130
130
|
name = match_data[1]
|
131
131
|
vers = Version.new(match_data[2])
|
@@ -563,7 +563,7 @@ module Pod
|
|
563
563
|
# rubocop:disable Eval
|
564
564
|
eval(string, nil, path.to_s)
|
565
565
|
# rubocop:enable Eval
|
566
|
-
rescue
|
566
|
+
rescue => e
|
567
567
|
message = "Invalid `#{path.basename}` file: #{e.message}"
|
568
568
|
raise DSLError.new(message, path, e.backtrace)
|
569
569
|
end
|
@@ -17,14 +17,14 @@ module Pod
|
|
17
17
|
class YAMLHelper
|
18
18
|
class << self
|
19
19
|
# Returns the YAML representation of the given object. If the given object
|
20
|
-
# is
|
20
|
+
# is a Hash, it accepts an optional hint for sorting the keys.
|
21
21
|
#
|
22
22
|
# @param [String, Symbol, Array, Hash] object
|
23
23
|
# the object to convert
|
24
24
|
#
|
25
25
|
# @param [Array] hash_keys_hint
|
26
26
|
# an array to use as a hint for sorting the keys of the object to
|
27
|
-
# convert if it is
|
27
|
+
# convert if it is a hash.
|
28
28
|
#
|
29
29
|
# @return [String] the YAML representation of the given object.
|
30
30
|
#
|
@@ -38,18 +38,39 @@ module Pod
|
|
38
38
|
result << "\n"
|
39
39
|
end
|
40
40
|
|
41
|
-
#
|
42
|
-
#
|
43
|
-
|
41
|
+
# Loads a YAML string and provide more informative
|
42
|
+
# error messages in special cases like merge conflict.
|
43
|
+
#
|
44
|
+
# @param [String] yaml_string
|
45
|
+
# The YAML String to be loaded
|
46
|
+
#
|
47
|
+
# @param [Pathname] file_path
|
48
|
+
# The (optional) file path to be used for read for the YAML file
|
49
|
+
#
|
50
|
+
# @return [Hash, Array] the Ruby YAML representaton
|
51
|
+
#
|
52
|
+
def load_string(yaml_string, file_path = nil)
|
44
53
|
YAML.load(yaml_string)
|
45
|
-
rescue
|
46
|
-
if yaml_has_merge_error(yaml_string)
|
47
|
-
raise Informative,
|
54
|
+
rescue
|
55
|
+
if yaml_has_merge_error?(yaml_string)
|
56
|
+
raise Informative, yaml_merge_conflict_msg(yaml_string, file_path)
|
48
57
|
else
|
49
|
-
raise
|
58
|
+
raise Informative, yaml_parsing_error_msg(yaml_string, file_path)
|
50
59
|
end
|
51
60
|
end
|
52
61
|
|
62
|
+
# Loads a YAML file and leans on the #load_string imp
|
63
|
+
# to do error detection
|
64
|
+
#
|
65
|
+
# @param [Pathname] file_path
|
66
|
+
# The file path to be used for read for the YAML file
|
67
|
+
#
|
68
|
+
# @return [Hash, Array] the Ruby YAML representaton
|
69
|
+
#
|
70
|
+
def load_file(file_path)
|
71
|
+
load_string(File.read(file_path), file_path)
|
72
|
+
end
|
73
|
+
|
53
74
|
#-----------------------------------------------------------------------#
|
54
75
|
|
55
76
|
private
|
@@ -130,12 +151,52 @@ module Pod
|
|
130
151
|
end
|
131
152
|
|
132
153
|
# Check for merge errors in a YAML string.
|
133
|
-
#
|
154
|
+
#
|
155
|
+
# @param [String] yaml_string
|
156
|
+
# A YAML string to evaluate
|
157
|
+
#
|
134
158
|
# @return If a merge error was detected or not.
|
135
|
-
|
159
|
+
#
|
160
|
+
def yaml_has_merge_error?(yaml_string)
|
136
161
|
yaml_string.include?('<<<<<<< HEAD')
|
137
162
|
end
|
138
163
|
|
164
|
+
# Error message describing that a merge conflict was found
|
165
|
+
# while parsing the YAML.
|
166
|
+
#
|
167
|
+
# @param [String] yaml
|
168
|
+
# Offending YAML
|
169
|
+
#
|
170
|
+
# @param [Pathname] path
|
171
|
+
# The (optional) offending path
|
172
|
+
#
|
173
|
+
# @return [String] The Error Message
|
174
|
+
#
|
175
|
+
def yaml_merge_conflict_msg(yaml, path = nil)
|
176
|
+
err = 'ERROR: Parsing unable to continue due '
|
177
|
+
err += "to merge conflicts present in:\n"
|
178
|
+
err += "the file located at #{path}\n" if path
|
179
|
+
err += "#{yaml}"
|
180
|
+
end
|
181
|
+
|
182
|
+
# Error message describing a general error took happened
|
183
|
+
# while parsing the YAML.
|
184
|
+
#
|
185
|
+
# @param [String] yaml
|
186
|
+
# Offending YAML
|
187
|
+
#
|
188
|
+
# @param [Pathname] path
|
189
|
+
# The (optional) offending path
|
190
|
+
#
|
191
|
+
# @return [String] The Error Message
|
192
|
+
#
|
193
|
+
def yaml_parsing_error_msg(yaml, path = nil)
|
194
|
+
err = 'ERROR: Parsing unable to continue due '
|
195
|
+
err += "to parsing error:\n"
|
196
|
+
err += "contained in the file located at #{path}\n" if path
|
197
|
+
err += "#{yaml}"
|
198
|
+
end
|
199
|
+
|
139
200
|
#-----------------------------------------------------------------------#
|
140
201
|
|
141
202
|
private
|