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.
- checksums.yaml +5 -5
- data/.github/workflows/ci.yml +28 -0
- data/.gitignore +3 -1
- data/.rspec +3 -0
- data/.ruby-version +1 -0
- data/Gemfile.lock +138 -0
- data/README.md +34 -35
- data/bin/localize +10 -7
- data/docs/plans/2026-02-23-modernization-design.md +91 -0
- data/docs/plans/2026-02-23-modernization.md +1699 -0
- data/lib/localio/processor.rb +2 -1
- data/lib/localio/processors/csv_processor.rb +12 -3
- data/lib/localio/processors/google_drive_processor.rb +36 -48
- data/lib/localio/processors/xls_processor.rb +12 -3
- data/lib/localio/processors/xlsx_processor.rb +12 -3
- data/lib/localio/template_handler.rb +3 -1
- data/lib/localio/templates/android_localizable.erb +14 -2
- data/lib/localio/templates/ios_constant_localizable.erb +16 -2
- data/lib/localio/templates/ios_localizable.erb +20 -5
- data/lib/localio/templates/java_properties_localizable.erb +16 -2
- data/lib/localio/templates/json_localizable.erb +6 -5
- data/lib/localio/templates/rails_localizable.erb +15 -3
- data/lib/localio/templates/resx_localizable.erb +14 -2
- data/lib/localio/templates/swift_constant_localizable.erb +15 -2
- data/lib/localio/version.rb +1 -1
- data/lib/localio/writers/ios_writer.rb +3 -3
- data/lib/localio/writers/swift_writer.rb +3 -3
- data/localio.gemspec +19 -25
- data/spec/fixtures/sample.csv +11 -0
- data/spec/localio/filter_spec.rb +40 -0
- data/spec/localio/formatter_spec.rb +32 -0
- data/spec/localio/processors/csv_processor_spec.rb +89 -0
- data/spec/localio/processors/google_drive_processor_spec.rb +107 -0
- data/spec/localio/processors/xls_processor_spec.rb +65 -0
- data/spec/localio/processors/xlsx_processor_spec.rb +59 -0
- data/spec/localio/segment_spec.rb +27 -0
- data/spec/localio/segments_list_holder_spec.rb +22 -0
- data/spec/localio/string_helper_spec.rb +49 -0
- data/spec/localio/template_handler_spec.rb +67 -0
- data/spec/localio/term_spec.rb +24 -0
- data/spec/localio/writers/android_writer_spec.rb +71 -0
- data/spec/localio/writers/ios_writer_spec.rb +63 -0
- data/spec/localio/writers/java_properties_writer_spec.rb +35 -0
- data/spec/localio/writers/json_writer_spec.rb +57 -0
- data/spec/localio/writers/rails_writer_spec.rb +47 -0
- data/spec/localio/writers/resx_writer_spec.rb +44 -0
- data/spec/localio/writers/swift_writer_spec.rb +42 -0
- data/spec/localio_spec.rb +62 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/support/shared_terms.rb +35 -0
- 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('& 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
|
data/spec/spec_helper.rb
ADDED
|
@@ -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.
|
|
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:
|
|
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: '
|
|
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: '
|
|
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:
|
|
42
|
+
name: google_drive
|
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
|
58
44
|
requirements:
|
|
59
45
|
- - "~>"
|
|
60
46
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
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: '
|
|
54
|
+
version: '3.0'
|
|
69
55
|
- !ruby/object:Gem::Dependency
|
|
70
|
-
name:
|
|
56
|
+
name: spreadsheet
|
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
|
72
58
|
requirements:
|
|
73
59
|
- - "~>"
|
|
74
60
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '1.
|
|
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.
|
|
68
|
+
version: '1.3'
|
|
83
69
|
- !ruby/object:Gem::Dependency
|
|
84
|
-
name:
|
|
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: '
|
|
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: '
|
|
82
|
+
version: '2.0'
|
|
97
83
|
- !ruby/object:Gem::Dependency
|
|
98
|
-
name:
|
|
84
|
+
name: nokogiri
|
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
|
100
86
|
requirements:
|
|
101
87
|
- - "~>"
|
|
102
88
|
- !ruby/object:Gem::Version
|
|
103
|
-
version: '1.
|
|
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.
|
|
96
|
+
version: '1.16'
|
|
111
97
|
- !ruby/object:Gem::Dependency
|
|
112
|
-
name:
|
|
98
|
+
name: csv
|
|
113
99
|
requirement: !ruby/object:Gem::Requirement
|
|
114
100
|
requirements:
|
|
115
101
|
- - "~>"
|
|
116
102
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: '
|
|
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: '
|
|
125
|
-
description: Automatic Localizable file generation for multiple platforms
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
195
|
-
|
|
196
|
-
signing_key:
|
|
207
|
+
rubygems_version: 3.5.22
|
|
208
|
+
signing_key:
|
|
197
209
|
specification_version: 4
|
|
198
|
-
summary:
|
|
199
|
-
|
|
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: []
|