yaml_normalizer 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d872c2e4bbddcde16c368ddd2279ad2b1a5a6f85
4
+ data.tar.gz: 0b2f989dfbc4c0be5250f3afffc8fa654703462f
5
+ SHA512:
6
+ metadata.gz: ca1c6808fc72ce7354a192ff7addc18d0d5fbf409ca030790da5f096977057785aa174307a89ebca66ad744801556895635118df0e7dbce6d20126f1289b72d2
7
+ data.tar.gz: 9a3c8646211ecc2279b99f36688f99540115d57d0cb2dfbb707d026346ba671c0b27499ff1e5a5b5675f2ef0cb4cdec2bfdee10e8e123e61fb4cbd58524fcb9f
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'yaml_normalizer'
5
+
6
+ YamlNormalizer::Services::Normalize.call(*ARGV)
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml_normalizer'
4
+
5
+ module YamlNormalizer
6
+ # Provides Rake task integration
7
+ class RakeTask < ::Rake::TaskLib
8
+ # @return [String] name of the Rake task
9
+ attr_accessor :name
10
+ # @return [Array] arguments to be passed to Suggest.run
11
+ attr_accessor :args
12
+
13
+ # @param name [String] name of the Rake task
14
+ # @param *args [Array] arguments to be passed to Normalize.call
15
+ # @param &block [Proc] optional, evaluated inside the task definition
16
+ def initialize(name = 'yaml_normalizer', *args, &block)
17
+ @name = name
18
+ @args = args
19
+ yield(self) if block
20
+
21
+ desc 'Normalize all YAML files in path'
22
+ task(@name) { normalize }
23
+ end
24
+
25
+ # @return [void]
26
+ def normalize
27
+ ::YamlNormalizer::Services::Normalize.call('**/*')
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YamlNormalizer
4
+ module Refinements
5
+ # Refine Hash to add method sort_by_key
6
+ module HashNamespaced
7
+ refine Hash do
8
+ # Transforms a tree-shaped hash into a plain key-value pair hash,
9
+ # separating tree levels with a dot.
10
+ # @examples
11
+ # {a: {b: {c: 1}}, b:{x: 2, y: {ok: true}, z: 4}}.namespaced
12
+ # => {"a.b.c"=>1, "b.x"=>2, "b.y.ok"=>true, "b.z"=>4}
13
+ def namespaced(namespace = [], tree = {})
14
+ each do |key, value|
15
+ child_ns = namespace.dup << key
16
+ if value.is_a?(Hash)
17
+ value.namespaced child_ns, tree
18
+ else
19
+ tree[child_ns.join('.')] = value
20
+ end
21
+ end
22
+ tree
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ # mutant doen't support Refinements use monky-patch for mutation testing
30
+ # class Hash
31
+ # # Transforms a tree-shaped hash into a plain key-value pair hash,
32
+ # # separating tree levels with a dot.
33
+ # # @examples
34
+ # # {a: {b: {c: 1}}, b:{x: 2, y: {ok: true}, z: 4}}.namespaced
35
+ # # => {"a.b.c"=>1, "b.x"=>2, "b.y.ok"=>true, "b.z"=>4}
36
+ # def namespaced(namespace = [], tree = {})
37
+ # each do |key, value|
38
+ # child_ns = namespace.dup << key
39
+ # if value.is_a?(Hash)
40
+ # value.namespaced child_ns, tree
41
+ # else
42
+ # tree[child_ns.join('.')] = value
43
+ # end
44
+ # end
45
+ # tree
46
+ # end
47
+ # end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YamlNormalizer
4
+ module Refinements
5
+ # Refine Hash to add method sort_by_key
6
+ module HashSortByKey
7
+ refine Hash do
8
+ # Sorts entries alphabetically by key and returns a new Hash
9
+ # sort_by_key does not modify the Hash it's called on.
10
+ def sort_by_key(recursive = true, &block)
11
+ keys.sort(&block).each_with_object({}) do |key, seed|
12
+ seed[key] = self[key]
13
+ if recursive && seed[key].is_a?(Hash)
14
+ seed[key] = seed[key].sort_by_key(true, &block)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ # mutant doen't support Refinements use monky-patch for mutation testing
24
+ # class Hash
25
+ # # Sorts entries alphabetically by key and returns a new Hash
26
+ # # sort_by_key does not modify the Hash it's called on.
27
+ # def sort_by_key(recursive = true, &block)
28
+ # keys.sort(&block).each_with_object({}) do |key, seed|
29
+ # seed[key] = self[key]
30
+ # if recursive && seed[key].is_a?(Hash)
31
+ # seed[key] = seed[key].sort_by_key(true, &block)
32
+ # end
33
+ # end
34
+ # end
35
+ # end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YamlNormalizer
4
+ # Refinements holds all refinements used for Yaml Normalizer
5
+ module Refinements
6
+ end
7
+ end
8
+
9
+ require 'yaml_normalizer/refinements/hash_sort_by_key'
10
+ require 'yaml_normalizer/refinements/hash_namespaced'
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YamlNormalizer
4
+ module Services
5
+ # The Base Service provides a convenience class method "call" to initialize
6
+ # the Service with the given arguments and call the method "call" on the
7
+ # instance.
8
+ class Base
9
+ # A convenience class method to initialize Normalize with the given
10
+ # arguments and call the method "call" on the instance.
11
+ def self.call(*args)
12
+ new(*args).call
13
+ end
14
+
15
+ # Inherit from Base and implement the call method
16
+ def call
17
+ raise NotImplementedError
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'psych'
4
+
5
+ module YamlNormalizer
6
+ module Services
7
+ # describe!
8
+ class IsYaml < Base
9
+ attr_reader :file
10
+
11
+ def initialize(file)
12
+ @file = file.to_s
13
+ end
14
+
15
+ # Return true if given file is a valid YAML file
16
+ def call
17
+ file? && parsable? && !scalar?
18
+ end
19
+
20
+ private
21
+
22
+ def file?
23
+ File.file? file
24
+ end
25
+
26
+ # The current implementation does not require parsable? to return a
27
+ # boolean value
28
+ def parsable?
29
+ Psych.load_file(file)
30
+ rescue Psych::SyntaxError
31
+ false
32
+ end
33
+
34
+ def scalar?
35
+ Psych.load_file(file).instance_of? String
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'peach'
4
+
5
+ module YamlNormalizer
6
+ module Services
7
+ # Normalize is a Service that provides functionality to
8
+ class Normalize < Base
9
+ attr_reader :files
10
+
11
+ using YamlNormalizer::Refinements::HashSortByKey
12
+ using YamlNormalizer::Refinements::HashNamespaced
13
+
14
+ def initialize(*args)
15
+ files = args.each_with_object([]) { |a, o| o << Dir[a.to_s] }
16
+ @files = files.flatten.sort.uniq
17
+ end
18
+
19
+ # Normalizes all YAML files defined on instantiation.
20
+ def call
21
+ files.peach do |file|
22
+ if IsYaml.call(file)
23
+ normalize!(file)
24
+ else
25
+ $stderr.puts "#{file} not a YAML file"
26
+ end
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def normalize!(file)
33
+ if stable?(input = File.read(file), norm = normalize_yaml(input))
34
+ File.open(file, 'w') { |f| f.write(norm) }
35
+ $stderr.puts "[NORMALIZED] #{file}"
36
+ else
37
+ $stderr.puts "[ERROR] Could not normalize #{file}"
38
+ end
39
+ end
40
+
41
+ def normalize_yaml(yaml)
42
+ hashes = Psych.parse_stream(yaml).transform
43
+ hashes.map(&:sort_by_key).map(&:to_yaml).join
44
+ end
45
+
46
+ def stable?(yaml_a, yaml_b)
47
+ parse(yaml_a).each_with_index.all? do |a, i|
48
+ a.namespaced.eql?(parse(yaml_b).fetch(i).namespaced)
49
+ end
50
+ end
51
+
52
+ def parse(yaml)
53
+ Psych.parse_stream(yaml).transform
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YamlNormalizer
4
+ # Holds all Yaml Normalizer services
5
+ module Services
6
+ end
7
+ end
8
+
9
+ require 'yaml_normalizer/services/base'
10
+ require 'yaml_normalizer/services/is_yaml'
11
+ require 'yaml_normalizer/services/normalize'
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module YamlNormalizer
4
+ # The current Yaml Normalizer version
5
+ VERSION = '0.1.0'
6
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Yaml Normalizer normalizes YAML files ensuring Psych's parsing result of
4
+ # the YAML file is identical before and after normalization.
5
+ module YamlNormalizer
6
+ end
7
+
8
+ require 'yaml_normalizer/version'
9
+ require 'yaml_normalizer/refinements'
10
+ require 'yaml_normalizer/services'
metadata ADDED
@@ -0,0 +1,370 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: yaml_normalizer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Wolfgang Teuber
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-03-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: psych
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: peach
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.5'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: parallel_tests
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: mutant-rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: cane
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: flay
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: flog
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: inch
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: coveralls
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: guard
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
209
+ - !ruby/object:Gem::Dependency
210
+ name: guard-rubocop
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - ">="
214
+ - !ruby/object:Gem::Version
215
+ version: '0'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ">="
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
223
+ - !ruby/object:Gem::Dependency
224
+ name: guard-rspec
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - ">="
228
+ - !ruby/object:Gem::Version
229
+ version: '0'
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ version: '0'
237
+ - !ruby/object:Gem::Dependency
238
+ name: yard
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - ">="
242
+ - !ruby/object:Gem::Version
243
+ version: '0'
244
+ type: :development
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - ">="
249
+ - !ruby/object:Gem::Version
250
+ version: '0'
251
+ - !ruby/object:Gem::Dependency
252
+ name: redcarpet
253
+ requirement: !ruby/object:Gem::Requirement
254
+ requirements:
255
+ - - ">="
256
+ - !ruby/object:Gem::Version
257
+ version: '0'
258
+ type: :development
259
+ prerelease: false
260
+ version_requirements: !ruby/object:Gem::Requirement
261
+ requirements:
262
+ - - ">="
263
+ - !ruby/object:Gem::Version
264
+ version: '0'
265
+ - !ruby/object:Gem::Dependency
266
+ name: github-markup
267
+ requirement: !ruby/object:Gem::Requirement
268
+ requirements:
269
+ - - ">="
270
+ - !ruby/object:Gem::Version
271
+ version: '0'
272
+ type: :development
273
+ prerelease: false
274
+ version_requirements: !ruby/object:Gem::Requirement
275
+ requirements:
276
+ - - ">="
277
+ - !ruby/object:Gem::Version
278
+ version: '0'
279
+ - !ruby/object:Gem::Dependency
280
+ name: awesome_print
281
+ requirement: !ruby/object:Gem::Requirement
282
+ requirements:
283
+ - - ">="
284
+ - !ruby/object:Gem::Version
285
+ version: '0'
286
+ type: :development
287
+ prerelease: false
288
+ version_requirements: !ruby/object:Gem::Requirement
289
+ requirements:
290
+ - - ">="
291
+ - !ruby/object:Gem::Version
292
+ version: '0'
293
+ - !ruby/object:Gem::Dependency
294
+ name: pry
295
+ requirement: !ruby/object:Gem::Requirement
296
+ requirements:
297
+ - - ">="
298
+ - !ruby/object:Gem::Version
299
+ version: '0'
300
+ type: :development
301
+ prerelease: false
302
+ version_requirements: !ruby/object:Gem::Requirement
303
+ requirements:
304
+ - - ">="
305
+ - !ruby/object:Gem::Version
306
+ version: '0'
307
+ - !ruby/object:Gem::Dependency
308
+ name: pry-byebug
309
+ requirement: !ruby/object:Gem::Requirement
310
+ requirements:
311
+ - - ">="
312
+ - !ruby/object:Gem::Version
313
+ version: '0'
314
+ type: :development
315
+ prerelease: false
316
+ version_requirements: !ruby/object:Gem::Requirement
317
+ requirements:
318
+ - - ">="
319
+ - !ruby/object:Gem::Version
320
+ version: '0'
321
+ description: |-
322
+ Yaml Normalizer follows the notion that there is
323
+ a normalized YAML file format. It re-formats YAML files in a way that the
324
+ results closely match Psych's output. Yaml Normalizer ensures that the
325
+ original file and the resulting file are 100% identical to Psych (stable
326
+ change).
327
+ email:
328
+ - wolfgang.teuber@sage.com
329
+ executables:
330
+ - yaml_normalizer
331
+ extensions: []
332
+ extra_rdoc_files: []
333
+ files:
334
+ - bin/yaml_normalizer
335
+ - lib/yaml_normalizer.rb
336
+ - lib/yaml_normalizer/rake_task.rb
337
+ - lib/yaml_normalizer/refinements.rb
338
+ - lib/yaml_normalizer/refinements/hash_namespaced.rb
339
+ - lib/yaml_normalizer/refinements/hash_sort_by_key.rb
340
+ - lib/yaml_normalizer/services.rb
341
+ - lib/yaml_normalizer/services/base.rb
342
+ - lib/yaml_normalizer/services/is_yaml.rb
343
+ - lib/yaml_normalizer/services/normalize.rb
344
+ - lib/yaml_normalizer/version.rb
345
+ homepage: https://github.com/Sage/yaml_normalizer
346
+ licenses:
347
+ - MIT
348
+ metadata: {}
349
+ post_install_message:
350
+ rdoc_options: []
351
+ require_paths:
352
+ - lib
353
+ required_ruby_version: !ruby/object:Gem::Requirement
354
+ requirements:
355
+ - - ">="
356
+ - !ruby/object:Gem::Version
357
+ version: '0'
358
+ required_rubygems_version: !ruby/object:Gem::Requirement
359
+ requirements:
360
+ - - ">="
361
+ - !ruby/object:Gem::Version
362
+ version: '0'
363
+ requirements: []
364
+ rubyforge_project:
365
+ rubygems_version: 2.6.8
366
+ signing_key:
367
+ specification_version: 4
368
+ summary: Yaml Normalizer normalizes YAML files
369
+ test_files: []
370
+ has_rdoc: