immosquare-yaml 1.0.2 → 1.0.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a2841e06b484ab63541fde122db5b67873fed11ace07d10423eae10ac4eb32b0
4
- data.tar.gz: ca15c7313768d2c70597370cf4121becd73d4afd32b70735d80572c66daabbbb
3
+ metadata.gz: 18474159a026b7caf6296f284339cd69fc74e3d413cc80135d527873a92db43d
4
+ data.tar.gz: a4e7b2e8193dde12dc218a055e6dd857dfdd5255f70ffdebe38568943ee5ffd0
5
5
  SHA512:
6
- metadata.gz: 89eafa27859e41e9a61ae861b746157dc010af7a29ecaffa8a42f0fc612d30c4637eea21aadad5293abafe670b5c5b317b861902fb7c2e8cbb858d40074fe5a8
7
- data.tar.gz: 48b27854d7f28c95f98a4f5bdbe04674a08407699c4ae27f5623571ec1a98fb8751e70fba844bf1dfe3f423bd9fae16a30b497233cc0536f8ef965e3a91f40e9
6
+ metadata.gz: 3895b71e4cee8091551f0ec75a9e95ecdc4a622c89778dac4bdee06d0abf66146021904b583e4baede6a9f12716532f51669d71355298579ce245561641e55fd
7
+ data.tar.gz: bd33415993538752b14b6c18919c984a5964efc2b800161871393d382908bb25949bcd7445780db51fa66b1786ac3c7a2214ee2ccf74253dc645d7b3a4b33bdd
@@ -0,0 +1,101 @@
1
+ module ImmosquareYaml
2
+ ##============================================================##
3
+ ## Delete — removes one or more dot-paths from an i18n YAML
4
+ ## file and re-emits it through the standard dump pipeline
5
+ ## (sort, quoting, literal blocks). Empty parent Hashes left
6
+ ## behind by a deletion are pruned recursively so the YAML
7
+ ## doesn't keep dangling empty maps.
8
+ ##
9
+ ## Path quoting follows the same convention as flatten_keys /
10
+ ## parse_path : reserved (yes/no/true/...) and purely numeric
11
+ ## segments must be wrapped in "..." inside the dot-path.
12
+ ##============================================================##
13
+ class << self
14
+
15
+ ##============================================================##
16
+ ## delete_paths(file_path, paths, sort: true, output: file_path)
17
+ ##
18
+ ## paths : a single dot-path String or an Array<String>.
19
+ ##
20
+ ## Returns a Hash :
21
+ ## { :deleted => [paths actually removed],
22
+ ## :not_found => [paths that did not exist in the file] }
23
+ ##
24
+ ## Returns false if the file cannot be parsed or if its root
25
+ ## node is not a Hash (i18n YAML files are always mappings).
26
+ ##
27
+ ## Note : the file is always rewritten through `dump`, even when
28
+ ## every path is reported as :not_found. This means calling
29
+ ## `delete_paths` doubles as a `clean` (sort + reformat) on the
30
+ ## target file. Use `:output => "..."` to write elsewhere.
31
+ ##============================================================##
32
+ def delete_paths(file_path, paths, **options)
33
+ options = {
34
+ :sort => true,
35
+ :output => file_path
36
+ }.merge(options)
37
+
38
+ begin
39
+ raise("File not found") if !File.exist?(file_path)
40
+
41
+ parsed = parse(file_path, :sort => options[:sort])
42
+ return false if parsed == false || !parsed.is_a?(Hash)
43
+
44
+ paths = Array(paths)
45
+ deleted = []
46
+ not_found = []
47
+
48
+ ##============================================================##
49
+ ## Walk each dot-path, delete the leaf if present, prune
50
+ ## empty parents on the way back up.
51
+ ##============================================================##
52
+ paths.each do |dot_path|
53
+ segments = parse_path(dot_path)
54
+ if !segments.empty? && delete_at_segments(parsed, segments)
55
+ deleted << dot_path
56
+ else
57
+ not_found << dot_path
58
+ end
59
+ end
60
+
61
+ output = dump(parsed)
62
+ FileUtils.mkdir_p(File.dirname(options[:output]))
63
+ File.write(options[:output], output)
64
+
65
+ {:deleted => deleted, :not_found => not_found}
66
+ rescue StandardError => e
67
+ puts(e.message)
68
+ puts(e.backtrace)
69
+ false
70
+ end
71
+ end
72
+
73
+
74
+ private
75
+
76
+
77
+ ##============================================================##
78
+ ## Recursive segment walker. Returns true if a leaf was
79
+ ## actually removed. On the way back up, an intermediate Hash
80
+ ## that has become empty is pruned from its parent so the
81
+ ## final YAML doesn't keep dangling empty maps.
82
+ ##============================================================##
83
+ def delete_at_segments(hash, segments)
84
+ return false if !hash.is_a?(Hash)
85
+
86
+ head, *rest = segments
87
+ return false if !hash.key?(head)
88
+
89
+ if rest.empty?
90
+ hash.delete(head)
91
+ return true
92
+ end
93
+
94
+ child = hash[head]
95
+ removed = delete_at_segments(child, rest)
96
+ hash.delete(head) if removed && child.is_a?(Hash) && child.empty?
97
+ removed
98
+ end
99
+
100
+ end
101
+ end
@@ -1,3 +1,3 @@
1
1
  module ImmosquareYaml
2
- VERSION = "1.0.2".freeze
2
+ VERSION = "1.0.4".freeze
3
3
  end
@@ -3,6 +3,7 @@ require "fileutils"
3
3
  require "immosquare-extensions"
4
4
  require_relative "immosquare-yaml/shared_methods"
5
5
  require_relative "immosquare-yaml/flatten"
6
+ require_relative "immosquare-yaml/delete"
6
7
 
7
8
  ##============================================================##
8
9
  ## ImmosquareYaml — post-processeur Psych dédié aux fichiers
@@ -271,7 +272,8 @@ module ImmosquareYaml
271
272
  ##
272
273
  ## On quote si la valeur contient des caractères qui auraient
273
274
  ## un sens YAML particulier en plain (": ", " #", début par un
274
- ## caractère spécial, fin par ":", mot réservé, espace en bord).
275
+ ## caractère spécial, fin par ":", espace en bord) ou si Psych
276
+ ## lui attribuerait un type implicite différent de String.
275
277
  ##============================================================##
276
278
  def format_scalar_value(value)
277
279
  value = value.to_s
@@ -297,7 +299,8 @@ module ImmosquareYaml
297
299
  value.end_with?(":") ||
298
300
  RESERVED_KEYS.include?(value) ||
299
301
  value.start_with?(SPACE) ||
300
- value.end_with?(SPACE)
302
+ value.end_with?(SPACE) ||
303
+ psych_implicitly_types?(value)
301
304
 
302
305
  return value if !need_quotes
303
306
 
@@ -317,6 +320,15 @@ module ImmosquareYaml
317
320
  end
318
321
  end
319
322
 
323
+ ##============================================================##
324
+ ## Détecte les scalaires plain que Psych convertirait en nombre,
325
+ ## valeur nulle, date ou heure lors du chargement YAML.
326
+ ##============================================================##
327
+ def psych_implicitly_types?(value)
328
+ scanner = Psych::ScalarScanner.new(Psych::ClassLoader.new, :parse_symbols => false)
329
+ !scanner.tokenize(value).is_a?(String)
330
+ end
331
+
320
332
  ##============================================================##
321
333
  ## Échappe une string pour la sérialiser en YAML double-quoted.
322
334
  ## On gère \, ", \t et \n. Les newlines réels n'arrivent pas
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: immosquare-yaml
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - immosquare
@@ -39,6 +39,7 @@ extensions: []
39
39
  extra_rdoc_files: []
40
40
  files:
41
41
  - lib/immosquare-yaml.rb
42
+ - lib/immosquare-yaml/delete.rb
42
43
  - lib/immosquare-yaml/flatten.rb
43
44
  - lib/immosquare-yaml/shared_methods.rb
44
45
  - lib/immosquare-yaml/version.rb
@@ -60,7 +61,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
60
61
  - !ruby/object:Gem::Version
61
62
  version: '0'
62
63
  requirements: []
63
- rubygems_version: 4.0.11
64
+ rubygems_version: 4.0.20
64
65
  specification_version: 4
65
66
  summary: A YAML parser optimized for translation files.
66
67
  test_files: []