immosquare-yaml 1.0.1 → 1.0.2

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: b52683e890b1d956eae3105cea9e41abf49ddd14d549fb76a4490f8f851d0855
4
- data.tar.gz: fb4b1fe155dd11b4a13c7b4dcd88e91839a1b9d9af8e5aeb2205ffa86c925f6c
3
+ metadata.gz: a2841e06b484ab63541fde122db5b67873fed11ace07d10423eae10ac4eb32b0
4
+ data.tar.gz: ca15c7313768d2c70597370cf4121becd73d4afd32b70735d80572c66daabbbb
5
5
  SHA512:
6
- metadata.gz: eee507c91cb95ac3ff5e87f15570f664622c0be05f449bad60823687e3f7cd71e54b9aef52a74b6799e04a7fdc8a4b855e3f217cbc6fef20861898c957433374
7
- data.tar.gz: 7f05834fc1b5e22c25d021b7eed1f6b77e3575a6a86d3c2794cf2c1b8bc0e193443b50c770acf0af5f5deb1dbc9001574242272d0b5065476dd42978daca56a4
6
+ metadata.gz: 89eafa27859e41e9a61ae861b746157dc010af7a29ecaffa8a42f0fc612d30c4637eea21aadad5293abafe670b5c5b317b861902fb7c2e8cbb858d40074fe5a8
7
+ data.tar.gz: 48b27854d7f28c95f98a4f5bdbe04674a08407699c4ae27f5623571ec1a98fb8751e70fba844bf1dfe3f423bd9fae16a30b497233cc0536f8ef965e3a91f40e9
@@ -0,0 +1,152 @@
1
+ module ImmosquareYaml
2
+ ##============================================================##
3
+ ## Flatten — turns one (or several) i18n YAML file(s), or a hash
4
+ ## already in memory, into a list of dot-separated paths pointing
5
+ ## to leaf values.
6
+ ##
7
+ ## Segments matching RESERVED_KEYS (yes/no/true/false/...) or
8
+ ## purely numeric segments are quoted ("true", "42") so they stay
9
+ ## compatible with I18n.t, which would otherwise interpret them
10
+ ## as booleans / integers.
11
+ ##
12
+ ## Array and nil values are treated as leaves (no descent).
13
+ ## Empty Hashes are skipped (no leaf emitted).
14
+ ##============================================================##
15
+ class << self
16
+
17
+ ##============================================================##
18
+ ## flatten_keys(input, with_values: false, with_file: false)
19
+ ##
20
+ ## input :
21
+ ## - Hash : flattened in memory (no I/O). File
22
+ ## column is nil in the resulting tuples.
23
+ ## - String : a single YAML file path.
24
+ ## - Array<String> : a list of YAML file paths.
25
+ ##
26
+ ## Globs are NOT expanded — the caller is expected to expand
27
+ ## them upstream (e.g. with Dir.glob) and pass an Array<String>.
28
+ ## Mixing a Hash with file paths in the same Array is not
29
+ ## supported.
30
+ ##
31
+ ## No option → Array<String> sorted + deduplicated
32
+ ## with_values: true → Array<[path, value]> not deduplicated
33
+ ## with_file: true → adds the source file_path to each entry
34
+ ## (nil for Hash inputs)
35
+ ##
36
+ ## Missing / empty / unreadable file: silently ignored.
37
+ ##============================================================##
38
+ def flatten_keys(input, **options)
39
+ options = {
40
+ :with_values => false,
41
+ :with_file => false
42
+ }.merge(options)
43
+
44
+ entries = []
45
+
46
+ if input.is_a?(Hash)
47
+ flatten_hash(input, [], entries, nil) if !input.empty?
48
+ else
49
+ paths = input.is_a?(Array) ? input : [input]
50
+ paths.each do |path|
51
+ path = path.to_s
52
+ next if path.empty? || !File.exist?(path)
53
+
54
+ parsed = parse(path, :sort => false)
55
+ next if parsed == false || !parsed.is_a?(Hash) || parsed.empty?
56
+
57
+ flatten_hash(parsed, [], entries, path)
58
+ end
59
+ end
60
+
61
+ format_entries(entries, options)
62
+ end
63
+
64
+ ##============================================================##
65
+ ## parse_path(dot_path) → Array<String>
66
+ ##
67
+ ## Symmetric inverse of the quoting done by flatten_keys: splits
68
+ ## on "." and strips wrapping quotes from reserved or numeric
69
+ ## segments. The result can be passed directly to Hash#dig on a
70
+ ## hash returned by ImmosquareYaml.parse.
71
+ ##
72
+ ## Limitation : keys containing a literal "." in their name are
73
+ ## not supported (the path would be split into two segments).
74
+ ##
75
+ ## Examples :
76
+ ## parse_path("fr.statuses.\"yes\"") # => ["fr", "statuses", "yes"]
77
+ ## parse_path("fr.counts.\"42\"") # => ["fr", "counts", "42"]
78
+ ## parse_path("fr.app.title") # => ["fr", "app", "title"]
79
+ ##============================================================##
80
+ def parse_path(dot_path)
81
+ dot_path.to_s.split(".").map {|segment| unquote_segment(segment) }
82
+ end
83
+
84
+
85
+ private
86
+
87
+
88
+ ##============================================================##
89
+ ## Recursive walk over the hash. Array and nil are treated as
90
+ ## leaves. Empty Hashes are skipped. Entries are accumulated as
91
+ ## [path, value, file].
92
+ ##============================================================##
93
+ def flatten_hash(node, segments, entries, file_path)
94
+ if node.is_a?(Hash)
95
+ return if node.empty?
96
+
97
+ node.each do |key, value|
98
+ flatten_hash(value, segments + [quote_segment(key.to_s)], entries, file_path)
99
+ end
100
+ else
101
+ entries << [segments.join("."), node, file_path]
102
+ end
103
+ end
104
+
105
+ ##============================================================##
106
+ ## Quotes a path segment if it matches RESERVED_KEYS or if it
107
+ ## is purely numeric (consistent with clean_key in the dump).
108
+ ##============================================================##
109
+ def quote_segment(segment)
110
+ if SharedMethods::RESERVED_KEYS.include?(segment) || segment.match?(/\A[-+]?\d+\z/)
111
+ "\"#{segment}\""
112
+ else
113
+ segment
114
+ end
115
+ end
116
+
117
+ ##============================================================##
118
+ ## Inverse of quote_segment: strips wrapping quotes when the
119
+ ## segment is enclosed in " ... ". Other segments are returned
120
+ ## unchanged.
121
+ ##============================================================##
122
+ def unquote_segment(segment)
123
+ if segment.start_with?("\"") && segment.end_with?("\"") && segment.length >= 2
124
+ segment[1..-2]
125
+ else
126
+ segment
127
+ end
128
+ end
129
+
130
+ ##============================================================##
131
+ ## Formats the output according to the options. Without
132
+ ## with_values, paths are deduplicated (useful when flattening
133
+ ## multiple locales sharing the same key). Otherwise, all
134
+ ## entries are kept.
135
+ ##============================================================##
136
+ def format_entries(entries, options)
137
+ if options[:with_values] && options[:with_file]
138
+ entries.sort_by {|path, _value, file| [path, file.to_s] }
139
+ elsif options[:with_values]
140
+ entries.sort_by {|path, _value, file| [path, file.to_s] }
141
+ .map {|path, value, _file| [path, value] }
142
+ elsif options[:with_file]
143
+ entries.map {|path, _value, file| [path, file] }
144
+ .uniq
145
+ .sort_by {|path, file| [path, file.to_s] }
146
+ else
147
+ entries.map(&:first).uniq.sort
148
+ end
149
+ end
150
+
151
+ end
152
+ end
@@ -1,3 +1,3 @@
1
1
  module ImmosquareYaml
2
- VERSION = "1.0.1".freeze
2
+ VERSION = "1.0.2".freeze
3
3
  end
@@ -1,9 +1,8 @@
1
1
  require "psych"
2
2
  require "fileutils"
3
3
  require "immosquare-extensions"
4
- require_relative "immosquare-yaml/configuration"
5
4
  require_relative "immosquare-yaml/shared_methods"
6
- require_relative "immosquare-yaml/railtie" if defined?(Rails)
5
+ require_relative "immosquare-yaml/flatten"
7
6
 
8
7
  ##============================================================##
9
8
  ## ImmosquareYaml — post-processeur Psych dédié aux fichiers
@@ -27,16 +26,6 @@ module ImmosquareYaml
27
26
 
28
27
  class << self
29
28
 
30
- attr_writer :configuration
31
-
32
- def configuration
33
- @configuration ||= Configuration.new
34
- end
35
-
36
- def config
37
- yield(configuration)
38
- end
39
-
40
29
  ##============================================================##
41
30
  ## clean(file_path, sort: true, output: file_path)
42
31
  ## Charge le fichier, le re-écrit propre et trié.
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.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - immosquare
@@ -39,11 +39,9 @@ extensions: []
39
39
  extra_rdoc_files: []
40
40
  files:
41
41
  - lib/immosquare-yaml.rb
42
- - lib/immosquare-yaml/configuration.rb
43
- - lib/immosquare-yaml/railtie.rb
42
+ - lib/immosquare-yaml/flatten.rb
44
43
  - lib/immosquare-yaml/shared_methods.rb
45
44
  - lib/immosquare-yaml/version.rb
46
- - lib/tasks/immosquare-yaml.rake
47
45
  homepage: https://github.com/immosquare/immosquare-yaml
48
46
  licenses:
49
47
  - MIT
@@ -1,12 +0,0 @@
1
- module ImmosquareYaml
2
- class Configuration
3
-
4
- attr_accessor :openai_api_key, :openai_model
5
-
6
- def initialize
7
- @openai_api_key = nil
8
- @openai_model = nil
9
- end
10
-
11
- end
12
- end
@@ -1,9 +0,0 @@
1
- module ImmosquareYaml
2
- class Railtie < Rails::Railtie
3
-
4
- rake_tasks do
5
- load "tasks/immosquare-yaml.rake"
6
- end
7
-
8
- end
9
- end
@@ -1,11 +0,0 @@
1
- namespace :immosquare_yaml do
2
- ##============================================================##
3
- ## Function to clean translation files in rails app
4
- ##============================================================##
5
- desc "Clean translation files in rails app"
6
- task :clean => :environment do
7
- Dir.glob("#{Rails.root}/config/locales/**/*.yml").each do |file|
8
- ImmosquareYaml.clean(file)
9
- end
10
- end
11
- end