localio 0.2.1 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e811c8aa9cf8dabaff74b28dca5476b389c46e27a2dbb5addd87177f28abf566
4
- data.tar.gz: 6536d23be9e050ec9d579e6fd0bd35af573eba46536f2d711acaf5d8ee086dc3
3
+ metadata.gz: 5eb5417063807fd19963f7ae28327a1c323357430d3f2de7b55edd04391f06fa
4
+ data.tar.gz: b41c293c7ab8c37d640b3f33293d84da1c7f6795b2f46e82bc576cadee918aec
5
5
  SHA512:
6
- metadata.gz: 2217300fc3ff1610320e23053d97969c93983caf57ecbbc064c5e4018ba4d599b90c71a70ee27bfa5e38ffc3f52bf8c539110c9c55eefdcec4fe8c0960a4d5bd
7
- data.tar.gz: 40b1707ad311b028a76a4a0b5f26485153642fc48a89b2e488b7c7b3c13e146f82b55f72bf6a18481082a76b486719c33f1936c83a706d94b14afd7a28b3e230
6
+ metadata.gz: 826799ef9f0a850dfd85c1e21dced3b9130c299081053693a78d2c70e95119cda368c019822360880359f1b9a7e9e1313214a739289a14f930b6ba984a08c15a
7
+ data.tar.gz: 6f1e9c5137de4906e174d5ae410990db0afa0b333f5a62dd8decdb0a15091c4f6ee1c0c3c5f91ef87c5679d11876978bfdf0c0c6032e4910bf3c8afbbcc7307a
@@ -0,0 +1,42 @@
1
+ name: Release
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ publish:
12
+ name: Publish to RubyGems
13
+ runs-on: ubuntu-latest
14
+
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - uses: ruby/setup-ruby@v1
19
+ with:
20
+ ruby-version: "3.3"
21
+ bundler-cache: true
22
+
23
+ - name: Run tests
24
+ run: bundle exec rspec
25
+
26
+ - name: Verify version matches tag
27
+ run: |
28
+ GEM_VERSION=$(ruby -r ./lib/localio/version -e 'puts Localio::VERSION')
29
+ TAG_VERSION="${GITHUB_REF_NAME#v}"
30
+ if [ "$GEM_VERSION" != "$TAG_VERSION" ]; then
31
+ echo "::error::Version mismatch: gem=$GEM_VERSION tag=$TAG_VERSION"
32
+ exit 1
33
+ fi
34
+ echo "Publishing localio v$GEM_VERSION"
35
+
36
+ - name: Build gem
37
+ run: gem build localio.gemspec
38
+
39
+ - name: Publish to RubyGems
40
+ run: gem push localio-*.gem
41
+ env:
42
+ GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.3.10
1
+ 3.2.9
data/AGENTS.md ADDED
@@ -0,0 +1 @@
1
+ CLAUDE.md
data/CLAUDE.md ADDED
@@ -0,0 +1,79 @@
1
+ # AGENTS.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) and other AI assistants working on this repository.
4
+
5
+ ## Commands
6
+
7
+ ```bash
8
+ # Run all tests
9
+ bundle exec rspec
10
+
11
+ # Run a single spec file
12
+ bundle exec rspec spec/localio_spec.rb
13
+
14
+ # Run a single example by line number
15
+ bundle exec rspec spec/localio_spec.rb:42
16
+
17
+ # Standard gem tasks (build, install, release)
18
+ bundle exec rake
19
+ ```
20
+
21
+ ## What This Gem Does
22
+
23
+ Localio reads translation data from spreadsheets (Google Drive, XLS, XLSX, CSV) and generates platform-specific localization files. Supported output platforms: Android (`strings.xml`), iOS/Swift (`.strings` + header/constants), JSON, Rails YAML, Java `.properties`, `.resx`, and Twine format.
24
+
25
+ The entry point is `bin/localize`, which reads a `Locfile` (Ruby DSL) from the current directory.
26
+
27
+ ## Architecture
28
+
29
+ ### Data Flow
30
+
31
+ ```
32
+ Locfile (DSL config)
33
+ → Processor (reads spreadsheet source)
34
+ → Filter (regex-based key filtering)
35
+ → LocalizableWriter (dispatches to platform writer)
36
+ → ERB templates → output files
37
+ ```
38
+
39
+ ### Key Abstractions
40
+
41
+ **`Locfile`** (`lib/localio/locfile.rb`) — DSL parser using `instance_eval`. Stores platform, source credentials, output path, formatter, and filters.
42
+
43
+ **`Processor`** (`lib/localio/processor.rb`) — Routes to the correct reader based on `:platform` config. Returns a hash of `language => [Segment]` pairs.
44
+
45
+ **`LocalizableWriter`** (`lib/localio/localizable_writer.rb`) — Routes to the correct writer class. Writers live in `lib/localio/writers/` and use ERB templates from `lib/localio/templates/`.
46
+
47
+ **`Segment`** — A single translation unit: `{key, value, language}`. **`Term`** — A key with a hash of all language values.
48
+
49
+ **`Filter`** (`lib/localio/filter.rb`) — Applied after loading; supports `:only` (allowlist) and `:except` (denylist) regex patterns.
50
+
51
+ **`Formatter`** (`lib/localio/formatter.rb`) — Transforms key names: `:smart`, `:snake_case`, `:camel_case`, `:none`.
52
+
53
+ ### Spreadsheet Format Convention
54
+
55
+ Spreadsheets must follow a specific structure:
56
+ - A `[key]` marker row with language codes as column headers (default language marked with `*`)
57
+ - Data rows with key in column A, translations in subsequent columns
58
+ - An `[end]` marker row to stop parsing
59
+ - Optional `[comment]` rows for documentation (skipped during parsing)
60
+
61
+ ### Adding a New Platform
62
+
63
+ 1. Create `lib/localio/writers/<platform>_writer.rb` with a `write_localizables(holder, path)` class method
64
+ 2. Create corresponding ERB template(s) in `lib/localio/templates/`
65
+ 3. Add a case branch in `LocalizableWriter`
66
+ 4. Add a case branch in the `platform` DSL accessor in `Locfile`
67
+ 5. Add specs in `spec/localio/writers/`
68
+
69
+ ### Adding a New Source Format
70
+
71
+ 1. Create `lib/localio/processors/<format>_processor.rb` with a `load_localizables(config)` class method returning `{language => [Segment]}`
72
+ 2. Add a case branch in `Processor`
73
+ 3. Add specs in `spec/localio/processors/`
74
+
75
+ ## Notes
76
+
77
+ - `String` is monkey-patched in `lib/localio/string_helper.rb` with color helpers and case-conversion methods used throughout
78
+ - The `ConfigStore` (`lib/localio/config_store.rb`) persists OAuth tokens/config to a local YAML file (`.localio.yml`)
79
+ - Tests use fixture spreadsheet files in `spec/` directories alongside spec files
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- localio (0.2.0)
4
+ localio (0.2.4)
5
5
  csv (~> 3.2)
6
6
  google_drive (~> 3.0)
7
7
  nokogiri (~> 1.16)
@@ -11,32 +11,36 @@ PATH
11
11
  GEM
12
12
  remote: https://rubygems.org/
13
13
  specs:
14
- addressable (2.8.8)
14
+ addressable (2.9.0)
15
15
  public_suffix (>= 2.0.2, < 8.0)
16
16
  base64 (0.3.0)
17
17
  bigdecimal (4.0.1)
18
18
  csv (3.3.5)
19
19
  declarative (0.0.20)
20
20
  diff-lcs (1.6.2)
21
- faraday (1.8.0)
21
+ faraday (1.10.6)
22
22
  faraday-em_http (~> 1.0)
23
23
  faraday-em_synchrony (~> 1.0)
24
24
  faraday-excon (~> 1.1)
25
- faraday-httpclient (~> 1.0.1)
25
+ faraday-httpclient (~> 1.0)
26
+ faraday-multipart (~> 1.0)
26
27
  faraday-net_http (~> 1.0)
27
- faraday-net_http_persistent (~> 1.1)
28
+ faraday-net_http_persistent (~> 1.0)
28
29
  faraday-patron (~> 1.0)
29
30
  faraday-rack (~> 1.0)
30
- multipart-post (>= 1.2, < 3)
31
+ faraday-retry (~> 1.0)
31
32
  ruby2_keywords (>= 0.0.4)
32
33
  faraday-em_http (1.0.0)
33
34
  faraday-em_synchrony (1.0.1)
34
35
  faraday-excon (1.1.0)
35
36
  faraday-httpclient (1.0.1)
37
+ faraday-multipart (1.2.0)
38
+ multipart-post (~> 2.0)
36
39
  faraday-net_http (1.0.2)
37
40
  faraday-net_http_persistent (1.2.0)
38
41
  faraday-patron (1.0.0)
39
42
  faraday-rack (1.0.0)
43
+ faraday-retry (1.0.4)
40
44
  google-apis-core (0.11.3)
41
45
  addressable (~> 2.5, >= 2.5.1)
42
46
  googleauth (>= 0.16.2, < 2.a)
@@ -63,7 +67,7 @@ GEM
63
67
  signet (~> 0.15)
64
68
  httpclient (2.9.0)
65
69
  mutex_m
66
- jwt (2.10.2)
70
+ jwt (2.10.3)
67
71
  base64
68
72
  logger (1.7.0)
69
73
  memoist (0.16.2)
@@ -72,15 +76,15 @@ GEM
72
76
  multi_json (1.19.1)
73
77
  multipart-post (2.4.1)
74
78
  mutex_m (0.3.0)
75
- nokogiri (1.19.1)
79
+ nokogiri (1.19.4)
76
80
  mini_portile2 (~> 2.8.2)
77
81
  racc (~> 1.4)
78
- nokogiri (1.19.1-arm64-darwin)
82
+ nokogiri (1.19.4-arm64-darwin)
79
83
  racc (~> 1.4)
80
- nokogiri (1.19.1-x86_64-linux-gnu)
84
+ nokogiri (1.19.4-x86_64-linux-gnu)
81
85
  racc (~> 1.4)
82
86
  os (1.1.4)
83
- public_suffix (7.0.2)
87
+ public_suffix (7.0.5)
84
88
  racc (1.8.1)
85
89
  rake (13.3.1)
86
90
  representable (3.2.0)
@@ -104,7 +108,7 @@ GEM
104
108
  rspec-support (3.13.7)
105
109
  ruby-ole (1.2.13.1)
106
110
  ruby2_keywords (0.0.5)
107
- rubyzip (3.2.2)
111
+ rubyzip (3.6.0)
108
112
  signet (0.21.0)
109
113
  addressable (~> 2.8)
110
114
  faraday (>= 0.17.5, < 3.a)
data/README.md CHANGED
@@ -271,6 +271,43 @@ For example, if we wanted to override the default (english) and use spanish inst
271
271
  platform :android, :override_default => 'es'
272
272
  ```
273
273
 
274
+ ## Fastlane Integration
275
+
276
+ Use the [fastlane-plugin-localio](https://github.com/mrmans0n/fastlane-plugin-localio) plugin to run localio as part of your Fastlane workflow.
277
+
278
+ ### Installation
279
+
280
+ ```bash
281
+ fastlane add_plugin localio
282
+ ```
283
+
284
+ ### Usage
285
+
286
+ You can use an existing Locfile:
287
+
288
+ ```ruby
289
+ lane :localize do
290
+ localio(locfile: "Locfile")
291
+ end
292
+ ```
293
+
294
+ Or configure everything inline:
295
+
296
+ ```ruby
297
+ lane :localize do
298
+ localio(
299
+ platform: "android",
300
+ source: "xlsx",
301
+ source_path: "translations.xlsx",
302
+ source_sheet: "Sheet1",
303
+ output_path: "app/src/main/res",
304
+ formatting: "smart"
305
+ )
306
+ end
307
+ ```
308
+
309
+ See the [plugin README](https://github.com/mrmans0n/fastlane-plugin-localio) for the full list of parameters and examples.
310
+
274
311
  ## Contributing
275
312
 
276
313
  Please read the [contributing guide](https://github.com/mrmans0n/localio/blob/master/CONTRIBUTING.md).
@@ -1,3 +1,3 @@
1
1
  module Localio
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.4"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: localio
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.4
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: 2026-02-24 00:00:00.000000000 Z
11
+ date: 2026-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -117,9 +117,12 @@ extensions: []
117
117
  extra_rdoc_files: []
118
118
  files:
119
119
  - ".github/workflows/ci.yml"
120
+ - ".github/workflows/release.yml"
120
121
  - ".gitignore"
121
122
  - ".rspec"
122
123
  - ".ruby-version"
124
+ - AGENTS.md
125
+ - CLAUDE.md
123
126
  - CONTRIBUTING.md
124
127
  - Gemfile
125
128
  - Gemfile.lock
@@ -127,10 +130,6 @@ files:
127
130
  - README.md
128
131
  - Rakefile
129
132
  - bin/localize
130
- - docs/plans/2026-02-23-modernization-design.md
131
- - docs/plans/2026-02-23-modernization.md
132
- - docs/plans/2026-02-23-twine-writer-design.md
133
- - docs/plans/2026-02-23-twine-writer.md
134
133
  - lib/localio.rb
135
134
  - lib/localio/config_store.rb
136
135
  - lib/localio/filter.rb
@@ -193,7 +192,7 @@ homepage: https://github.com/mrmans0n/localio
193
192
  licenses:
194
193
  - MIT
195
194
  metadata: {}
196
- post_install_message:
195
+ post_install_message:
197
196
  rdoc_options: []
198
197
  require_paths:
199
198
  - lib
@@ -208,8 +207,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
208
207
  - !ruby/object:Gem::Version
209
208
  version: '0'
210
209
  requirements: []
211
- rubygems_version: 3.0.3.1
212
- signing_key:
210
+ rubygems_version: 3.5.22
211
+ signing_key:
213
212
  specification_version: 4
214
213
  summary: Generates Android, iOS, Rails, JSON, Java Properties, and .NET ResX localization
215
214
  files from spreadsheet sources.
@@ -1,91 +0,0 @@
1
- # Localio Modernization Design
2
-
3
- **Date:** 2026-02-23
4
- **Approach:** Option A — tests first, then dependency updates
5
-
6
- ## Overview
7
-
8
- Modernize the Localio gem in two phases:
9
-
10
- 1. Write a comprehensive RSpec test suite with fixtures and mocks
11
- 2. Update all dependencies to current versions and target Ruby 3.x, using the test suite as a safety net
12
-
13
- ## Phase 1: Test Suite
14
-
15
- ### Structure
16
-
17
- ```
18
- spec/
19
- spec_helper.rb
20
- fixtures/
21
- sample.csv # canonical test data: keys in 3 languages, special chars, comments, multi-level keys
22
- sample.xlsx # small binary fixture
23
- sample.xls # small binary fixture
24
- localio/
25
- term_spec.rb
26
- segment_spec.rb
27
- filter_spec.rb
28
- formatter_spec.rb
29
- template_handler_spec.rb
30
- processors/
31
- csv_processor_spec.rb
32
- xlsx_processor_spec.rb
33
- xls_processor_spec.rb
34
- google_drive_processor_spec.rb # mocked worksheet interface
35
- writers/
36
- android_writer_spec.rb
37
- ios_writer_spec.rb
38
- swift_writer_spec.rb
39
- json_writer_spec.rb
40
- rails_writer_spec.rb
41
- java_properties_writer_spec.rb
42
- resx_writer_spec.rb
43
- localio_spec.rb # end-to-end: CSV fixture → writer → verify output files
44
- ```
45
-
46
- ### Fixture Data
47
-
48
- A single canonical `sample.csv` covers all test scenarios:
49
- - Normal keys with translations in 3 languages
50
- - Special characters: ampersands, ellipsis, printf format strings
51
- - Comment rows
52
- - Multi-level/nested keys (dot-separated) for JSON nesting tests
53
-
54
- The same fixture data drives all processor and writer tests for consistency.
55
-
56
- ### Testing Strategy Per Layer
57
-
58
- **Models (Term, Segment):** Construction, attribute access, `is_comment?` detection.
59
-
60
- **Filter:** `only` and `except` with regex patterns against a fixed segment list.
61
-
62
- **Formatter:** All 4 modes (`:smart`, `:none`, `:camel_case`, `:snake_case`) against varied key strings.
63
-
64
- **Processors:**
65
- - CSV/XLSX/XLS: Parse real fixture files, assert correct Term extraction, language detection, comment handling
66
- - Google Drive: Mock the gem's worksheet interface, test the same parsing logic in isolation
67
-
68
- **TemplateHandler:** Render ERB templates, write to `Dir.mktmpdir`, assert output matches expected content.
69
-
70
- **Writers (all 7):** Feed a fixed Terms array → call writer → assert output files in a temp dir contain expected strings (spot-check key lines, not byte-perfect comparison).
71
-
72
- **Pipeline (`localio_spec.rb`):** CSV fixture → Android + JSON writers → verify files exist with correct content.
73
-
74
- ### Key Test Helpers
75
- - Shared `let(:terms)` factory via RSpec shared contexts
76
- - `Dir.mktmpdir` for output isolation in all writer and template tests
77
- - No network calls; Google Drive mocked at the worksheet interface level
78
-
79
- ## Phase 2: Dependency Updates
80
-
81
- | Gem | Current | Target | Notes |
82
- |-----|---------|--------|-------|
83
- | `google_drive` | `~> 1.0` | `~> 3.0` | API changed; processor needs update |
84
- | `spreadsheet` | `~> 1.0` | `~> 1.3` | Minor updates only |
85
- | `simple_xlsx_reader` | `~> 1.0` | `~> 2.0` | Breaking changes in v2 |
86
- | `nokogiri` | `~> 1.6` | `~> 1.16` | Mostly drop-in |
87
- | `micro-optparse` | `~> 1.2` | remove → stdlib `optparse` | Unmaintained |
88
- | `bundler` | `~> 1.3` | `~> 2.0` | Dev dep |
89
- | Ruby | `>= 1.9.2` | `>= 3.0` | Gemspec update |
90
-
91
- The green test suite from Phase 1 is the safety net — failures after dep updates pinpoint exactly what broke.