localio 0.1.6 → 0.2.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.
Files changed (51) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ci.yml +28 -0
  3. data/.gitignore +3 -1
  4. data/.rspec +3 -0
  5. data/.ruby-version +1 -0
  6. data/Gemfile.lock +138 -0
  7. data/README.md +34 -35
  8. data/bin/localize +10 -7
  9. data/docs/plans/2026-02-23-modernization-design.md +91 -0
  10. data/docs/plans/2026-02-23-modernization.md +1699 -0
  11. data/lib/localio/processor.rb +2 -1
  12. data/lib/localio/processors/csv_processor.rb +12 -3
  13. data/lib/localio/processors/google_drive_processor.rb +36 -48
  14. data/lib/localio/processors/xls_processor.rb +12 -3
  15. data/lib/localio/processors/xlsx_processor.rb +12 -3
  16. data/lib/localio/template_handler.rb +3 -1
  17. data/lib/localio/templates/android_localizable.erb +14 -2
  18. data/lib/localio/templates/ios_constant_localizable.erb +16 -2
  19. data/lib/localio/templates/ios_localizable.erb +20 -5
  20. data/lib/localio/templates/java_properties_localizable.erb +16 -2
  21. data/lib/localio/templates/json_localizable.erb +6 -5
  22. data/lib/localio/templates/rails_localizable.erb +15 -3
  23. data/lib/localio/templates/resx_localizable.erb +14 -2
  24. data/lib/localio/templates/swift_constant_localizable.erb +15 -2
  25. data/lib/localio/version.rb +1 -1
  26. data/lib/localio/writers/ios_writer.rb +3 -3
  27. data/lib/localio/writers/swift_writer.rb +3 -3
  28. data/localio.gemspec +19 -25
  29. data/spec/fixtures/sample.csv +11 -0
  30. data/spec/localio/filter_spec.rb +40 -0
  31. data/spec/localio/formatter_spec.rb +32 -0
  32. data/spec/localio/processors/csv_processor_spec.rb +89 -0
  33. data/spec/localio/processors/google_drive_processor_spec.rb +107 -0
  34. data/spec/localio/processors/xls_processor_spec.rb +65 -0
  35. data/spec/localio/processors/xlsx_processor_spec.rb +59 -0
  36. data/spec/localio/segment_spec.rb +27 -0
  37. data/spec/localio/segments_list_holder_spec.rb +22 -0
  38. data/spec/localio/string_helper_spec.rb +49 -0
  39. data/spec/localio/template_handler_spec.rb +67 -0
  40. data/spec/localio/term_spec.rb +24 -0
  41. data/spec/localio/writers/android_writer_spec.rb +71 -0
  42. data/spec/localio/writers/ios_writer_spec.rb +63 -0
  43. data/spec/localio/writers/java_properties_writer_spec.rb +35 -0
  44. data/spec/localio/writers/json_writer_spec.rb +57 -0
  45. data/spec/localio/writers/rails_writer_spec.rb +47 -0
  46. data/spec/localio/writers/resx_writer_spec.rb +44 -0
  47. data/spec/localio/writers/swift_writer_spec.rb +42 -0
  48. data/spec/localio_spec.rb +62 -0
  49. data/spec/spec_helper.rb +24 -0
  50. data/spec/support/shared_terms.rb +35 -0
  51. metadata +60 -49
@@ -0,0 +1,35 @@
1
+ require 'localio/string_helper'
2
+ require 'localio/term'
3
+ require 'localio/segment'
4
+ require 'localio/segments_list_holder'
5
+ require 'localio/formatter'
6
+ require 'localio/template_handler'
7
+ require 'localio/writers/java_properties_writer'
8
+
9
+ RSpec.describe JavaPropertiesWriter do
10
+ include_context 'standard terms'
11
+
12
+ let(:options) { { default_language: 'en' } }
13
+
14
+ describe '.write' do
15
+ it 'creates language_{lang}.properties for each language' do
16
+ Dir.mktmpdir do |tmpdir|
17
+ workdir = File.join(tmpdir, 'work')
18
+ FileUtils.mkdir_p(workdir)
19
+ Dir.chdir(workdir) { JavaPropertiesWriter.write(languages, terms, tmpdir, :smart, options) }
20
+ expect(File).to exist(File.join(tmpdir, 'language_en.properties'))
21
+ expect(File).to exist(File.join(tmpdir, 'language_es.properties'))
22
+ end
23
+ end
24
+
25
+ it 'includes translation values' do
26
+ Dir.mktmpdir do |tmpdir|
27
+ workdir = File.join(tmpdir, 'work')
28
+ FileUtils.mkdir_p(workdir)
29
+ Dir.chdir(workdir) { JavaPropertiesWriter.write(languages, terms, tmpdir, :smart, options) }
30
+ content = File.read(File.join(tmpdir, 'language_en.properties'))
31
+ expect(content).to include('My App')
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,57 @@
1
+ require 'json'
2
+ require 'localio/string_helper'
3
+ require 'localio/term'
4
+ require 'localio/segment'
5
+ require 'localio/segments_list_holder'
6
+ require 'localio/formatter'
7
+ require 'localio/template_handler'
8
+ require 'localio/writers/json_writer'
9
+
10
+ RSpec.describe JsonWriter do
11
+ include_context 'standard terms'
12
+
13
+ let(:options) { { default_language: 'en' } }
14
+
15
+ describe '.write' do
16
+ it 'creates strings-{lang}.json for each language' do
17
+ Dir.mktmpdir do |tmpdir|
18
+ workdir = File.join(tmpdir, 'work')
19
+ FileUtils.mkdir_p(workdir)
20
+ Dir.chdir(workdir) { JsonWriter.write(languages, terms, tmpdir, :smart, options) }
21
+ expect(File).to exist(File.join(tmpdir, 'strings-en.json'))
22
+ expect(File).to exist(File.join(tmpdir, 'strings-es.json'))
23
+ expect(File).to exist(File.join(tmpdir, 'strings-fr.json'))
24
+ end
25
+ end
26
+
27
+ it 'produces valid JSON' do
28
+ Dir.mktmpdir do |tmpdir|
29
+ workdir = File.join(tmpdir, 'work')
30
+ FileUtils.mkdir_p(workdir)
31
+ Dir.chdir(workdir) { JsonWriter.write(languages, terms, tmpdir, :smart, options) }
32
+ content = File.read(File.join(tmpdir, 'strings-en.json'))
33
+ expect { JSON.parse(content) }.not_to raise_error
34
+ end
35
+ end
36
+
37
+ it 'includes translation values' do
38
+ Dir.mktmpdir do |tmpdir|
39
+ workdir = File.join(tmpdir, 'work')
40
+ FileUtils.mkdir_p(workdir)
41
+ Dir.chdir(workdir) { JsonWriter.write(languages, terms, tmpdir, :smart, options) }
42
+ data = JSON.parse(File.read(File.join(tmpdir, 'strings-en.json')))
43
+ expect(data['translations']['app_name']).to eq('My App')
44
+ end
45
+ end
46
+
47
+ it 'sets correct language in meta' do
48
+ Dir.mktmpdir do |tmpdir|
49
+ workdir = File.join(tmpdir, 'work')
50
+ FileUtils.mkdir_p(workdir)
51
+ Dir.chdir(workdir) { JsonWriter.write(languages, terms, tmpdir, :smart, options) }
52
+ data = JSON.parse(File.read(File.join(tmpdir, 'strings-es.json')))
53
+ expect(data['meta']['language']).to eq('es')
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,47 @@
1
+ require 'localio/string_helper'
2
+ require 'localio/term'
3
+ require 'localio/segment'
4
+ require 'localio/segments_list_holder'
5
+ require 'localio/formatter'
6
+ require 'localio/template_handler'
7
+ require 'localio/writers/rails_writer'
8
+
9
+ RSpec.describe RailsWriter do
10
+ include_context 'standard terms'
11
+
12
+ let(:options) { { default_language: 'en' } }
13
+
14
+ describe '.write' do
15
+ it 'creates {lang}.yml for each language' do
16
+ Dir.mktmpdir do |tmpdir|
17
+ workdir = File.join(tmpdir, 'work')
18
+ FileUtils.mkdir_p(workdir)
19
+ Dir.chdir(workdir) { RailsWriter.write(languages, terms, tmpdir, :smart, options) }
20
+ expect(File).to exist(File.join(tmpdir, 'en.yml'))
21
+ expect(File).to exist(File.join(tmpdir, 'es.yml'))
22
+ expect(File).to exist(File.join(tmpdir, 'fr.yml'))
23
+ end
24
+ end
25
+
26
+ it 'starts YAML with the language key' do
27
+ Dir.mktmpdir do |tmpdir|
28
+ workdir = File.join(tmpdir, 'work')
29
+ FileUtils.mkdir_p(workdir)
30
+ Dir.chdir(workdir) { RailsWriter.write(languages, terms, tmpdir, :smart, options) }
31
+ content = File.read(File.join(tmpdir, 'en.yml'))
32
+ expect(content).to include('en:')
33
+ expect(content).to include('app_name: "My App"')
34
+ end
35
+ end
36
+
37
+ it 'renders comment rows as YAML comments' do
38
+ Dir.mktmpdir do |tmpdir|
39
+ workdir = File.join(tmpdir, 'work')
40
+ FileUtils.mkdir_p(workdir)
41
+ Dir.chdir(workdir) { RailsWriter.write(languages, terms, tmpdir, :smart, options) }
42
+ content = File.read(File.join(tmpdir, 'en.yml'))
43
+ expect(content).to include('# Section General')
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,44 @@
1
+ require 'localio/string_helper'
2
+ require 'localio/term'
3
+ require 'localio/segment'
4
+ require 'localio/segments_list_holder'
5
+ require 'localio/formatter'
6
+ require 'localio/template_handler'
7
+ require 'localio/writers/resx_writer'
8
+
9
+ RSpec.describe ResXWriter do
10
+ include_context 'standard terms'
11
+
12
+ let(:options) { { default_language: 'en' } }
13
+
14
+ describe '.write' do
15
+ it 'creates Resources.resx for the default language' do
16
+ Dir.mktmpdir do |tmpdir|
17
+ workdir = File.join(tmpdir, 'work')
18
+ FileUtils.mkdir_p(workdir)
19
+ Dir.chdir(workdir) { ResXWriter.write(languages, terms, tmpdir, :smart, options) }
20
+ expect(File).to exist(File.join(tmpdir, 'Resources.resx'))
21
+ end
22
+ end
23
+
24
+ it 'creates Resources.{lang}.resx for non-default languages' do
25
+ Dir.mktmpdir do |tmpdir|
26
+ workdir = File.join(tmpdir, 'work')
27
+ FileUtils.mkdir_p(workdir)
28
+ Dir.chdir(workdir) { ResXWriter.write(languages, terms, tmpdir, :smart, options) }
29
+ expect(File).to exist(File.join(tmpdir, 'Resources.es.resx'))
30
+ expect(File).to exist(File.join(tmpdir, 'Resources.fr.resx'))
31
+ end
32
+ end
33
+
34
+ it 'uses custom resource_file name when specified' do
35
+ Dir.mktmpdir do |tmpdir|
36
+ workdir = File.join(tmpdir, 'work')
37
+ FileUtils.mkdir_p(workdir)
38
+ Dir.chdir(workdir) { ResXWriter.write(languages, terms, tmpdir, :smart, options.merge(resource_file: 'Strings')) }
39
+ expect(File).to exist(File.join(tmpdir, 'Strings.resx'))
40
+ expect(File).to exist(File.join(tmpdir, 'Strings.es.resx'))
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,42 @@
1
+ require 'localio/string_helper'
2
+ require 'localio/term'
3
+ require 'localio/segment'
4
+ require 'localio/segments_list_holder'
5
+ require 'localio/formatter'
6
+ require 'localio/template_handler'
7
+ require 'localio/writers/swift_writer'
8
+
9
+ RSpec.describe SwiftWriter do
10
+ include_context 'standard terms'
11
+
12
+ let(:options) { { default_language: 'en' } }
13
+
14
+ describe '.write' do
15
+ it 'creates Localizable.strings in {lang}.lproj/' do
16
+ Dir.mktmpdir do |tmpdir|
17
+ workdir = File.join(tmpdir, 'work')
18
+ FileUtils.mkdir_p(workdir)
19
+ Dir.chdir(workdir) { SwiftWriter.write(languages, terms, tmpdir, :smart, options) }
20
+ expect(File).to exist(File.join(tmpdir, 'en.lproj', 'Localizable.strings'))
21
+ end
22
+ end
23
+
24
+ it 'creates LocalizableConstants.swift by default' do
25
+ Dir.mktmpdir do |tmpdir|
26
+ workdir = File.join(tmpdir, 'work')
27
+ FileUtils.mkdir_p(workdir)
28
+ Dir.chdir(workdir) { SwiftWriter.write(languages, terms, tmpdir, :smart, options) }
29
+ expect(File).to exist(File.join(tmpdir, 'LocalizableConstants.swift'))
30
+ end
31
+ end
32
+
33
+ it 'skips LocalizableConstants.swift when create_constants is false' do
34
+ Dir.mktmpdir do |tmpdir|
35
+ workdir = File.join(tmpdir, 'work')
36
+ FileUtils.mkdir_p(workdir)
37
+ Dir.chdir(workdir) { SwiftWriter.write(languages, terms, tmpdir, :smart, options.merge(create_constants: false)) }
38
+ expect(File).not_to exist(File.join(tmpdir, 'LocalizableConstants.swift'))
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,62 @@
1
+ require 'json'
2
+ require 'localio/string_helper'
3
+ require 'localio/term'
4
+ require 'localio/segment'
5
+ require 'localio/segments_list_holder'
6
+ require 'localio/filter'
7
+ require 'localio/formatter'
8
+ require 'localio/template_handler'
9
+ require 'localio/processors/csv_processor'
10
+ require 'localio/writers/android_writer'
11
+ require 'localio/writers/json_writer'
12
+
13
+ RSpec.describe 'Localio pipeline' do
14
+ let(:fixture_path) { File.expand_path('fixtures/sample.csv', __dir__) }
15
+
16
+ it 'processes CSV and writes Android strings.xml with correct transformations' do
17
+ Dir.mktmpdir do |tmpdir|
18
+ workdir = File.join(tmpdir, 'work')
19
+ FileUtils.mkdir_p(workdir)
20
+ Dir.chdir(workdir) do
21
+ result = CsvProcessor.load_localizables({}, { path: fixture_path })
22
+ AndroidWriter.write(result[:languages], result[:segments], tmpdir, :smart,
23
+ { default_language: result[:default_language] })
24
+
25
+ content = File.read(File.join(tmpdir, 'values', 'strings.xml'))
26
+ expect(content).to include('<string name="app_name">My App</string>')
27
+ expect(content).to include('&amp; Jerry')
28
+ expect(content).to include('Wait…')
29
+ expect(content).to include('%s world')
30
+ expect(content).to include('<!-- Section General -->')
31
+ end
32
+ end
33
+ end
34
+
35
+ it 'processes CSV and writes valid JSON with correct content' do
36
+ Dir.mktmpdir do |tmpdir|
37
+ workdir = File.join(tmpdir, 'work')
38
+ FileUtils.mkdir_p(workdir)
39
+ Dir.chdir(workdir) do
40
+ result = CsvProcessor.load_localizables({}, { path: fixture_path })
41
+ JsonWriter.write(result[:languages], result[:segments], tmpdir, :smart,
42
+ { default_language: result[:default_language] })
43
+
44
+ data = JSON.parse(File.read(File.join(tmpdir, 'strings-en.json')))
45
+ expect(data['translations']['app_name']).to eq('My App')
46
+ expect(data['meta']['language']).to eq('en')
47
+ end
48
+ end
49
+ end
50
+
51
+ it 'applies only filter before writing' do
52
+ result = CsvProcessor.load_localizables({}, { path: fixture_path })
53
+ filtered = Filter.apply_filter(result[:segments], { keys: 'app_' }, nil)
54
+ expect(filtered.map(&:keyword)).to eq(['app_name'])
55
+ end
56
+
57
+ it 'applies except filter before writing' do
58
+ result = CsvProcessor.load_localizables({}, { path: fixture_path })
59
+ filtered = Filter.apply_filter(result[:segments], nil, { keys: 'dots_|ampersand_' })
60
+ expect(filtered.map(&:keyword)).not_to include('dots_test', 'ampersand_test')
61
+ end
62
+ end
@@ -0,0 +1,24 @@
1
+ require 'tmpdir'
2
+ require 'fileutils'
3
+ # Load nokogiri eagerly so it is available before any spec file runs.
4
+ # Some specs stub $LOADED_FEATURES for google_drive (which also requires
5
+ # nokogiri internally); loading nokogiri here first ensures SimpleXlsxReader
6
+ # and android_writer can always find the Nokogiri constant.
7
+ require 'nokogiri'
8
+
9
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
10
+
11
+ Dir[File.expand_path('support/**/*.rb', __dir__)].each { |f| require f }
12
+
13
+ RSpec.configure do |config|
14
+ config.expect_with :rspec do |c|
15
+ c.include_chain_clauses_in_custom_matcher_descriptions = true
16
+ end
17
+ config.mock_with :rspec do |mocks|
18
+ mocks.verify_partial_doubles = true
19
+ end
20
+ config.shared_context_metadata_behavior = :apply_to_host_groups
21
+ config.filter_run_when_matching :focus
22
+ config.disable_monkey_patching!
23
+ config.order = :random
24
+ end
@@ -0,0 +1,35 @@
1
+ require 'localio/term'
2
+
3
+ RSpec.shared_context 'standard terms' do
4
+ let(:languages) { { 'en' => 1, 'es' => 2, 'fr' => 3 } }
5
+ let(:default_language) { 'en' }
6
+ let(:terms) do
7
+ [
8
+ Term.new('[comment]').tap do |t|
9
+ t.values['en'] = 'Section General'
10
+ t.values['es'] = 'Section General'
11
+ t.values['fr'] = 'Section General'
12
+ end,
13
+ Term.new('app_name').tap do |t|
14
+ t.values['en'] = 'My App'
15
+ t.values['es'] = 'Mi Aplicación'
16
+ t.values['fr'] = 'Mon Application'
17
+ end,
18
+ Term.new('greeting').tap do |t|
19
+ t.values['en'] = 'Hello %@ world'
20
+ t.values['es'] = 'Hola %@ mundo'
21
+ t.values['fr'] = 'Bonjour %@ monde'
22
+ end,
23
+ Term.new('dots_test').tap do |t|
24
+ t.values['en'] = 'Wait...'
25
+ t.values['es'] = 'Espera...'
26
+ t.values['fr'] = 'Attendez...'
27
+ end,
28
+ Term.new('ampersand_test').tap do |t|
29
+ t.values['en'] = 'Tom & Jerry'
30
+ t.values['es'] = 'Tom & Jerry'
31
+ t.values['fr'] = 'Tom & Jerry'
32
+ end,
33
+ ]
34
+ end
35
+ end
metadata CHANGED
@@ -1,129 +1,114 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: localio
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nacho Lopez
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-17 00:00:00.000000000 Z
11
+ date: 2026-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: bundler
29
15
  requirement: !ruby/object:Gem::Requirement
30
16
  requirements:
31
17
  - - "~>"
32
18
  - !ruby/object:Gem::Version
33
- version: '1.3'
19
+ version: '3.0'
34
20
  type: :development
35
21
  prerelease: false
36
22
  version_requirements: !ruby/object:Gem::Requirement
37
23
  requirements:
38
24
  - - "~>"
39
25
  - !ruby/object:Gem::Version
40
- version: '1.3'
26
+ version: '3.0'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: rake
43
29
  requirement: !ruby/object:Gem::Requirement
44
30
  requirements:
45
- - - ">="
31
+ - - "~>"
46
32
  - !ruby/object:Gem::Version
47
- version: '0'
33
+ version: '13.0'
48
34
  type: :development
49
35
  prerelease: false
50
36
  version_requirements: !ruby/object:Gem::Requirement
51
37
  requirements:
52
- - - ">="
38
+ - - "~>"
53
39
  - !ruby/object:Gem::Version
54
- version: '0'
40
+ version: '13.0'
55
41
  - !ruby/object:Gem::Dependency
56
- name: micro-optparse
42
+ name: google_drive
57
43
  requirement: !ruby/object:Gem::Requirement
58
44
  requirements:
59
45
  - - "~>"
60
46
  - !ruby/object:Gem::Version
61
- version: '1.2'
47
+ version: '3.0'
62
48
  type: :runtime
63
49
  prerelease: false
64
50
  version_requirements: !ruby/object:Gem::Requirement
65
51
  requirements:
66
52
  - - "~>"
67
53
  - !ruby/object:Gem::Version
68
- version: '1.2'
54
+ version: '3.0'
69
55
  - !ruby/object:Gem::Dependency
70
- name: google_drive
56
+ name: spreadsheet
71
57
  requirement: !ruby/object:Gem::Requirement
72
58
  requirements:
73
59
  - - "~>"
74
60
  - !ruby/object:Gem::Version
75
- version: '1.0'
61
+ version: '1.3'
76
62
  type: :runtime
77
63
  prerelease: false
78
64
  version_requirements: !ruby/object:Gem::Requirement
79
65
  requirements:
80
66
  - - "~>"
81
67
  - !ruby/object:Gem::Version
82
- version: '1.0'
68
+ version: '1.3'
83
69
  - !ruby/object:Gem::Dependency
84
- name: spreadsheet
70
+ name: simple_xlsx_reader
85
71
  requirement: !ruby/object:Gem::Requirement
86
72
  requirements:
87
73
  - - "~>"
88
74
  - !ruby/object:Gem::Version
89
- version: '1.0'
75
+ version: '2.0'
90
76
  type: :runtime
91
77
  prerelease: false
92
78
  version_requirements: !ruby/object:Gem::Requirement
93
79
  requirements:
94
80
  - - "~>"
95
81
  - !ruby/object:Gem::Version
96
- version: '1.0'
82
+ version: '2.0'
97
83
  - !ruby/object:Gem::Dependency
98
- name: simple_xlsx_reader
84
+ name: nokogiri
99
85
  requirement: !ruby/object:Gem::Requirement
100
86
  requirements:
101
87
  - - "~>"
102
88
  - !ruby/object:Gem::Version
103
- version: '1.0'
89
+ version: '1.16'
104
90
  type: :runtime
105
91
  prerelease: false
106
92
  version_requirements: !ruby/object:Gem::Requirement
107
93
  requirements:
108
94
  - - "~>"
109
95
  - !ruby/object:Gem::Version
110
- version: '1.0'
96
+ version: '1.16'
111
97
  - !ruby/object:Gem::Dependency
112
- name: nokogiri
98
+ name: csv
113
99
  requirement: !ruby/object:Gem::Requirement
114
100
  requirements:
115
101
  - - "~>"
116
102
  - !ruby/object:Gem::Version
117
- version: '1.6'
103
+ version: '3.2'
118
104
  type: :runtime
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
107
  requirements:
122
108
  - - "~>"
123
109
  - !ruby/object:Gem::Version
124
- version: '1.6'
125
- description: Automatic Localizable file generation for multiple platforms (Rails YAML,
126
- Android, Java Properties, iOS, JSON, .NET ResX)
110
+ version: '3.2'
111
+ description: Automatic Localizable file generation for multiple platforms
127
112
  email:
128
113
  - nacho@nlopez.io
129
114
  executables:
@@ -131,13 +116,19 @@ executables:
131
116
  extensions: []
132
117
  extra_rdoc_files: []
133
118
  files:
119
+ - ".github/workflows/ci.yml"
134
120
  - ".gitignore"
121
+ - ".rspec"
122
+ - ".ruby-version"
135
123
  - CONTRIBUTING.md
136
124
  - Gemfile
125
+ - Gemfile.lock
137
126
  - LICENSE.txt
138
127
  - README.md
139
128
  - Rakefile
140
129
  - bin/localize
130
+ - docs/plans/2026-02-23-modernization-design.md
131
+ - docs/plans/2026-02-23-modernization.md
141
132
  - lib/localio.rb
142
133
  - lib/localio/config_store.rb
143
134
  - lib/localio/filter.rb
@@ -172,11 +163,33 @@ files:
172
163
  - lib/localio/writers/resx_writer.rb
173
164
  - lib/localio/writers/swift_writer.rb
174
165
  - localio.gemspec
175
- homepage: http://github.com/mrmans0n/localio
166
+ - spec/fixtures/sample.csv
167
+ - spec/localio/filter_spec.rb
168
+ - spec/localio/formatter_spec.rb
169
+ - spec/localio/processors/csv_processor_spec.rb
170
+ - spec/localio/processors/google_drive_processor_spec.rb
171
+ - spec/localio/processors/xls_processor_spec.rb
172
+ - spec/localio/processors/xlsx_processor_spec.rb
173
+ - spec/localio/segment_spec.rb
174
+ - spec/localio/segments_list_holder_spec.rb
175
+ - spec/localio/string_helper_spec.rb
176
+ - spec/localio/template_handler_spec.rb
177
+ - spec/localio/term_spec.rb
178
+ - spec/localio/writers/android_writer_spec.rb
179
+ - spec/localio/writers/ios_writer_spec.rb
180
+ - spec/localio/writers/java_properties_writer_spec.rb
181
+ - spec/localio/writers/json_writer_spec.rb
182
+ - spec/localio/writers/rails_writer_spec.rb
183
+ - spec/localio/writers/resx_writer_spec.rb
184
+ - spec/localio/writers/swift_writer_spec.rb
185
+ - spec/localio_spec.rb
186
+ - spec/spec_helper.rb
187
+ - spec/support/shared_terms.rb
188
+ homepage: https://github.com/mrmans0n/localio
176
189
  licenses:
177
190
  - MIT
178
191
  metadata: {}
179
- post_install_message:
192
+ post_install_message:
180
193
  rdoc_options: []
181
194
  require_paths:
182
195
  - lib
@@ -184,18 +197,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
184
197
  requirements:
185
198
  - - ">="
186
199
  - !ruby/object:Gem::Version
187
- version: 1.9.2
200
+ version: '3.2'
188
201
  required_rubygems_version: !ruby/object:Gem::Requirement
189
202
  requirements:
190
203
  - - ">="
191
204
  - !ruby/object:Gem::Version
192
205
  version: '0'
193
206
  requirements: []
194
- rubyforge_project:
195
- rubygems_version: 2.4.7
196
- signing_key:
207
+ rubygems_version: 3.5.22
208
+ signing_key:
197
209
  specification_version: 4
198
- summary: Automatic Localizable file generation for multiple type of files, like Android
199
- string.xml, Xcode Localizable.strings, JSON files, Rails YAML files, Java properties,
200
- etc. reading from Google Drive and Excel spreadsheets as base.
210
+ summary: Generates Android, iOS, Rails, JSON, Java Properties, and .NET ResX localization
211
+ files from spreadsheet sources.
201
212
  test_files: []