fastlane-plugin-localio 0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 567d3c7d22bdcbc694d4f7c796152270dd5f9d2460107a461540420f45e1d270
4
+ data.tar.gz: 07fc8436a3ab1a9986252b6b7da2b9701915e05c90f06b47ae17ea68f9e0aa68
5
+ SHA512:
6
+ metadata.gz: 724f0852d3f9919d160d5525297fc91ea14fb41e51c7551535064f4ef5d617e9a8276004fc457eecf7c891178e2a84ad7a97e77f337c0ccb73d21fdf88bb06b3
7
+ data.tar.gz: 22effa0e8033297b3d67b074b4cddab91a78717a653bba9922ae1f8345874b17669a07a18e874b5382285329f19c136f7ebfe4519ec8fa7707f996ed031ec17c
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Nacho Lopez
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,188 @@
1
+ # fastlane-plugin-localio
2
+
3
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/mrmans0n/fastlane-plugin-localio/blob/main/LICENSE)
4
+ [![Gem Version](https://badge.fury.io/rb/fastlane-plugin-localio.svg)](https://badge.fury.io/rb/fastlane-plugin-localio)
5
+
6
+ Fastlane plugin for the [localio](https://github.com/mrmans0n/localio) gem. Generates localization files from spreadsheets (Google Drive, XLS, XLSX, CSV) for multiple platforms (Android, iOS, Swift, Rails, JSON, Java Properties, RESX, Twine).
7
+
8
+ ## Installation
9
+
10
+ Add to your project's `Gemfile`:
11
+
12
+ ```ruby
13
+ gem "fastlane-plugin-localio"
14
+ ```
15
+
16
+ Or install via fastlane:
17
+
18
+ ```bash
19
+ fastlane add_plugin localio
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ The plugin supports two modes of operation.
25
+
26
+ ### Mode 1: Locfile-based (simple)
27
+
28
+ If you already have a `Locfile` configured for localio, just point to it:
29
+
30
+ ```ruby
31
+ localio(locfile: "path/to/Locfile")
32
+ ```
33
+
34
+ ### Mode 2: Inline parameters
35
+
36
+ Configure everything directly in your Fastfile without needing a separate Locfile:
37
+
38
+ ```ruby
39
+ localio(
40
+ platform: "android",
41
+ source: "xlsx",
42
+ source_path: "translations.xlsx",
43
+ source_sheet: "Sheet1",
44
+ output_path: "app/src/main/res",
45
+ formatting: "smart"
46
+ )
47
+ ```
48
+
49
+ ## Source types
50
+
51
+ ### XLSX
52
+
53
+ ```ruby
54
+ localio(
55
+ platform: "android",
56
+ source: "xlsx",
57
+ source_path: "translations.xlsx",
58
+ source_sheet: "Sheet1",
59
+ output_path: "app/src/main/res"
60
+ )
61
+ ```
62
+
63
+ ### XLS
64
+
65
+ ```ruby
66
+ localio(
67
+ platform: "ios",
68
+ source: "xls",
69
+ source_path: "translations.xls",
70
+ source_sheet: "Translations",
71
+ output_path: "Resources"
72
+ )
73
+ ```
74
+
75
+ ### CSV
76
+
77
+ ```ruby
78
+ localio(
79
+ platform: "json",
80
+ source: "csv",
81
+ source_path: "translations.csv",
82
+ output_path: "locales",
83
+ source_options: { column_separator: ";" }
84
+ )
85
+ ```
86
+
87
+ ### Google Drive
88
+
89
+ ```ruby
90
+ localio(
91
+ platform: "android",
92
+ source: "google_drive",
93
+ source_path: "My Translations Spreadsheet",
94
+ source_sheet: "Sheet1",
95
+ source_options: {
96
+ client_id: "your_client_id",
97
+ client_secret: "your_client_secret",
98
+ client_token: "path/to/token.json"
99
+ },
100
+ output_path: "app/src/main/res"
101
+ )
102
+ ```
103
+
104
+ ## Platforms
105
+
106
+ | Platform | Key | Description |
107
+ |----------|-----|-------------|
108
+ | Android | `android` | Generates `strings.xml` resource files |
109
+ | iOS | `ios` | Generates `.strings` files |
110
+ | Swift | `swift` | Generates Swift constants |
111
+ | Rails | `rails` | Generates YAML locale files |
112
+ | JSON | `json` | Generates JSON locale files |
113
+ | Java Properties | `java_properties` | Generates `.properties` files |
114
+ | RESX | `resx` | Generates `.resx` resource files |
115
+ | Twine | `twine` | Generates Twine format files |
116
+
117
+ ## Platform options
118
+
119
+ Pass platform-specific options via the `platform_options` parameter:
120
+
121
+ ```ruby
122
+ localio(
123
+ platform: "swift",
124
+ source: "xlsx",
125
+ source_path: "translations.xlsx",
126
+ output_path: "Generated",
127
+ platform_options: {
128
+ create_constants: false,
129
+ override_default: "es"
130
+ }
131
+ )
132
+ ```
133
+
134
+ ## Formatting
135
+
136
+ Control how translation keys are formatted:
137
+
138
+ | Style | Key |
139
+ |-------|-----|
140
+ | Smart (default) | `smart` |
141
+ | Snake Case | `snake_case` |
142
+ | Camel Case | `camel_case` |
143
+ | None | `none` |
144
+
145
+ ```ruby
146
+ localio(
147
+ platform: "android",
148
+ source: "xlsx",
149
+ source_path: "translations.xlsx",
150
+ output_path: "res",
151
+ formatting: "camel_case"
152
+ )
153
+ ```
154
+
155
+ ## Filtering
156
+
157
+ Use `only` and `except` to filter which keys are processed:
158
+
159
+ ```ruby
160
+ localio(
161
+ platform: "android",
162
+ source: "xlsx",
163
+ source_path: "translations.xlsx",
164
+ output_path: "res",
165
+ only: '[\[][a][\]]',
166
+ except: '[\[][b][\]]'
167
+ )
168
+ ```
169
+
170
+ ## Parameters
171
+
172
+ | Key | Description | Default |
173
+ |-----|-------------|---------|
174
+ | `locfile` | Path to an existing Locfile | |
175
+ | `platform` | Target platform | |
176
+ | `source` | Source type (google_drive, xls, xlsx, csv) | |
177
+ | `source_path` | Path to source file or spreadsheet title | |
178
+ | `source_sheet` | Sheet name or index | |
179
+ | `source_options` | Additional source options hash | |
180
+ | `output_path` | Output directory | |
181
+ | `formatting` | Key formatting style | `smart` |
182
+ | `platform_options` | Additional platform options hash | |
183
+ | `only` | Regex filter to include only matching keys | |
184
+ | `except` | Regex filter to exclude matching keys | |
185
+
186
+ ## License
187
+
188
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,174 @@
1
+ require 'fastlane/action'
2
+ require_relative '../helper/localio_helper'
3
+
4
+ module Fastlane
5
+ module Actions
6
+ class LocalioAction < Action
7
+ def self.run(params)
8
+ if params[:locfile]
9
+ run_with_locfile(params[:locfile])
10
+ else
11
+ run_with_params(params)
12
+ end
13
+ end
14
+
15
+ def self.run_with_locfile(locfile_path)
16
+ Helper::LocalioHelper.require_localio!
17
+
18
+ UI.message("Running localio with Locfile: #{locfile_path}")
19
+
20
+ unless File.exist?(locfile_path)
21
+ UI.user_error!("Locfile not found at path: #{locfile_path}")
22
+ end
23
+
24
+ Dir.chdir(File.dirname(File.expand_path(locfile_path))) do
25
+ filename = File.basename(locfile_path)
26
+ config = ::Locfile.new
27
+ config.instance_eval(File.read(filename), filename)
28
+ ::Localio.from_configuration(config)
29
+ end
30
+ end
31
+
32
+ def self.run_with_params(params)
33
+ unless params[:platform]
34
+ UI.user_error!("Parameter 'platform' is required when not using a Locfile")
35
+ end
36
+
37
+ unless params[:source]
38
+ UI.user_error!("Parameter 'source' is required when not using a Locfile")
39
+ end
40
+
41
+ Helper::LocalioHelper.require_localio!
42
+
43
+ UI.message("Running localio with inline configuration (platform: #{params[:platform]}, source: #{params[:source]})")
44
+
45
+ config = Helper::LocalioHelper.build_configuration(params)
46
+ ::Localio.from_configuration(config)
47
+ end
48
+
49
+ def self.description
50
+ "Generates localization files from spreadsheets using the localio gem"
51
+ end
52
+
53
+ def self.authors
54
+ ["Nacho Lopez"]
55
+ end
56
+
57
+ def self.return_value
58
+ nil
59
+ end
60
+
61
+ def self.details
62
+ "Reads translation data from spreadsheets (Google Drive, XLS, XLSX, CSV) " \
63
+ "and generates platform-specific localization files using the localio gem. " \
64
+ "Supports two modes: Locfile-based (simple) and inline parameters (no Locfile needed)."
65
+ end
66
+
67
+ def self.available_options
68
+ [
69
+ FastlaneCore::ConfigItem.new(
70
+ key: :locfile,
71
+ env_name: "LOCALIO_LOCFILE",
72
+ description: "Path to an existing Locfile. If provided, all other parameters are ignored",
73
+ optional: true,
74
+ type: String
75
+ ),
76
+ FastlaneCore::ConfigItem.new(
77
+ key: :platform,
78
+ env_name: "LOCALIO_PLATFORM",
79
+ description: "Target platform (android, ios, swift, rails, json, java_properties, resx, twine)",
80
+ optional: true,
81
+ type: String,
82
+ verify_block: proc do |value|
83
+ unless Helper::LocalioHelper::VALID_PLATFORMS.include?(value.to_sym)
84
+ UI.user_error!("Invalid platform '#{value}'. Valid: #{Helper::LocalioHelper::VALID_PLATFORMS.join(', ')}")
85
+ end
86
+ end
87
+ ),
88
+ FastlaneCore::ConfigItem.new(
89
+ key: :source,
90
+ env_name: "LOCALIO_SOURCE",
91
+ description: "Source type (google_drive, xls, xlsx, csv)",
92
+ optional: true,
93
+ type: String,
94
+ verify_block: proc do |value|
95
+ unless Helper::LocalioHelper::VALID_SOURCES.include?(value.to_sym)
96
+ UI.user_error!("Invalid source '#{value}'. Valid: #{Helper::LocalioHelper::VALID_SOURCES.join(', ')}")
97
+ end
98
+ end
99
+ ),
100
+ FastlaneCore::ConfigItem.new(
101
+ key: :source_path,
102
+ env_name: "LOCALIO_SOURCE_PATH",
103
+ description: "Path to the source file (XLS/XLSX/CSV) or spreadsheet title (Google Drive)",
104
+ optional: true,
105
+ type: String
106
+ ),
107
+ FastlaneCore::ConfigItem.new(
108
+ key: :source_sheet,
109
+ env_name: "LOCALIO_SOURCE_SHEET",
110
+ description: "Sheet name or index within the spreadsheet",
111
+ optional: true,
112
+ type: String
113
+ ),
114
+ FastlaneCore::ConfigItem.new(
115
+ key: :source_options,
116
+ env_name: "LOCALIO_SOURCE_OPTIONS",
117
+ description: "Additional source options as a hash (merged with source_path/source_sheet)",
118
+ optional: true,
119
+ type: Hash
120
+ ),
121
+ FastlaneCore::ConfigItem.new(
122
+ key: :output_path,
123
+ env_name: "LOCALIO_OUTPUT_PATH",
124
+ description: "Output directory for generated localization files",
125
+ optional: true,
126
+ type: String
127
+ ),
128
+ FastlaneCore::ConfigItem.new(
129
+ key: :formatting,
130
+ env_name: "LOCALIO_FORMATTING",
131
+ description: "Key formatting style (smart, snake_case, camel_case, none)",
132
+ optional: true,
133
+ default_value: "smart",
134
+ type: String,
135
+ verify_block: proc do |value|
136
+ unless Helper::LocalioHelper::VALID_FORMATTING.include?(value.to_sym)
137
+ UI.user_error!("Invalid formatting '#{value}'. Valid: #{Helper::LocalioHelper::VALID_FORMATTING.join(', ')}")
138
+ end
139
+ end
140
+ ),
141
+ FastlaneCore::ConfigItem.new(
142
+ key: :platform_options,
143
+ env_name: "LOCALIO_PLATFORM_OPTIONS",
144
+ description: "Additional platform options as a hash (e.g. { create_constants: false })",
145
+ optional: true,
146
+ type: Hash
147
+ ),
148
+ FastlaneCore::ConfigItem.new(
149
+ key: :only,
150
+ env_name: "LOCALIO_ONLY",
151
+ description: "Regex filter to include only matching keys",
152
+ optional: true,
153
+ type: String
154
+ ),
155
+ FastlaneCore::ConfigItem.new(
156
+ key: :except,
157
+ env_name: "LOCALIO_EXCEPT",
158
+ description: "Regex filter to exclude matching keys",
159
+ optional: true,
160
+ type: String
161
+ )
162
+ ]
163
+ end
164
+
165
+ def self.is_supported?(platform)
166
+ true
167
+ end
168
+
169
+ def self.category
170
+ :misc
171
+ end
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,59 @@
1
+ require 'fastlane_core/ui/ui'
2
+
3
+ module Fastlane
4
+ module Helper
5
+ class LocalioHelper
6
+ VALID_PLATFORMS = %i[android ios swift rails json java_properties resx twine].freeze
7
+ VALID_SOURCES = %i[google_drive xls xlsx csv].freeze
8
+ VALID_FORMATTING = %i[smart snake_case camel_case none].freeze
9
+
10
+ def self.require_localio!
11
+ return if defined?(::Locfile) && ::Locfile.method_defined?(:platform)
12
+
13
+ begin
14
+ require 'localio'
15
+ rescue LoadError
16
+ UI.user_error!("The 'localio' gem is required. Add `gem 'localio'` to your Gemfile.")
17
+ end
18
+ end
19
+
20
+ def self.build_configuration(params)
21
+ config = Locfile.new
22
+
23
+ platform_sym = params[:platform].to_sym
24
+ platform_opts = params[:platform_options] || {}
25
+ config.platform(platform_sym, platform_opts)
26
+
27
+ source_sym = params[:source].to_sym
28
+ source_opts = build_source_options(params)
29
+ config.source(source_sym, source_opts)
30
+
31
+ config.output_path(params[:output_path]) if params[:output_path]
32
+ config.formatting(params[:formatting].to_sym) if params[:formatting]
33
+
34
+ config.only(keys: params[:only]) if params[:only]
35
+ config.except(keys: params[:except]) if params[:except]
36
+
37
+ config
38
+ end
39
+
40
+ def self.build_source_options(params)
41
+ opts = {}
42
+ opts.merge!(params[:source_options]) if params[:source_options]
43
+
44
+ case params[:source].to_sym
45
+ when :google_drive
46
+ opts[:spreadsheet] ||= params[:source_path]
47
+ opts[:sheet] ||= params[:source_sheet]
48
+ when :xls, :xlsx
49
+ opts[:path] ||= params[:source_path]
50
+ opts[:sheet] ||= params[:source_sheet]
51
+ when :csv
52
+ opts[:path] ||= params[:source_path]
53
+ end
54
+
55
+ opts
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,5 @@
1
+ module Fastlane
2
+ module Localio
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,13 @@
1
+ require 'fastlane/plugin/localio/version'
2
+
3
+ module Fastlane
4
+ module Localio
5
+ def self.all_classes
6
+ Dir[File.expand_path('*/{actions,helper}/*.rb', File.dirname(__FILE__))]
7
+ end
8
+ end
9
+ end
10
+
11
+ Fastlane::Localio.all_classes.each do |current|
12
+ require current
13
+ end
metadata ADDED
@@ -0,0 +1,148 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fastlane-plugin-localio
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Nacho Lopez
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-03-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: localio
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: fastlane
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '2.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '2.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: Generates localization files from spreadsheets using the localio gem.
112
+ Supports Google Drive, XLS, XLSX, and CSV sources with output for Android, iOS,
113
+ Swift, Rails, JSON, Java Properties, RESX, and Twine.
114
+ email: nacho@nlopez.io
115
+ executables: []
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - LICENSE
120
+ - README.md
121
+ - lib/fastlane/plugin/localio.rb
122
+ - lib/fastlane/plugin/localio/actions/localio_action.rb
123
+ - lib/fastlane/plugin/localio/helper/localio_helper.rb
124
+ - lib/fastlane/plugin/localio/version.rb
125
+ homepage: https://github.com/mrmans0n/fastlane-plugin-localio
126
+ licenses:
127
+ - MIT
128
+ metadata: {}
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '2.6'
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ requirements: []
144
+ rubygems_version: 3.5.22
145
+ signing_key:
146
+ specification_version: 4
147
+ summary: Fastlane plugin for the localio gem
148
+ test_files: []