i18n-tasks 0.2.22 → 0.3.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/CHANGES.md +5 -1
- data/Gemfile +0 -1
- data/README.md +59 -49
- data/bin/i18n-tasks +38 -0
- data/i18n-tasks.gemspec +1 -0
- data/lib/i18n/tasks/commands.rb +121 -0
- data/lib/i18n/tasks/commands_base.rb +54 -0
- data/lib/i18n/tasks/configuration.rb +39 -1
- data/lib/i18n/tasks/data/storage/file_storage.rb +1 -1
- data/lib/i18n/tasks/data_traversal.rb +6 -7
- data/lib/i18n/tasks/fill_tasks.rb +20 -48
- data/lib/i18n/tasks/google_translation.rb +1 -1
- data/lib/i18n/tasks/key.rb +11 -26
- data/lib/i18n/tasks/key/key_group.rb +44 -0
- data/lib/i18n/tasks/key/match_pattern.rb +23 -0
- data/lib/i18n/tasks/key/usages.rb +11 -0
- data/lib/i18n/tasks/key_pattern_matching.rb +6 -2
- data/lib/i18n/tasks/missing_keys.rb +15 -12
- data/lib/i18n/tasks/plural_keys.rb +3 -3
- data/lib/i18n/tasks/reports/base.rb +3 -2
- data/lib/i18n/tasks/reports/spreadsheet.rb +2 -1
- data/lib/i18n/tasks/reports/terminal.rb +6 -6
- data/lib/i18n/tasks/scanners/base_scanner.rb +20 -14
- data/lib/i18n/tasks/scanners/pattern_scanner.rb +31 -5
- data/lib/i18n/tasks/scanners/pattern_with_scope_scanner.rb +75 -0
- data/lib/i18n/tasks/translation_data.rb +32 -11
- data/lib/i18n/tasks/unused_keys.rb +3 -2
- data/lib/i18n/tasks/used_keys.rb +14 -11
- data/lib/i18n/tasks/version.rb +1 -1
- data/lib/tasks/i18n-tasks.rake +34 -85
- data/spec/fixtures/app/controllers/events_controller.rb +23 -3
- data/spec/fixtures/app/views/index.html.slim +4 -1
- data/spec/fixtures/app/views/usages.html.slim +2 -0
- data/spec/fixtures/config/i18n-tasks.yml +1 -1
- data/spec/i18n_tasks_spec.rb +66 -38
- data/spec/pattern_scanner_spec.rb +1 -1
- data/spec/spec_helper.rb +2 -1
- data/spec/support/capture_std.rb +17 -0
- data/spec/support/fixtures.rb +9 -2
- data/spec/support/test_codebase.rb +5 -18
- data/spec/support/test_codebase_env.rake +4 -2
- data/spec/used_keys_spec.rb +1 -0
- metadata +31 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 79c771676a7ab2418350137799e74f5cfe9a84c9
|
4
|
+
data.tar.gz: fa7170a9f5aa0f0a557b87499c48a393ebf47a81
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b9af27eac0d3d7e2c68154a5b21f9b1aa3bd1d29940cceced793c57fe0263346cb20c5e3a9f5faf2ecb0bc8160e561b7b566e40b5634e934782b973c4bfb451d
|
7
|
+
data.tar.gz: 133cf042e3d976e3e6fc8a670428c2b91743e0abfba53c58bdf5d67e6c8511b61bd97ae5c5ca5d231e81cb5a6db536e01e7ca017d8e8f4343f90d682bad8fb62
|
data/CHANGES.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -7,83 +7,101 @@ Tasks to manage translations in ruby applications using I18n.
|
|
7
7
|
|
8
8
|
## Installation
|
9
9
|
|
10
|
-
|
10
|
+
1. Add to Gemfile:
|
11
11
|
|
12
12
|
```ruby
|
13
|
-
gem 'i18n-tasks', '~> 0.
|
13
|
+
gem 'i18n-tasks', '~> 0.3.0'
|
14
14
|
```
|
15
15
|
|
16
|
-
|
16
|
+
2. Create a config file at `config/i18n-tasks.yml`:
|
17
17
|
|
18
|
-
```
|
19
|
-
#
|
20
|
-
|
18
|
+
```yaml
|
19
|
+
# config/i18n-tasks.yml
|
20
|
+
base_locale: en
|
21
|
+
locales: [es, fr]
|
21
22
|
```
|
22
23
|
|
23
24
|
## Usage
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
There are reports for missing and unused translations:
|
26
|
+
Run `i18n-tasks` to get the list of tasks with short descriptions.
|
28
27
|
|
29
28
|
```bash
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
29
|
+
$ i18n-tasks
|
30
|
+
Usage: i18n-tasks [command] [options]
|
31
|
+
-v, --version Print the version
|
32
|
+
-h, --help Display this help message.
|
33
|
+
|
34
|
+
Available commands:
|
35
|
+
|
36
|
+
missing show missing translations
|
37
|
+
unused show unused translations
|
38
|
+
translate-missing translate missing keys with Google Translate
|
39
|
+
add-missing add missing keys to the locales
|
40
|
+
find show where the keys are used in the code
|
41
|
+
normalize normalize translation data: sort and move to the right files
|
42
|
+
remove-unused remove unused keys
|
43
|
+
config display i18n-tasks configuration
|
44
|
+
xlsx-report save missing and unused translations to an Excel file
|
45
|
+
|
46
|
+
See `<command> --help` for more information on a specific command.
|
38
47
|
```
|
39
48
|
|
49
|
+
There are reports for missing and unused translations.
|
40
50
|
i18n-tasks can add missing keys to the locale data, and it can also fill untranslated values.
|
41
51
|
|
42
|
-
|
52
|
+
|
53
|
+
Whenever you can pass locales as arguments, you can use special values `base` and `all`.
|
54
|
+
Add placeholders for missing keys to the base locale only:
|
43
55
|
|
44
56
|
```bash
|
45
|
-
|
46
|
-
# values set to to the optional [argument] or key.humanize
|
47
|
-
rake i18n:add_missing
|
57
|
+
i18n-tasks add-missing[base]
|
48
58
|
```
|
49
59
|
|
50
60
|
Prefill empty translations using Google Translate ([more below on the API key](#translation-config)).
|
51
61
|
|
52
62
|
```bash
|
53
|
-
|
63
|
+
i18n-tasks translate-missing
|
54
64
|
# this task and the ones below can also accept specific locales:
|
55
|
-
|
65
|
+
i18n-tasks translate-missing -l es,de
|
56
66
|
```
|
57
67
|
|
58
|
-
|
68
|
+
Sort the keys and write them to their respective files:
|
69
|
+
|
59
70
|
```bash
|
60
|
-
|
71
|
+
# always happens on add-missing or translate-missing
|
72
|
+
i18n-tasks normalize
|
61
73
|
```
|
62
74
|
|
63
|
-
|
75
|
+
Unused report will detect pattern translations and not report them, e.g.:
|
64
76
|
|
65
|
-
```
|
66
|
-
#
|
67
|
-
|
77
|
+
```ruby
|
78
|
+
t 'category.' + category.key # all 'category.*' keys are considered used
|
79
|
+
t "category.#{category.key}.name" # all 'category.*.name' keys are considered used
|
68
80
|
```
|
69
81
|
|
82
|
+
Relative keys (`t '.title'`) and plural keys (key.one/many/other/etc) are fully supported.
|
70
83
|
|
71
|
-
|
84
|
+
Scope argument is supported, but only when it is the first keyword argument ([this](/lib/i18n/tasks/scanners/pattern_with_scope_scanner.rb) can be improved):
|
72
85
|
|
73
86
|
```ruby
|
74
|
-
|
75
|
-
t
|
87
|
+
# this is supported
|
88
|
+
t :invalid, scope: [:auth, :password], attempts: 5
|
89
|
+
# but not this
|
90
|
+
t :invalid, attempts: 5, scope: [:auth, :password]
|
76
91
|
```
|
77
92
|
|
78
|
-
Relative keys (`t '.title'`) and plural keys (key.one/many/other/etc) are fully supported.
|
79
|
-
|
80
93
|
Translation data storage, key usage search, and other [settings](#configuration) are compatible with Rails by default.
|
81
94
|
|
82
95
|
## Configuration
|
83
96
|
|
84
97
|
Configuration is read from `config/i18n-tasks.yml` or `config/i18n-tasks.yml.erb`.
|
98
|
+
See current configuration with `i18n-tasks config`.
|
85
99
|
|
86
|
-
|
100
|
+
### Locales
|
101
|
+
|
102
|
+
By default, `i18n-tasks` will read `I18n.default_locale` and `I18n.available_locales`.
|
103
|
+
However, i18n-tasks does not load application environment by default,
|
104
|
+
so it is recommended to set locale settings explicitly:
|
87
105
|
|
88
106
|
```yaml
|
89
107
|
# config/i18n-tasks.yml
|
@@ -91,13 +109,6 @@ base_locale: en
|
|
91
109
|
locales: [es, fr]
|
92
110
|
```
|
93
111
|
|
94
|
-
On Rails, if locales are set in the config file, you can make i18n tasks a lot faster by adding this to `Rakefile`:
|
95
|
-
|
96
|
-
```ruby
|
97
|
-
# disable loading :environment for i18n-tasks
|
98
|
-
Rake::Task['i18n:setup'].clear_prerequisites
|
99
|
-
```
|
100
|
-
|
101
112
|
### Storage
|
102
113
|
|
103
114
|
```yaml
|
@@ -143,14 +154,13 @@ data:
|
|
143
154
|
Inspect all the usages with:
|
144
155
|
|
145
156
|
```bash
|
146
|
-
|
157
|
+
i18n-tasks find
|
147
158
|
# Filter by a key pattern
|
148
|
-
|
149
|
-
|
150
|
-
rake i18n:usages['{number+currency}.format.*']
|
159
|
+
i18n-tasks find 'auth.*
|
160
|
+
i18n-tasks find '{number,currency}.format.*'
|
151
161
|
```
|
152
162
|
|
153
|
-

|
154
164
|
|
155
165
|
|
156
166
|
Configure usage search in `config/i18n-tasks.yml`:
|
@@ -222,7 +232,7 @@ ignore:
|
|
222
232
|
<a name="translation-config"></a>
|
223
233
|
### Google Translate
|
224
234
|
|
225
|
-
`
|
235
|
+
`i18n-tasks translate-missing` requires a Google Translate API key, get it at [Google API Console](https://code.google.com/apis/console).
|
226
236
|
Put the key in `GOOGLE_TRANSLATE_API_KEY` environment variable or in the config file.
|
227
237
|
|
228
238
|
```yaml
|
@@ -260,7 +270,7 @@ end
|
|
260
270
|
Export missing and unused data to XLSX:
|
261
271
|
|
262
272
|
```bash
|
263
|
-
|
273
|
+
i18n-tasks xlsx-report
|
264
274
|
```
|
265
275
|
|
266
276
|
|
data/bin/i18n-tasks
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'i18n/tasks'
|
4
|
+
require 'i18n/tasks/commands'
|
5
|
+
require 'slop'
|
6
|
+
|
7
|
+
command = nil
|
8
|
+
slop = Slop.parse(help: true) do
|
9
|
+
on('-v', '--version', 'Print the version') {
|
10
|
+
puts I18n::Tasks::VERSION
|
11
|
+
exit
|
12
|
+
}
|
13
|
+
::I18n::Tasks::Commands.cmds.each do |name, attr|
|
14
|
+
command name.tr('_', '-') do
|
15
|
+
description attr.desc if attr.desc
|
16
|
+
instance_exec(&attr.opts) if attr.opts
|
17
|
+
run do |opts, args|
|
18
|
+
command = [name, opts, args]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
if command
|
25
|
+
cmd = ::I18n::Tasks::Commands.new
|
26
|
+
meth = command[0]
|
27
|
+
if cmd.method(meth).arity == 0
|
28
|
+
cmd.send meth
|
29
|
+
else
|
30
|
+
opt = command[1].to_hash.merge(arguments: command[2])
|
31
|
+
STDERR.puts Term::ANSIColor.green "i18n-tasks: #{meth.tr('_', '-')} #{opt.reject { |k, v| v.blank? }.map { |k, v| "#{k}=#{v}" } * ' '}"
|
32
|
+
cmd.send meth, opt
|
33
|
+
end
|
34
|
+
else
|
35
|
+
STDERR.puts Term::ANSIColor.red "Command unknown: #{ARGV[0]}" if ARGV[0]
|
36
|
+
puts slop.help
|
37
|
+
exit 64
|
38
|
+
end
|
data/i18n-tasks.gemspec
CHANGED
@@ -31,6 +31,7 @@ Gem::Specification.new do |s|
|
|
31
31
|
s.add_dependency 'term-ansicolor'
|
32
32
|
s.add_dependency 'terminal-table'
|
33
33
|
s.add_dependency 'highline'
|
34
|
+
s.add_dependency 'slop', '>= 3.4.7'
|
34
35
|
s.add_development_dependency 'axlsx', '~> 2.0'
|
35
36
|
s.add_development_dependency 'bundler', '~> 1.3'
|
36
37
|
s.add_development_dependency 'rake'
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'i18n/tasks/commands_base'
|
2
|
+
require 'i18n/tasks/reports/terminal'
|
3
|
+
require 'i18n/tasks/reports/spreadsheet'
|
4
|
+
|
5
|
+
module I18n::Tasks
|
6
|
+
class Commands < CommandsBase
|
7
|
+
include Term::ANSIColor
|
8
|
+
require 'highline/import'
|
9
|
+
|
10
|
+
desc 'show missing translations'
|
11
|
+
opts do
|
12
|
+
on '-l', :locales=, 'Filter by locale', as: Array, delimiter: /[+:,]/, default: 'all'
|
13
|
+
on '-t', :types, 'Filter by type (types: missing_from_base, eq_base, missing_from_locale)', as: Array, delimiter: /[+:,]/
|
14
|
+
end
|
15
|
+
cmd :missing do |opt = {}|
|
16
|
+
opt[:locales] = locales_opt(opt[:locales])
|
17
|
+
terminal_report.missing_keys i18n_task.missing_keys(opt)
|
18
|
+
end
|
19
|
+
|
20
|
+
desc 'show unused translations'
|
21
|
+
cmd :unused do
|
22
|
+
terminal_report.unused_keys
|
23
|
+
end
|
24
|
+
|
25
|
+
desc 'translate missing keys with Google Translate'
|
26
|
+
opts do
|
27
|
+
on '-l', :locales, 'Only specified locales', as: Array, delimiter: /[+:,]/
|
28
|
+
on '-f', :from, 'Locale to translate from (default: base)', default: 'base'
|
29
|
+
end
|
30
|
+
cmd :translate_missing do |opt = {}|
|
31
|
+
opt[:from] = base_locale if opt[:from].blank? || opt[:from] == 'base'
|
32
|
+
opt[:locales] = locales_opt(opt[:locale] || opt[:locales])
|
33
|
+
i18n_task.fill_missing_google_translate opt
|
34
|
+
end
|
35
|
+
|
36
|
+
desc 'add missing keys to the locales'
|
37
|
+
opts do
|
38
|
+
on '-p', :placeholder, 'Value for empty keys (default: base value or key.humanize)'
|
39
|
+
on '-l', :locales, 'Only for specified locales', as: Array, delimiter: /[+:,]/
|
40
|
+
end
|
41
|
+
cmd :add_missing do |opt = {}|
|
42
|
+
opt[:locales] = locales_opt(opt[:locale] || opt[:locales])
|
43
|
+
opt[:value] ||= opt.delete(:placeholder)
|
44
|
+
opt[:value] ||= proc { |key, locale|
|
45
|
+
# default to base value or key.humanize
|
46
|
+
locale == base_locale && t(locale, base_locale) || key.split('.').last.to_s.humanize
|
47
|
+
}
|
48
|
+
i18n_task.fill_missing_value opt
|
49
|
+
end
|
50
|
+
|
51
|
+
desc 'show where the keys are used in the code'
|
52
|
+
opts do
|
53
|
+
on '-p', :pattern, 'Show only keys matching pattern', argument: true, optional: false
|
54
|
+
end
|
55
|
+
cmd :find do |opt = {}|
|
56
|
+
opt[:filter] ||= opt.delete(:pattern) || opt[:arguments].try(:first)
|
57
|
+
filter = opt[:filter].is_a?(String) ? opt[:filter].tr('+', ',') : nil
|
58
|
+
used_keys = i18n_task.scanner.with_key_filter(filter) {
|
59
|
+
i18n_task.used_keys true
|
60
|
+
}
|
61
|
+
terminal_report.used_keys used_keys
|
62
|
+
end
|
63
|
+
|
64
|
+
desc 'normalize translation data: sort and move to the right files'
|
65
|
+
opts do
|
66
|
+
on '-l', :locales=, 'Only for specified locales', as: Array, delimiter: /[+:,]/
|
67
|
+
end
|
68
|
+
cmd :normalize do |opt = {}|
|
69
|
+
i18n_task.normalize_store! locales_opt(opt[:locales])
|
70
|
+
end
|
71
|
+
|
72
|
+
desc 'remove unused keys'
|
73
|
+
opts do
|
74
|
+
on '-l', :locales=, 'Only for specified locales', as: Array, delimiter: /[+:,]/
|
75
|
+
end
|
76
|
+
cmd :remove_unused do |opt = {}|
|
77
|
+
locales = locales_opt opt[:locales]
|
78
|
+
unused_keys = i18n_task.unused_keys
|
79
|
+
if unused_keys.present?
|
80
|
+
terminal_report.unused_keys(unused_keys)
|
81
|
+
unless ENV['CONFIRM']
|
82
|
+
exit 1 unless agree(red "All these translations will be removed in #{bold locales * ', '}#{red '.'} " + yellow('Continue? (yes/no)') + ' ')
|
83
|
+
end
|
84
|
+
i18n_task.remove_unused!(locales)
|
85
|
+
$stderr.puts "Removed #{unused_keys.size} keys"
|
86
|
+
else
|
87
|
+
$stderr.puts bold green 'No unused keys to remove'
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
desc 'display i18n-tasks configuration'
|
92
|
+
cmd :config do
|
93
|
+
puts i18n_task.config_for_inspect.to_yaml.sub(/\A---\n/, '').gsub('!ruby/hash:ActiveSupport::HashWithIndifferentAccess', '')
|
94
|
+
end
|
95
|
+
|
96
|
+
desc 'save missing and unused translations to an Excel file'
|
97
|
+
opts do
|
98
|
+
on :path, 'Destination path', default: 'tmp/i18n-report.xlsx'
|
99
|
+
end
|
100
|
+
cmd :xlsx_report do |opt = {}|
|
101
|
+
begin
|
102
|
+
require 'axlsx'
|
103
|
+
rescue LoadError
|
104
|
+
message = %Q(For spreadsheet report please add axlsx gem to Gemfile:\ngem 'axlsx', '~> 2.0')
|
105
|
+
STDERR.puts Term::ANSIColor.red Term::ANSIColor.bold message
|
106
|
+
exit 1
|
107
|
+
end
|
108
|
+
spreadsheet_report.save_report opt[:path]
|
109
|
+
end
|
110
|
+
|
111
|
+
protected
|
112
|
+
|
113
|
+
def terminal_report
|
114
|
+
@terminal_report ||= I18n::Tasks::Reports::Terminal.new(i18n_task)
|
115
|
+
end
|
116
|
+
|
117
|
+
def spreadsheet_report
|
118
|
+
@spreadsheet_report ||= I18n::Tasks::Reports::Spreadsheet.new(i18n_task)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
module I18n::Tasks
|
3
|
+
class CommandsBase
|
4
|
+
def locales_opt(value, default = nil)
|
5
|
+
if value.is_a?(String)
|
6
|
+
value = value.strip.split(/\s*\+\s*/).compact.presence
|
7
|
+
end
|
8
|
+
return i18n_task.locales if value == ['all']
|
9
|
+
if value.present?
|
10
|
+
value = value.map { |v| v == 'base' ? base_locale : v }
|
11
|
+
value
|
12
|
+
else
|
13
|
+
default || i18n_task.locales
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class << self
|
18
|
+
def cmds
|
19
|
+
@cmds ||= {}.with_indifferent_access
|
20
|
+
end
|
21
|
+
|
22
|
+
def cmd(name, &block)
|
23
|
+
cmds[name] = OpenStruct.new(@next_def)
|
24
|
+
@next_def = {}
|
25
|
+
define_method(name, &block)
|
26
|
+
end
|
27
|
+
|
28
|
+
def desc(text)
|
29
|
+
next_def[:desc] = text
|
30
|
+
end
|
31
|
+
|
32
|
+
def opts(&block)
|
33
|
+
next_def[:opts] = block
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
def next_def
|
38
|
+
@next_def ||= {}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def desc(name)
|
43
|
+
self.class.cmds.try(:[], name).try(:desc)
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
|
48
|
+
def i18n_task
|
49
|
+
@i18n_task ||= I18n::Tasks::BaseTask.new
|
50
|
+
end
|
51
|
+
|
52
|
+
delegate :base_locale, :t, to: :i18n_task
|
53
|
+
end
|
54
|
+
end
|
@@ -33,8 +33,46 @@ module I18n::Tasks::Configuration
|
|
33
33
|
def translation_config
|
34
34
|
@config_sections[:translation] ||= begin
|
35
35
|
conf = (config[:translation] || {}).with_indifferent_access
|
36
|
-
conf[:api_key] ||= ENV['GOOGLE_TRANSLATE_API_KEY']
|
36
|
+
conf[:api_key] ||= ENV['GOOGLE_TRANSLATE_API_KEY'] if ENV.key?('GOOGLE_TRANSLATE_API_KEY')
|
37
37
|
conf
|
38
38
|
end
|
39
39
|
end
|
40
|
+
|
41
|
+
def search_config
|
42
|
+
@config_sections[:search] ||= {
|
43
|
+
scanner: scanner.class.name,
|
44
|
+
config: scanner.config
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [Array<String>] all available locales
|
49
|
+
def locales
|
50
|
+
@config_sections[:locales] ||= begin
|
51
|
+
locales = (config[:locales] || I18n.available_locales).map(&:to_s)
|
52
|
+
locales = [base_locale] + locales unless locales.include?(base_locale)
|
53
|
+
locales
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return [String] default i18n locale
|
58
|
+
def base_locale
|
59
|
+
@config_sections[:base_locale] ||= config[:base_locale] || I18n.default_locale.to_s
|
60
|
+
end
|
61
|
+
|
62
|
+
# evaluated configuration (as the app sees it)
|
63
|
+
def config_sections
|
64
|
+
# init all sections
|
65
|
+
base_locale
|
66
|
+
locales
|
67
|
+
data_config
|
68
|
+
search_config
|
69
|
+
relative_roots
|
70
|
+
translation_config
|
71
|
+
@config_sections
|
72
|
+
end
|
73
|
+
|
74
|
+
def config_for_inspect
|
75
|
+
# hide empty sections, stringify keys
|
76
|
+
Hash[config_sections.reject { |k, v| v.empty? }.map { |k, v| [k.to_s, v.respond_to?(:stringify_keys) ? v.stringify_keys : v] }]
|
77
|
+
end
|
40
78
|
end
|