better_translate 1.0.0.1 → 1.1.0
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/.rubocop.yml +28 -0
- data/.rubocop_todo.yml +291 -0
- data/CHANGELOG.md +88 -0
- data/README.md +234 -1
- data/lib/better_translate/analyzer/code_scanner.rb +151 -0
- data/lib/better_translate/analyzer/key_scanner.rb +109 -0
- data/lib/better_translate/analyzer/orphan_detector.rb +88 -0
- data/lib/better_translate/analyzer/reporter.rb +155 -0
- data/lib/better_translate/cli.rb +79 -0
- data/lib/better_translate/configuration.rb +48 -2
- data/lib/better_translate/errors.rb +9 -0
- data/lib/better_translate/json_handler.rb +227 -0
- data/lib/better_translate/translator.rb +204 -23
- data/lib/better_translate/version.rb +1 -1
- data/lib/better_translate/yaml_handler.rb +59 -0
- data/lib/better_translate.rb +5 -0
- data/sig/better_translate/configuration.rbs +6 -0
- data/sig/better_translate/errors.rbs +4 -0
- data/sig/better_translate/translator.rbs +12 -1
- data/sig/better_translate/yaml_handler.rbs +6 -0
- metadata +7 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 80868b0f529d5c8310efabe07a402bd89d015e6bced86a3c0e2689e288d702f6
|
|
4
|
+
data.tar.gz: fdaede4b54e2c956d3f2cc936f221a83703a2001e1d647fec3abe2283d11e157
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 90a863900c1e132d7be3bf96a80a66cfad9580e38d7c634fd0e8dcea891be5768ff4cd548eadae6a74dde15a18c4f839a047e8e0653e6642272e518e6859ebac
|
|
7
|
+
data.tar.gz: 3ffb3062a2919d7296fe0ad95f28f29d5352ea3c126f12d09c89229378194a6386c4da65a7d419e7868d34d2297353a2561364600b1b5fe09d30ee9a24244408
|
data/.rubocop.yml
CHANGED
|
@@ -1,8 +1,36 @@
|
|
|
1
|
+
inherit_from: .rubocop_todo.yml
|
|
2
|
+
|
|
3
|
+
inherit_mode:
|
|
4
|
+
merge:
|
|
5
|
+
- Exclude
|
|
6
|
+
|
|
7
|
+
plugins:
|
|
8
|
+
- rubocop-rake
|
|
9
|
+
- rubocop-rspec
|
|
10
|
+
|
|
1
11
|
AllCops:
|
|
2
12
|
TargetRubyVersion: 3.0
|
|
13
|
+
NewCops: enable
|
|
3
14
|
|
|
4
15
|
Style/StringLiterals:
|
|
5
16
|
EnforcedStyle: double_quotes
|
|
6
17
|
|
|
7
18
|
Style/StringLiteralsInInterpolation:
|
|
8
19
|
EnforcedStyle: double_quotes
|
|
20
|
+
|
|
21
|
+
Metrics/BlockLength:
|
|
22
|
+
Exclude:
|
|
23
|
+
- 'spec/**/*_spec.rb'
|
|
24
|
+
- 'Rakefile'
|
|
25
|
+
- '*.gemspec'
|
|
26
|
+
|
|
27
|
+
# RSpec-specific configurations
|
|
28
|
+
RSpec/MultipleExpectations:
|
|
29
|
+
Max: 5
|
|
30
|
+
|
|
31
|
+
RSpec/ExampleLength:
|
|
32
|
+
Max: 15
|
|
33
|
+
|
|
34
|
+
RSpec/DescribeClass:
|
|
35
|
+
Exclude:
|
|
36
|
+
- 'spec/integration/**/*'
|
data/.rubocop_todo.yml
ADDED
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
# This configuration was generated by
|
|
2
|
+
# `rubocop --auto-gen-config`
|
|
3
|
+
# on 2025-10-22 20:47:42 UTC using RuboCop version 1.81.6.
|
|
4
|
+
# The point is for the user to remove these configuration records
|
|
5
|
+
# one by one as the offenses are removed from the code base.
|
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
|
8
|
+
|
|
9
|
+
# Offense count: 1
|
|
10
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
11
|
+
# Configuration parameters: Severity.
|
|
12
|
+
Gemspec/RequireMFA:
|
|
13
|
+
Exclude:
|
|
14
|
+
- 'better_translate.gemspec'
|
|
15
|
+
|
|
16
|
+
# Offense count: 4
|
|
17
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
18
|
+
Lint/AmbiguousOperatorPrecedence:
|
|
19
|
+
Exclude:
|
|
20
|
+
- 'lib/better_translate/analyzer/reporter.rb'
|
|
21
|
+
|
|
22
|
+
# Offense count: 1
|
|
23
|
+
Lint/FloatComparison:
|
|
24
|
+
Exclude:
|
|
25
|
+
- 'spec/better_translate/providers/chatgpt_provider_spec.rb'
|
|
26
|
+
|
|
27
|
+
# Offense count: 8
|
|
28
|
+
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
29
|
+
Lint/NonAtomicFileOperation:
|
|
30
|
+
Exclude:
|
|
31
|
+
- 'lib/better_translate/json_handler.rb'
|
|
32
|
+
- 'lib/better_translate/yaml_handler.rb'
|
|
33
|
+
- 'spec/better_translate/analyzer/key_scanner_spec.rb'
|
|
34
|
+
- 'spec/better_translate/analyzer/reporter_spec.rb'
|
|
35
|
+
|
|
36
|
+
# Offense count: 22
|
|
37
|
+
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
|
|
38
|
+
Metrics/AbcSize:
|
|
39
|
+
Max: 116
|
|
40
|
+
|
|
41
|
+
# Offense count: 7
|
|
42
|
+
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
|
|
43
|
+
# AllowedMethods: refine
|
|
44
|
+
Metrics/BlockLength:
|
|
45
|
+
Max: 99
|
|
46
|
+
|
|
47
|
+
# Offense count: 3
|
|
48
|
+
# Configuration parameters: CountComments, CountAsOne.
|
|
49
|
+
Metrics/ClassLength:
|
|
50
|
+
Max: 246
|
|
51
|
+
|
|
52
|
+
# Offense count: 12
|
|
53
|
+
# Configuration parameters: AllowedMethods, AllowedPatterns.
|
|
54
|
+
Metrics/CyclomaticComplexity:
|
|
55
|
+
Max: 24
|
|
56
|
+
|
|
57
|
+
# Offense count: 41
|
|
58
|
+
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
|
59
|
+
Metrics/MethodLength:
|
|
60
|
+
Max: 61
|
|
61
|
+
|
|
62
|
+
# Offense count: 1
|
|
63
|
+
# Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
|
|
64
|
+
Metrics/ParameterLists:
|
|
65
|
+
Max: 6
|
|
66
|
+
|
|
67
|
+
# Offense count: 9
|
|
68
|
+
# Configuration parameters: AllowedMethods, AllowedPatterns.
|
|
69
|
+
Metrics/PerceivedComplexity:
|
|
70
|
+
Max: 25
|
|
71
|
+
|
|
72
|
+
# Offense count: 2
|
|
73
|
+
Naming/AccessorMethodName:
|
|
74
|
+
Exclude:
|
|
75
|
+
- 'lib/better_translate/json_handler.rb'
|
|
76
|
+
- 'lib/better_translate/yaml_handler.rb'
|
|
77
|
+
|
|
78
|
+
# Offense count: 6
|
|
79
|
+
# Configuration parameters: Mode, AllowedMethods, AllowedPatterns, AllowBangMethods, WaywardPredicates.
|
|
80
|
+
# AllowedMethods: call
|
|
81
|
+
# WaywardPredicates: nonzero?
|
|
82
|
+
Naming/PredicateMethod:
|
|
83
|
+
Exclude:
|
|
84
|
+
- 'lib/better_translate/configuration.rb'
|
|
85
|
+
- 'lib/better_translate/validator.rb'
|
|
86
|
+
- 'lib/better_translate/variable_extractor.rb'
|
|
87
|
+
|
|
88
|
+
# Offense count: 30
|
|
89
|
+
RSpec/AnyInstance:
|
|
90
|
+
Exclude:
|
|
91
|
+
- 'spec/better_translate/cli_spec.rb'
|
|
92
|
+
- 'spec/better_translate/direct_translator_spec.rb'
|
|
93
|
+
- 'spec/better_translate/multiple_files_spec.rb'
|
|
94
|
+
- 'spec/better_translate/rake_tasks_spec.rb'
|
|
95
|
+
- 'spec/better_translate/translator_spec.rb'
|
|
96
|
+
- 'spec/better_translate_spec.rb'
|
|
97
|
+
- 'spec/generators/translate_generator_spec.rb'
|
|
98
|
+
|
|
99
|
+
# Offense count: 1
|
|
100
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
101
|
+
# Configuration parameters: EnforcedStyle.
|
|
102
|
+
# SupportedStyles: be, be_nil
|
|
103
|
+
RSpec/BeNil:
|
|
104
|
+
Exclude:
|
|
105
|
+
- 'spec/better_translate_spec.rb'
|
|
106
|
+
|
|
107
|
+
# Offense count: 6
|
|
108
|
+
RSpec/BeforeAfterAll:
|
|
109
|
+
Exclude:
|
|
110
|
+
- '**/spec/spec_helper.rb'
|
|
111
|
+
- '**/spec/rails_helper.rb'
|
|
112
|
+
- '**/spec/support/**/*.rb'
|
|
113
|
+
- 'spec/generators/analyze_generator_spec.rb'
|
|
114
|
+
- 'spec/generators/install_generator_spec.rb'
|
|
115
|
+
- 'spec/generators/translate_generator_spec.rb'
|
|
116
|
+
|
|
117
|
+
# Offense count: 13
|
|
118
|
+
# Configuration parameters: Prefixes, AllowedPatterns.
|
|
119
|
+
# Prefixes: when, with, without
|
|
120
|
+
RSpec/ContextWording:
|
|
121
|
+
Exclude:
|
|
122
|
+
- 'spec/better_translate/analyzer/reporter_spec.rb'
|
|
123
|
+
- 'spec/better_translate/configuration_spec.rb'
|
|
124
|
+
- 'spec/better_translate/strategies/batch_strategy_spec.rb'
|
|
125
|
+
- 'spec/better_translate/strategies/deep_strategy_spec.rb'
|
|
126
|
+
- 'spec/better_translate/strategies/strategy_selector_spec.rb'
|
|
127
|
+
|
|
128
|
+
# Offense count: 2
|
|
129
|
+
# Configuration parameters: IgnoredMetadata.
|
|
130
|
+
RSpec/DescribeClass:
|
|
131
|
+
Exclude:
|
|
132
|
+
- 'spec/integration/**/*'
|
|
133
|
+
- 'spec/better_translate/multiple_files_spec.rb'
|
|
134
|
+
- 'spec/better_translate/rake_tasks_spec.rb'
|
|
135
|
+
|
|
136
|
+
# Offense count: 1
|
|
137
|
+
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
138
|
+
# Configuration parameters: SkipBlocks, EnforcedStyle, OnlyStaticConstants.
|
|
139
|
+
# SupportedStyles: described_class, explicit
|
|
140
|
+
RSpec/DescribedClass:
|
|
141
|
+
Exclude:
|
|
142
|
+
- 'spec/better_translate/cli_spec.rb'
|
|
143
|
+
|
|
144
|
+
# Offense count: 18
|
|
145
|
+
# Configuration parameters: Max, CountAsOne.
|
|
146
|
+
RSpec/ExampleLength:
|
|
147
|
+
Exclude:
|
|
148
|
+
- 'spec/better_translate/configuration_spec.rb'
|
|
149
|
+
- 'spec/better_translate/direct_translator_spec.rb'
|
|
150
|
+
- 'spec/better_translate/providers/base_http_provider_spec.rb'
|
|
151
|
+
- 'spec/better_translate/strategies/batch_strategy_spec.rb'
|
|
152
|
+
- 'spec/better_translate/strategies/deep_strategy_spec.rb'
|
|
153
|
+
- 'spec/better_translate/translator_spec.rb'
|
|
154
|
+
- 'spec/integration/analyzer_integration_spec.rb'
|
|
155
|
+
|
|
156
|
+
# Offense count: 11
|
|
157
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
158
|
+
RSpec/LeadingSubject:
|
|
159
|
+
Exclude:
|
|
160
|
+
- 'spec/better_translate/direct_translator_spec.rb'
|
|
161
|
+
- 'spec/better_translate/json_handler_spec.rb'
|
|
162
|
+
- 'spec/better_translate/providers/anthropic_provider_spec.rb'
|
|
163
|
+
- 'spec/better_translate/providers/base_http_provider_spec.rb'
|
|
164
|
+
- 'spec/better_translate/providers/chatgpt_provider_spec.rb'
|
|
165
|
+
- 'spec/better_translate/providers/gemini_provider_spec.rb'
|
|
166
|
+
- 'spec/better_translate/strategies/base_strategy_spec.rb'
|
|
167
|
+
- 'spec/better_translate/yaml_handler_spec.rb'
|
|
168
|
+
- 'spec/integration/anthropic_integration_spec.rb'
|
|
169
|
+
- 'spec/integration/chatgpt_integration_spec.rb'
|
|
170
|
+
- 'spec/integration/gemini_integration_spec.rb'
|
|
171
|
+
|
|
172
|
+
# Offense count: 32
|
|
173
|
+
# Configuration parameters: EnforcedStyle.
|
|
174
|
+
# SupportedStyles: have_received, receive
|
|
175
|
+
RSpec/MessageSpies:
|
|
176
|
+
Exclude:
|
|
177
|
+
- 'spec/better_translate/strategies/batch_strategy_spec.rb'
|
|
178
|
+
- 'spec/better_translate/strategies/deep_strategy_spec.rb'
|
|
179
|
+
|
|
180
|
+
# Offense count: 1
|
|
181
|
+
RSpec/MultipleDescribes:
|
|
182
|
+
Exclude:
|
|
183
|
+
- 'spec/better_translate/errors_spec.rb'
|
|
184
|
+
|
|
185
|
+
# Offense count: 9
|
|
186
|
+
# Configuration parameters: Max.
|
|
187
|
+
RSpec/MultipleExpectations:
|
|
188
|
+
Exclude:
|
|
189
|
+
- 'spec/better_translate/configuration_spec.rb'
|
|
190
|
+
- 'spec/better_translate/providers/anthropic_provider_spec.rb'
|
|
191
|
+
- 'spec/better_translate/providers/chatgpt_provider_spec.rb'
|
|
192
|
+
- 'spec/better_translate/strategies/batch_strategy_spec.rb'
|
|
193
|
+
- 'spec/better_translate/strategies/deep_strategy_spec.rb'
|
|
194
|
+
- 'spec/better_translate_spec.rb'
|
|
195
|
+
- 'spec/integration/analyzer_integration_spec.rb'
|
|
196
|
+
|
|
197
|
+
# Offense count: 22
|
|
198
|
+
# Configuration parameters: AllowSubject.
|
|
199
|
+
RSpec/MultipleMemoizedHelpers:
|
|
200
|
+
Max: 6
|
|
201
|
+
|
|
202
|
+
# Offense count: 16
|
|
203
|
+
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
204
|
+
RSpec/ReceiveMessages:
|
|
205
|
+
Exclude:
|
|
206
|
+
- 'spec/better_translate/providers/base_http_provider_spec.rb'
|
|
207
|
+
|
|
208
|
+
# Offense count: 2
|
|
209
|
+
RSpec/RepeatedExample:
|
|
210
|
+
Exclude:
|
|
211
|
+
- 'spec/generators/analyze_generator_spec.rb'
|
|
212
|
+
|
|
213
|
+
# Offense count: 4
|
|
214
|
+
# Configuration parameters: CustomTransform, IgnoreMethods, IgnoreMetadata.
|
|
215
|
+
RSpec/SpecFilePathFormat:
|
|
216
|
+
Exclude:
|
|
217
|
+
- '**/spec/routing/**/*'
|
|
218
|
+
- 'spec/better_translate/providers/chatgpt_provider_spec.rb'
|
|
219
|
+
- 'spec/generators/analyze_generator_spec.rb'
|
|
220
|
+
- 'spec/generators/install_generator_spec.rb'
|
|
221
|
+
- 'spec/generators/translate_generator_spec.rb'
|
|
222
|
+
|
|
223
|
+
# Offense count: 17
|
|
224
|
+
RSpec/StubbedMock:
|
|
225
|
+
Exclude:
|
|
226
|
+
- 'spec/better_translate/strategies/batch_strategy_spec.rb'
|
|
227
|
+
- 'spec/better_translate/strategies/deep_strategy_spec.rb'
|
|
228
|
+
|
|
229
|
+
# Offense count: 4
|
|
230
|
+
RSpec/SubjectStub:
|
|
231
|
+
Exclude:
|
|
232
|
+
- 'spec/better_translate/providers/base_http_provider_spec.rb'
|
|
233
|
+
|
|
234
|
+
# Offense count: 33
|
|
235
|
+
# Configuration parameters: IgnoreNameless, IgnoreSymbolicNames.
|
|
236
|
+
RSpec/VerifiedDoubles:
|
|
237
|
+
Exclude:
|
|
238
|
+
- 'spec/better_translate/providers/anthropic_provider_spec.rb'
|
|
239
|
+
- 'spec/better_translate/providers/base_http_provider_spec.rb'
|
|
240
|
+
- 'spec/better_translate/providers/chatgpt_provider_spec.rb'
|
|
241
|
+
- 'spec/better_translate/providers/gemini_provider_spec.rb'
|
|
242
|
+
|
|
243
|
+
# Offense count: 1
|
|
244
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
245
|
+
# Configuration parameters: EnforcedStyle.
|
|
246
|
+
# SupportedStyles: trailing_conditional, ternary
|
|
247
|
+
Style/EmptyStringInsideInterpolation:
|
|
248
|
+
Exclude:
|
|
249
|
+
- 'lib/generators/better_translate/analyze/analyze_generator.rb'
|
|
250
|
+
|
|
251
|
+
# Offense count: 14
|
|
252
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
253
|
+
# Configuration parameters: AllowedVars, DefaultToNil.
|
|
254
|
+
Style/FetchEnvVar:
|
|
255
|
+
Exclude:
|
|
256
|
+
- 'lib/better_translate/cli.rb'
|
|
257
|
+
- 'lib/generators/better_translate/translate/translate_generator.rb'
|
|
258
|
+
- 'lib/tasks/better_translate.rake'
|
|
259
|
+
- 'regenerate_vcr.rb'
|
|
260
|
+
|
|
261
|
+
# Offense count: 5
|
|
262
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
263
|
+
# Configuration parameters: EnforcedStyle, MaxUnannotatedPlaceholdersAllowed, Mode, AllowedMethods, AllowedPatterns.
|
|
264
|
+
# SupportedStyles: annotated, template, unannotated
|
|
265
|
+
Style/FormatStringToken:
|
|
266
|
+
Exclude:
|
|
267
|
+
- 'lib/better_translate/progress_tracker.rb'
|
|
268
|
+
|
|
269
|
+
# Offense count: 2
|
|
270
|
+
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
271
|
+
Style/HashExcept:
|
|
272
|
+
Exclude:
|
|
273
|
+
- 'lib/better_translate/json_handler.rb'
|
|
274
|
+
- 'lib/better_translate/yaml_handler.rb'
|
|
275
|
+
|
|
276
|
+
# Offense count: 9
|
|
277
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
278
|
+
Style/IfUnlessModifier:
|
|
279
|
+
Exclude:
|
|
280
|
+
- 'lib/better_translate/configuration.rb'
|
|
281
|
+
- 'lib/better_translate/providers/anthropic_provider.rb'
|
|
282
|
+
- 'lib/better_translate/providers/chatgpt_provider.rb'
|
|
283
|
+
- 'lib/better_translate/providers/gemini_provider.rb'
|
|
284
|
+
- 'lib/better_translate/translator.rb'
|
|
285
|
+
|
|
286
|
+
# Offense count: 4
|
|
287
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
288
|
+
# Configuration parameters: AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings.
|
|
289
|
+
# URISchemes: http, https
|
|
290
|
+
Layout/LineLength:
|
|
291
|
+
Max: 181
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,94 @@ All notable changes to BetterTranslate will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.1.0] - 2025-10-22
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
#### Enhanced Configuration
|
|
13
|
+
- **Provider-Specific Options**: Fine-tune AI provider behavior
|
|
14
|
+
- `model`: Specify which AI model to use (e.g., "gpt-5-nano", "gemini-2.0-flash-exp")
|
|
15
|
+
- `temperature`: Control creativity/randomness (0.0-2.0, default: 0.3)
|
|
16
|
+
- `max_tokens`: Limit response length (default: 2000)
|
|
17
|
+
- Configurable via CLI, configuration file, or programmatically
|
|
18
|
+
|
|
19
|
+
#### Automatic Backups
|
|
20
|
+
- **Backup System**: Automatic backup creation before overwriting translation files
|
|
21
|
+
- `create_backup`: Enable/disable automatic backups (default: true)
|
|
22
|
+
- `max_backups`: Keep up to N backup files with rotation (default: 3)
|
|
23
|
+
- Backup format: `.bak`, `.bak.1`, `.bak.2`, etc.
|
|
24
|
+
- Automatic cleanup of old backups beyond `max_backups`
|
|
25
|
+
- Works with both YAML and JSON files
|
|
26
|
+
|
|
27
|
+
#### JSON File Support
|
|
28
|
+
- **JSON Handler**: Complete support for JSON translation files
|
|
29
|
+
- Read and write JSON locale files
|
|
30
|
+
- Automatic format detection based on file extension (.json vs .yml)
|
|
31
|
+
- Same feature set as YAML (incremental mode, backups, exclusions)
|
|
32
|
+
- Pretty-printed output with proper indentation
|
|
33
|
+
- Compatible with modern JavaScript frameworks (React, Vue, etc.)
|
|
34
|
+
|
|
35
|
+
#### Parallel Translation
|
|
36
|
+
- **Concurrent Processing**: Translate multiple languages simultaneously
|
|
37
|
+
- `max_concurrent_requests`: Control concurrency level (default: 3)
|
|
38
|
+
- Thread-based parallel execution for improved performance
|
|
39
|
+
- Automatic fallback to sequential processing when `max_concurrent_requests = 1`
|
|
40
|
+
- Thread-safe error handling
|
|
41
|
+
- Significant time savings for projects with many target languages
|
|
42
|
+
|
|
43
|
+
#### Multiple Files Support
|
|
44
|
+
- **Batch Translation**: Translate multiple files in a single run
|
|
45
|
+
- `input_files`: Accept array of file paths or glob patterns
|
|
46
|
+
- Glob pattern support: `config/locales/**/*.en.yml`
|
|
47
|
+
- Preserves directory structure in output
|
|
48
|
+
- Smart filename handling: `common.en.yml` → `common.it.yml`
|
|
49
|
+
- Works with both YAML and JSON files
|
|
50
|
+
- Backward compatible with single `input_file` attribute
|
|
51
|
+
|
|
52
|
+
### Examples
|
|
53
|
+
|
|
54
|
+
#### Provider-Specific Options
|
|
55
|
+
```ruby
|
|
56
|
+
config.model = "gpt-5-nano" # Use specific model
|
|
57
|
+
config.temperature = 0.7 # More creative translations
|
|
58
|
+
config.max_tokens = 1500 # Limit response length
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
#### Automatic Backups
|
|
62
|
+
```ruby
|
|
63
|
+
config.create_backup = true # Enable backups (default)
|
|
64
|
+
config.max_backups = 5 # Keep up to 5 backup versions
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
#### JSON Support
|
|
68
|
+
```ruby
|
|
69
|
+
config.input_file = "config/locales/en.json"
|
|
70
|
+
config.output_folder = "config/locales"
|
|
71
|
+
# Automatically detects JSON format and uses JsonHandler
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
#### Parallel Translation
|
|
75
|
+
```ruby
|
|
76
|
+
config.target_languages = [
|
|
77
|
+
{ short_name: "it", name: "Italian" },
|
|
78
|
+
{ short_name: "fr", name: "French" },
|
|
79
|
+
{ short_name: "es", name: "Spanish" }
|
|
80
|
+
]
|
|
81
|
+
config.max_concurrent_requests = 3 # Translate 3 languages at once
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
#### Multiple Files
|
|
85
|
+
```ruby
|
|
86
|
+
# Array of specific files
|
|
87
|
+
config.input_files = [
|
|
88
|
+
"config/locales/common.en.yml",
|
|
89
|
+
"config/locales/errors.en.yml"
|
|
90
|
+
]
|
|
91
|
+
|
|
92
|
+
# Or use glob patterns
|
|
93
|
+
config.input_files = "config/locales/**/*.en.yml"
|
|
94
|
+
```
|
|
95
|
+
|
|
8
96
|
## [1.0.0] - 2025-10-22
|
|
9
97
|
|
|
10
98
|
### Complete Rewrite 🎉
|
data/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://www.ruby-lang.org/en/)
|
|
6
6
|
[](LICENSE.txt)
|
|
7
|
-
[](https://rubygems.org/gems/better_translate)
|
|
8
8
|
|
|
9
9
|
BetterTranslate automatically translates your YAML locale files using cutting-edge AI providers (ChatGPT, Google Gemini, and Anthropic Claude). It's designed for Rails applications but works with any Ruby project that uses YAML-based internationalization.
|
|
10
10
|
|
|
@@ -31,6 +31,14 @@ BetterTranslate automatically translates your YAML locale files using cutting-ed
|
|
|
31
31
|
- 🚫 **Flexible Exclusions**: Global exclusions for all languages + language-specific exclusions for fine-grained control
|
|
32
32
|
- 🎨 **Translation Context**: Provide domain-specific context for medical, legal, financial, or technical terminology
|
|
33
33
|
- 📊 **Similarity Analysis**: Built-in Levenshtein distance analyzer to identify similar translations
|
|
34
|
+
- 🔍 **Orphan Key Analyzer**: Find unused translation keys in your codebase with comprehensive reports (text, JSON, CSV)
|
|
35
|
+
|
|
36
|
+
### New in v1.1.0 🎉
|
|
37
|
+
- 🎛️ **Provider-Specific Options**: Fine-tune AI behavior with `model`, `temperature`, and `max_tokens`
|
|
38
|
+
- 💾 **Automatic Backups**: Configurable backup rotation before overwriting files (`.bak`, `.bak.1`, `.bak.2`)
|
|
39
|
+
- 📦 **JSON Support**: Full support for JSON locale files (React, Vue, modern JS frameworks)
|
|
40
|
+
- ⚡ **Parallel Translation**: Translate multiple languages concurrently with thread-based execution
|
|
41
|
+
- 📁 **Multiple Files**: Translate multiple files with arrays or glob patterns (`**/*.en.yml`)
|
|
34
42
|
|
|
35
43
|
### Development & Quality
|
|
36
44
|
- 🧪 **Comprehensive Testing**: Unit tests + integration tests with VCR cassettes (18 cassettes, 260KB)
|
|
@@ -160,6 +168,11 @@ BetterTranslate.configure do |config|
|
|
|
160
168
|
config.request_timeout = 30 # seconds
|
|
161
169
|
config.max_retries = 3
|
|
162
170
|
config.retry_delay = 2.0 # seconds
|
|
171
|
+
|
|
172
|
+
# 🆕 v1.1.0: Provider-specific options
|
|
173
|
+
config.model = "gpt-5-nano" # Specify model (optional)
|
|
174
|
+
config.temperature = 0.3 # Creativity (0.0-2.0, default: 0.3)
|
|
175
|
+
config.max_tokens = 2000 # Response length limit
|
|
163
176
|
end
|
|
164
177
|
```
|
|
165
178
|
|
|
@@ -195,6 +208,90 @@ end
|
|
|
195
208
|
|
|
196
209
|
Get your API key from [Anthropic Console](https://console.anthropic.com/).
|
|
197
210
|
|
|
211
|
+
### New Features (v1.1.0)
|
|
212
|
+
|
|
213
|
+
#### Automatic Backups
|
|
214
|
+
|
|
215
|
+
Protect your translation files with automatic backup creation:
|
|
216
|
+
|
|
217
|
+
```ruby
|
|
218
|
+
config.create_backup = true # Enable backups (default: true)
|
|
219
|
+
config.max_backups = 5 # Keep up to 5 backup versions
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Backup files are created with rotation:
|
|
223
|
+
- First backup: `it.yml.bak`
|
|
224
|
+
- Second backup: `it.yml.bak.1`
|
|
225
|
+
- Third backup: `it.yml.bak.2`
|
|
226
|
+
- Older backups are automatically deleted
|
|
227
|
+
|
|
228
|
+
#### JSON File Support
|
|
229
|
+
|
|
230
|
+
Translate JSON locale files for modern JavaScript frameworks:
|
|
231
|
+
|
|
232
|
+
```ruby
|
|
233
|
+
# Automatically detects JSON format from file extension
|
|
234
|
+
config.input_file = "config/locales/en.json"
|
|
235
|
+
config.output_folder = "config/locales"
|
|
236
|
+
|
|
237
|
+
# All features work with JSON: backups, incremental mode, exclusions, etc.
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Example JSON file:
|
|
241
|
+
```json
|
|
242
|
+
{
|
|
243
|
+
"en": {
|
|
244
|
+
"common": {
|
|
245
|
+
"greeting": "Hello %{name}"
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
#### Parallel Translation
|
|
252
|
+
|
|
253
|
+
Translate multiple languages concurrently for faster processing:
|
|
254
|
+
|
|
255
|
+
```ruby
|
|
256
|
+
config.target_languages = [
|
|
257
|
+
{ short_name: "it", name: "Italian" },
|
|
258
|
+
{ short_name: "fr", name: "French" },
|
|
259
|
+
{ short_name: "es", name: "Spanish" },
|
|
260
|
+
{ short_name: "de", name: "German" }
|
|
261
|
+
]
|
|
262
|
+
|
|
263
|
+
config.max_concurrent_requests = 4 # Translate 4 languages at once
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
**Performance improvement:** With 4 languages and `max_concurrent_requests = 4`, translation time is reduced by ~75% compared to sequential processing.
|
|
267
|
+
|
|
268
|
+
#### Multiple Files Support
|
|
269
|
+
|
|
270
|
+
Translate multiple files in a single run:
|
|
271
|
+
|
|
272
|
+
```ruby
|
|
273
|
+
# Array of specific files
|
|
274
|
+
config.input_files = [
|
|
275
|
+
"config/locales/common.en.yml",
|
|
276
|
+
"config/locales/errors.en.yml",
|
|
277
|
+
"config/locales/admin.en.yml"
|
|
278
|
+
]
|
|
279
|
+
|
|
280
|
+
# Or use glob patterns (recommended)
|
|
281
|
+
config.input_files = "config/locales/**/*.en.yml"
|
|
282
|
+
|
|
283
|
+
# Or combine both approaches
|
|
284
|
+
config.input_files = [
|
|
285
|
+
"config/locales/**/*.en.yml",
|
|
286
|
+
"app/javascript/translations/*.en.json"
|
|
287
|
+
]
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
Output files preserve the original structure:
|
|
291
|
+
- `common.en.yml` → `common.it.yml`
|
|
292
|
+
- `errors.en.yml` → `errors.it.yml`
|
|
293
|
+
- `admin/settings.en.yml` → `admin/settings.it.yml`
|
|
294
|
+
|
|
198
295
|
### Language Configuration
|
|
199
296
|
|
|
200
297
|
```ruby
|
|
@@ -444,6 +541,142 @@ Enable detailed logging for debugging:
|
|
|
444
541
|
config.verbose = true
|
|
445
542
|
```
|
|
446
543
|
|
|
544
|
+
## 🔍 Orphan Key Analyzer
|
|
545
|
+
|
|
546
|
+
The Orphan Key Analyzer helps you find unused translation keys in your codebase. It scans your YAML locale files and compares them against your actual code usage, generating comprehensive reports.
|
|
547
|
+
|
|
548
|
+
### CLI Usage
|
|
549
|
+
|
|
550
|
+
Find orphan keys from the command line:
|
|
551
|
+
|
|
552
|
+
```bash
|
|
553
|
+
# Basic text report (default)
|
|
554
|
+
better_translate analyze \
|
|
555
|
+
--source config/locales/en.yml \
|
|
556
|
+
--scan-path app/
|
|
557
|
+
|
|
558
|
+
# JSON format (great for CI/CD)
|
|
559
|
+
better_translate analyze \
|
|
560
|
+
--source config/locales/en.yml \
|
|
561
|
+
--scan-path app/ \
|
|
562
|
+
--format json
|
|
563
|
+
|
|
564
|
+
# CSV format (easy to share with team)
|
|
565
|
+
better_translate analyze \
|
|
566
|
+
--source config/locales/en.yml \
|
|
567
|
+
--scan-path app/ \
|
|
568
|
+
--format csv
|
|
569
|
+
|
|
570
|
+
# Save to file
|
|
571
|
+
better_translate analyze \
|
|
572
|
+
--source config/locales/en.yml \
|
|
573
|
+
--scan-path app/ \
|
|
574
|
+
--output orphan_report.txt
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
### Sample Output
|
|
578
|
+
|
|
579
|
+
**Text format:**
|
|
580
|
+
```
|
|
581
|
+
============================================================
|
|
582
|
+
Orphan Keys Analysis Report
|
|
583
|
+
============================================================
|
|
584
|
+
|
|
585
|
+
Statistics:
|
|
586
|
+
Total keys: 50
|
|
587
|
+
Used keys: 45
|
|
588
|
+
Orphan keys: 5
|
|
589
|
+
Usage: 90.0%
|
|
590
|
+
|
|
591
|
+
Orphan Keys (5):
|
|
592
|
+
------------------------------------------------------------
|
|
593
|
+
|
|
594
|
+
Key: users.old_message
|
|
595
|
+
Value: This feature was removed
|
|
596
|
+
|
|
597
|
+
Key: products.deprecated_label
|
|
598
|
+
Value: Old Label
|
|
599
|
+
...
|
|
600
|
+
============================================================
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
**JSON format:**
|
|
604
|
+
```json
|
|
605
|
+
{
|
|
606
|
+
"orphans": ["users.old_message", "products.deprecated_label"],
|
|
607
|
+
"orphan_details": {
|
|
608
|
+
"users.old_message": "This feature was removed",
|
|
609
|
+
"products.deprecated_label": "Old Label"
|
|
610
|
+
},
|
|
611
|
+
"orphan_count": 5,
|
|
612
|
+
"total_keys": 50,
|
|
613
|
+
"used_keys": 45,
|
|
614
|
+
"usage_percentage": 90.0
|
|
615
|
+
}
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
### Programmatic Usage
|
|
619
|
+
|
|
620
|
+
Use the analyzer in your Ruby code:
|
|
621
|
+
|
|
622
|
+
```ruby
|
|
623
|
+
# Scan YAML file
|
|
624
|
+
key_scanner = BetterTranslate::Analyzer::KeyScanner.new("config/locales/en.yml")
|
|
625
|
+
all_keys = key_scanner.scan # Returns Hash of all keys
|
|
626
|
+
|
|
627
|
+
# Scan code for used keys
|
|
628
|
+
code_scanner = BetterTranslate::Analyzer::CodeScanner.new("app/")
|
|
629
|
+
used_keys = code_scanner.scan # Returns Set of used keys
|
|
630
|
+
|
|
631
|
+
# Detect orphans
|
|
632
|
+
detector = BetterTranslate::Analyzer::OrphanDetector.new(all_keys, used_keys)
|
|
633
|
+
orphans = detector.detect
|
|
634
|
+
|
|
635
|
+
# Get statistics
|
|
636
|
+
puts "Orphan count: #{detector.orphan_count}"
|
|
637
|
+
puts "Usage: #{detector.usage_percentage}%"
|
|
638
|
+
|
|
639
|
+
# Generate report
|
|
640
|
+
reporter = BetterTranslate::Analyzer::Reporter.new(
|
|
641
|
+
orphans: orphans,
|
|
642
|
+
orphan_details: detector.orphan_details,
|
|
643
|
+
total_keys: all_keys.size,
|
|
644
|
+
used_keys: used_keys.size,
|
|
645
|
+
usage_percentage: detector.usage_percentage,
|
|
646
|
+
format: :text
|
|
647
|
+
)
|
|
648
|
+
|
|
649
|
+
puts reporter.generate
|
|
650
|
+
reporter.save_to_file("orphan_report.txt")
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
### Supported Translation Patterns
|
|
654
|
+
|
|
655
|
+
The analyzer recognizes these i18n patterns:
|
|
656
|
+
|
|
657
|
+
- `t('key')` - Rails short form
|
|
658
|
+
- `t("key")` - Rails short form with double quotes
|
|
659
|
+
- `I18n.t(:key)` - Symbol syntax
|
|
660
|
+
- `I18n.t('key')` - String syntax
|
|
661
|
+
- `I18n.translate('key')` - Full method name
|
|
662
|
+
- `<%= t('key') %>` - ERB templates
|
|
663
|
+
- `I18n.t('key', param: value)` - With parameters
|
|
664
|
+
|
|
665
|
+
**Nested keys:**
|
|
666
|
+
```yaml
|
|
667
|
+
en:
|
|
668
|
+
users:
|
|
669
|
+
profile:
|
|
670
|
+
title: "Profile" # Detected as: users.profile.title
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
**Use cases:**
|
|
674
|
+
- Clean up unused translations before deployment
|
|
675
|
+
- Identify dead code after refactoring
|
|
676
|
+
- Reduce locale file size
|
|
677
|
+
- Improve translation maintenance
|
|
678
|
+
- Generate reports for translation teams
|
|
679
|
+
|
|
447
680
|
## 🧪 Development & Testing
|
|
448
681
|
|
|
449
682
|
BetterTranslate includes comprehensive testing infrastructure with **unit tests**, **integration tests**, and a **Rails dummy app** for realistic testing.
|