ad_localize 3.1.0 → 3.6.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/.github/workflows/ruby.yml +20 -0
- data/.gitignore +2 -1
- data/CHANGELOG.md +41 -1
- data/Gemfile.lock +78 -0
- data/Makefile +11 -0
- data/README.md +57 -3
- data/ad_localize.gemspec +9 -5
- data/lib/ad_localize.rb +2 -0
- data/lib/ad_localize/constant.rb +1 -0
- data/lib/ad_localize/csv_file_manager.rb +20 -3
- data/lib/ad_localize/csv_parser.rb +27 -12
- data/lib/ad_localize/option_handler.rb +6 -1
- data/lib/ad_localize/platform/android_formatter.rb +2 -2
- data/lib/ad_localize/platform/ios_formatter.rb +87 -32
- data/lib/ad_localize/platform/json_formatter.rb +6 -7
- data/lib/ad_localize/platform/platform_formatter.rb +38 -5
- data/lib/ad_localize/platform/yml_formatter.rb +6 -5
- data/lib/ad_localize/runner.rb +17 -7
- data/lib/ad_localize/version.rb +1 -1
- metadata +45 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 736260ad38d18773bf3b8ed6441534bb3467f49edeae2335c7ec5b8742f934e9
|
4
|
+
data.tar.gz: 38cb4f5d8647cc997dc2eb0c784b42469ae5dbb51aad9ba8f19f97907654a181
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5448a25049abad18258c563bd84809a3f38cfefa54a60ace5c80fd7f214af81dcb30effb3a1d907962e6fb7d5707de322159e7361ef80ae01925124914d1a9ac
|
7
|
+
data.tar.gz: a139d77e6c76386493c3cb8d7d39aaf2c3a9526cba30a05b9aff2adaaccf326cb71303919a888da7329b4d56bef72f51211b0ee7fd3aa21e1641e0156ea0461e
|
@@ -0,0 +1,20 @@
|
|
1
|
+
name: Ruby
|
2
|
+
|
3
|
+
on: [push, pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
build:
|
7
|
+
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
|
10
|
+
steps:
|
11
|
+
- uses: actions/checkout@v1
|
12
|
+
- name: Set up Ruby 2.6
|
13
|
+
uses: actions/setup-ruby@v1
|
14
|
+
with:
|
15
|
+
ruby-version: 2.6.x
|
16
|
+
- name: Build and test with Rake
|
17
|
+
run: |
|
18
|
+
gem install bundler
|
19
|
+
bundle install --jobs 4 --retry 3
|
20
|
+
bundle exec rake
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -4,9 +4,50 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
|
+
## [3.6.0] - 2020-06-23
|
8
|
+
### Added
|
9
|
+
- add documentation for service account usage by [@sjcqs](https://github.com/sjcqs)
|
10
|
+
- add compatibility with activesupport 6 by [@Hugo-Hache](https://github.com/Hugo-Hache)
|
11
|
+
|
12
|
+
### Changed
|
13
|
+
|
14
|
+
### Fixed
|
15
|
+
|
16
|
+
## [3.5.0] - 2020-05-12
|
17
|
+
### Added
|
18
|
+
- add support for private spreadsheet using google service acccount by [@sjcqs](https://github.com/sjcqs). Fixes [#31](https://github.com/applidium/ad_localize/issues/31)
|
19
|
+
- add makefile for easier testing by [@felginep](https://github.com/felginep)
|
20
|
+
|
21
|
+
### Changed
|
22
|
+
- improve error message to have useful information in case of google spreadsheet use by [@felginep](https://github.com/felginep). Fixes [#27](https://github.com/applidium/ad_localize/issues/27)
|
23
|
+
- platform folder is no longer generated when there is only one platform selected. The files are directly generated in the output path. By [@felginep](https://github.com/felginep). Fixes [#29](https://github.com/applidium/ad_localize/issues/29)
|
24
|
+
- raise error when google spreadsheet key is invalid by [@felginep](https://github.com/felginep)
|
25
|
+
|
26
|
+
### Fixed
|
27
|
+
- auto escape strings in Localizable.strings by [@felginep](https://github.com/felginep). Fixes [#26](https://github.com/applidium/ad_localize/issues/26)
|
28
|
+
- trim keys to prevent user error by [@felginep](https://github.com/felginep). Fixes [#16](https://github.com/applidium/ad_localize/issues/16)
|
29
|
+
|
30
|
+
## [3.4.0] - 2019-02-10
|
31
|
+
### Added
|
32
|
+
- Rails folks, [@epaillous](https://github.com/epaillous) has improved the YAML support. You can now have multi-level wording.
|
33
|
+
|
34
|
+
## [3.3.0] - 2019-02-10
|
35
|
+
### Added
|
36
|
+
- improve React support using keys with dots to generate nested JSON files by [@epaillous](https://github.com/epaillous)
|
37
|
+
|
38
|
+
## [3.2.0] - 2019-12-10
|
39
|
+
### Added
|
40
|
+
- Add tests to compare reference exports by [@felginep](https://github.com/felginep)
|
41
|
+
- [iOS only] Handle [adaptive strings](https://developer.apple.com/documentation/foundation/nsstring/1413104-variantfittingpresentationwidth) by [@felginep](https://github.com/felginep)
|
42
|
+
|
43
|
+
### Changed
|
44
|
+
- Fix issue with Info.plist format by [@felginep](https://github.com/felginep)
|
45
|
+
- Do not export plurals for android when there are no values by [@felginep](https://github.com/felginep)
|
46
|
+
|
7
47
|
## [3.1.0] - 2019-09-30
|
8
48
|
### Added
|
9
49
|
- [iOS only] Info.plist generation support by [@felginep](https://github.com/felginep)
|
50
|
+
|
10
51
|
### Changed
|
11
52
|
- No more warning log for empty lines by [@felginep](https://github.com/felginep)
|
12
53
|
|
@@ -27,4 +68,3 @@ TODO
|
|
27
68
|
|
28
69
|
## [0.1.0] - 2016-04-25
|
29
70
|
TODO
|
30
|
-
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
ad_localize (3.5.0)
|
5
|
+
activesupport (>= 5.2, < 7.0)
|
6
|
+
colorize (~> 0.8)
|
7
|
+
googleauth (~> 0.12)
|
8
|
+
nokogiri (~> 1.10)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: https://rubygems.org/
|
12
|
+
specs:
|
13
|
+
activesupport (6.0.3.1)
|
14
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
15
|
+
i18n (>= 0.7, < 2)
|
16
|
+
minitest (~> 5.1)
|
17
|
+
tzinfo (~> 1.1)
|
18
|
+
zeitwerk (~> 2.2, >= 2.2.2)
|
19
|
+
addressable (2.7.0)
|
20
|
+
public_suffix (>= 2.0.2, < 5.0)
|
21
|
+
ansi (1.5.0)
|
22
|
+
builder (3.2.4)
|
23
|
+
byebug (11.1.3)
|
24
|
+
colorize (0.8.1)
|
25
|
+
concurrent-ruby (1.1.6)
|
26
|
+
diffy (3.3.0)
|
27
|
+
faraday (1.0.1)
|
28
|
+
multipart-post (>= 1.2, < 3)
|
29
|
+
googleauth (0.12.0)
|
30
|
+
faraday (>= 0.17.3, < 2.0)
|
31
|
+
jwt (>= 1.4, < 3.0)
|
32
|
+
memoist (~> 0.16)
|
33
|
+
multi_json (~> 1.11)
|
34
|
+
os (>= 0.9, < 2.0)
|
35
|
+
signet (~> 0.14)
|
36
|
+
i18n (1.8.2)
|
37
|
+
concurrent-ruby (~> 1.0)
|
38
|
+
jwt (2.2.1)
|
39
|
+
memoist (0.16.2)
|
40
|
+
mini_portile2 (2.4.0)
|
41
|
+
minitest (5.14.0)
|
42
|
+
minitest-reporters (1.4.2)
|
43
|
+
ansi
|
44
|
+
builder
|
45
|
+
minitest (>= 5.0)
|
46
|
+
ruby-progressbar
|
47
|
+
multi_json (1.14.1)
|
48
|
+
multipart-post (2.1.1)
|
49
|
+
nokogiri (1.10.9)
|
50
|
+
mini_portile2 (~> 2.4.0)
|
51
|
+
os (1.1.0)
|
52
|
+
public_suffix (4.0.5)
|
53
|
+
rake (12.3.3)
|
54
|
+
ruby-progressbar (1.10.1)
|
55
|
+
signet (0.14.0)
|
56
|
+
addressable (~> 2.3)
|
57
|
+
faraday (>= 0.17.3, < 2.0)
|
58
|
+
jwt (>= 1.5, < 3.0)
|
59
|
+
multi_json (~> 1.10)
|
60
|
+
thread_safe (0.3.6)
|
61
|
+
tzinfo (1.2.7)
|
62
|
+
thread_safe (~> 0.1)
|
63
|
+
zeitwerk (2.3.0)
|
64
|
+
|
65
|
+
PLATFORMS
|
66
|
+
ruby
|
67
|
+
|
68
|
+
DEPENDENCIES
|
69
|
+
ad_localize!
|
70
|
+
bundler (>= 1.12.0, < 3.0.0)
|
71
|
+
byebug (~> 11.0)
|
72
|
+
diffy (~> 3.3)
|
73
|
+
minitest (~> 5.11)
|
74
|
+
minitest-reporters (~> 1.3)
|
75
|
+
rake (~> 12.3)
|
76
|
+
|
77
|
+
BUNDLED WITH
|
78
|
+
2.1.4
|
data/Makefile
ADDED
data/README.md
CHANGED
@@ -29,15 +29,31 @@ $ gem install ad_localize
|
|
29
29
|
$ bundle exec ad_localize -h
|
30
30
|
```
|
31
31
|
|
32
|
-
* Export wording from a google
|
32
|
+
* Export wording from a google spreadsheet, using the file key. Make sure to enable _Allow external access_ in sharing options.
|
33
33
|
```
|
34
34
|
$ bundle exec ad_localize -k <your-spreadsheet-drive-key>
|
35
35
|
```
|
36
|
-
|
36
|
+
|
37
|
+
* Export wording from a google spreadsheet, using the file key and specifying a sheet (useful when your file has multiple sheets)
|
37
38
|
```
|
38
39
|
$ bundle exec ad_localize -k <your-spreadsheet-drive-key> -s <your-specific-sheet-id>
|
39
40
|
```
|
40
41
|
|
42
|
+
* Export wording from a private google spreadsheet using a Google Cloud Service Account.
|
43
|
+
1. Create a GCloud Service Account:
|
44
|
+
- Go to [Google Cloud Console](https://console.cloud.google.com/)
|
45
|
+
- Either create a new project or use an existing one (when using Firebase, a GCloud project is created)
|
46
|
+
- Go to *IAM & Admin / Service Account* and create a new service account.
|
47
|
+
- Store the created `client-secret.json` (in a password manager for example)
|
48
|
+
2. Enable Google Drive API for the projet
|
49
|
+
- Go to *API / Library* and enable the **Drive API** there.
|
50
|
+
3. Add the service account to a spreadsheet.
|
51
|
+
- In *IAM & Admin / Service Account*, the service account's email is listed. Invite it to the spreadsheet to export.
|
52
|
+
```
|
53
|
+
$ export GCLOUD_CLIENT_SECRET=$(cat <client-secret.json>)
|
54
|
+
$ bundle exec ad_localize -k <your-spreadsheet-drive-key> -a
|
55
|
+
```
|
56
|
+
|
41
57
|
* Only generate wording files for the specified platforms
|
42
58
|
```
|
43
59
|
$ bundle exec ad_localize -o ios
|
@@ -62,10 +78,11 @@ $ bundle exec ad_localize -d
|
|
62
78
|
| favorites | Mes favoris | My favorites |
|
63
79
|
| from_to | du %1$@ au %2$@ | from %1$@ to %2$@ |
|
64
80
|
|
65
|
-
- Any column after the `key` column will be considered as a locale column (except from the optional `comment columns)
|
81
|
+
- Any column after the `key` column will be considered as a locale column (except from the optional `comment columns)
|
66
82
|
- Keys should be written in Android format : [a-z0-9_]+
|
67
83
|
- Format specifiers must be numeroted if there are more than one in a translation string (eg: "%1$@ %2$@'s report").
|
68
84
|
|
85
|
+
|
69
86
|
#### Comment columns
|
70
87
|
|
71
88
|
In iOS (and only iOS) you can add a comment to a missing translation.
|
@@ -111,6 +128,8 @@ exports/
|
|
111
128
|
└── fr.yml
|
112
129
|
```
|
113
130
|
|
131
|
+
NB: If you select only one platform, the wording files will directly be generated in the output path. The output path is the `exports` folder in the current directory by default and you can change it using the option `-o`.
|
132
|
+
|
114
133
|
## Plurals
|
115
134
|
|
116
135
|
Plurals are supported for iOS and Android.
|
@@ -177,6 +196,41 @@ Every key that matches the following formats will be added to the `InfoPlist.str
|
|
177
196
|
|
178
197
|
Source: https://developer.apple.com/documentation/bundleresources/information_property_list
|
179
198
|
|
199
|
+
## Adaptive strings
|
200
|
+
|
201
|
+
_Only for iOS._
|
202
|
+
|
203
|
+
Syntax for adaptive keys in the CSV file:
|
204
|
+
|
205
|
+
key##{20}
|
206
|
+
key##{25}
|
207
|
+
key##{50}
|
208
|
+
…
|
209
|
+
|
210
|
+
Sample of iOS output in .stringsdict
|
211
|
+
|
212
|
+
```xml
|
213
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
214
|
+
<plist>
|
215
|
+
<dict>
|
216
|
+
<key>start_countdown</key>
|
217
|
+
<dict>
|
218
|
+
<key>NSStringVariableWidthRuleType</key>
|
219
|
+
<dict>
|
220
|
+
<key>20</key>
|
221
|
+
<string>Start</string>
|
222
|
+
<key>25</key>
|
223
|
+
<string>Start countdown</string>
|
224
|
+
<key>50</key>
|
225
|
+
<string>Start countdown</string>
|
226
|
+
</dict>
|
227
|
+
</dict>
|
228
|
+
</dict>
|
229
|
+
</plist>
|
230
|
+
```
|
231
|
+
|
232
|
+
Source: https://developer.apple.com/documentation/foundation/nsstring/1413104-variantfittingpresentationwidth
|
233
|
+
|
180
234
|
## Development
|
181
235
|
|
182
236
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/ad_localize.gemspec
CHANGED
@@ -19,14 +19,16 @@ Gem::Specification.new do |spec|
|
|
19
19
|
'Nicolas Braun',
|
20
20
|
'Corentin Huard',
|
21
21
|
'Claire Peyron',
|
22
|
-
'Claire Dufetrelle'
|
22
|
+
'Claire Dufetrelle',
|
23
|
+
'Pierre Felgines',
|
24
|
+
'Satyan Jacquens'
|
23
25
|
]
|
24
26
|
spec.email = %w(joanna.vigne@fabernovel.com hugo.hache@fabernovel.com edouard.siegel@fabernovel.com)
|
25
27
|
|
26
28
|
spec.summary = %q{AdLocalize helps with mobile and web applications wording}
|
27
29
|
spec.description = %q{AdLocalize produces localization files from platform agnostic wording.
|
28
30
|
Supported wording format : CSV. Supported export format: iOS, Android, JSON and YAML}
|
29
|
-
spec.homepage = 'https://
|
31
|
+
spec.homepage = 'https://github.com/applidium/ad_localize'
|
30
32
|
|
31
33
|
# Specify which files should be added to the gem when it is released.
|
32
34
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
@@ -42,10 +44,12 @@ Gem::Specification.new do |spec|
|
|
42
44
|
spec.add_development_dependency 'minitest', '~> 5.11'
|
43
45
|
spec.add_development_dependency 'byebug', '~> 11.0'
|
44
46
|
spec.add_development_dependency 'minitest-reporters', '~> 1.3'
|
47
|
+
spec.add_development_dependency 'diffy', '~> 3.3'
|
45
48
|
|
46
|
-
spec.add_dependency 'activesupport', '
|
47
|
-
spec.add_dependency 'nokogiri', '~> 1.
|
49
|
+
spec.add_dependency 'activesupport', '>= 5.2', '< 7.0'
|
50
|
+
spec.add_dependency 'nokogiri', '~> 1.10'
|
48
51
|
spec.add_dependency 'colorize', '~> 0.8'
|
52
|
+
spec.add_dependency 'googleauth', '~> 0.12'
|
49
53
|
|
50
|
-
spec.required_ruby_version
|
54
|
+
spec.required_ruby_version = '~> 2.3'
|
51
55
|
end
|
data/lib/ad_localize.rb
CHANGED
data/lib/ad_localize/constant.rb
CHANGED
@@ -8,13 +8,20 @@ module AdLocalize
|
|
8
8
|
end
|
9
9
|
|
10
10
|
# Returns the downloaded file name (it is located in the current directory)
|
11
|
-
def download_from_drive(key, sheet)
|
12
|
-
LOGGER.log(:info, :
|
11
|
+
def download_from_drive(key, sheet, use_service_account=false)
|
12
|
+
LOGGER.log(:info, :green, "Downloading file from google drive...")
|
13
13
|
download_string_path = "./#{key}.csv"
|
14
14
|
begin
|
15
15
|
File.open(download_string_path, "wb") do |saved_file|
|
16
|
+
download_url = drive_download_url(key, sheet)
|
17
|
+
headers = {}
|
18
|
+
if use_service_account
|
19
|
+
LOGGER.log(:debug, :green, "Using a service account...")
|
20
|
+
token = service_account_access_token()
|
21
|
+
headers["Authorization"] = "#{token["token_type"]} #{token["access_token"]}"
|
22
|
+
end
|
16
23
|
# the following "open" is provided by open-uri
|
17
|
-
open(
|
24
|
+
open(download_url, "rb", headers) do |read_file|
|
18
25
|
saved_file.write(read_file.read)
|
19
26
|
end
|
20
27
|
File.basename saved_file
|
@@ -42,6 +49,16 @@ module AdLocalize
|
|
42
49
|
query_id = sheet ? "gid=#{sheet}" : "id=#{key}"
|
43
50
|
"https://docs.google.com/spreadsheets/d/#{key}/export?format=csv&#{query_id}"
|
44
51
|
end
|
52
|
+
private
|
53
|
+
def service_account_access_token()
|
54
|
+
scope = "https://www.googleapis.com/auth/drive.readonly"
|
55
|
+
json_key_io = StringIO.new ENV["GCLOUD_CLIENT_SECRET"]
|
56
|
+
authorizer = Google::Auth::ServiceAccountCredentials.make_creds(
|
57
|
+
json_key_io: json_key_io,
|
58
|
+
scope: scope
|
59
|
+
)
|
60
|
+
authorizer.fetch_access_token!
|
61
|
+
end
|
45
62
|
end
|
46
63
|
end
|
47
64
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module AdLocalize
|
2
2
|
class CsvParser
|
3
3
|
CSV_WORDING_KEYS_COLUMN = "key"
|
4
|
-
PLURAL_KEY_REGEXP = /\#\#\{(
|
4
|
+
PLURAL_KEY_REGEXP = /\#\#\{([A-Za-z]+)\}/
|
5
|
+
ADAPTIVE_KEY_REGEXP = /\#\#\{(\d+)\}/
|
5
6
|
INFO_PLIST_KEY_REGEXP = /(NS.+UsageDescription)|(CF.+Name)/ # see https://developer.apple.com/documentation/bundleresources/information_property_list
|
6
7
|
|
7
8
|
attr_accessor :locales
|
@@ -57,7 +58,7 @@ module AdLocalize
|
|
57
58
|
if locales.empty?
|
58
59
|
raise 'NO DETECTED LOCALES'
|
59
60
|
else
|
60
|
-
LOGGER.log(:debug, :
|
61
|
+
LOGGER.log(:debug, :green, "DETECTED LOCALES : #{locales.join(', ')}")
|
61
62
|
end
|
62
63
|
end
|
63
64
|
|
@@ -78,6 +79,11 @@ module AdLocalize
|
|
78
79
|
"[#{locale.upcase}] Plural key ---> plural_identifier : #{key_infos.dig(:plural_identifier)}, key : #{current_key}",
|
79
80
|
"[#{locale.upcase}] Missing translation for #{current_key} (#{key_infos.dig(:plural_identifier)})")
|
80
81
|
value = { key_infos.dig(:plural_identifier) => row[locale] || default_wording(locale, "#{current_key} (#{key_infos.dig(:plural_identifier)})") }
|
82
|
+
elsif key_infos.dig(:numeral_key) == Constant::ADAPTIVE_KEY_SYMBOL
|
83
|
+
trace_wording(row[locale],
|
84
|
+
"[#{locale.upcase}] Adaptive key ---> adaptive_identifier : #{key_infos.dig(:adaptive_identifier)}, key : #{current_key}",
|
85
|
+
"[#{locale.upcase}] Missing translation for #{current_key} (#{key_infos.dig(:adaptive_identifier)})")
|
86
|
+
value = { key_infos.dig(:adaptive_identifier) => row[locale] || default_wording(locale, "#{current_key} (#{key_infos.dig(:adaptive_identifier)})") }
|
81
87
|
elsif key_infos.dig(:numeral_key) == Constant::INFO_PLIST_KEY_SYMBOL
|
82
88
|
trace_wording(row[locale], "[#{locale.upcase}] Info.plist key ---> #{current_key}", "[#{locale.upcase}] Missing translation for #{current_key}")
|
83
89
|
value = row[locale] || default_wording(locale, current_key)
|
@@ -93,27 +99,36 @@ module AdLocalize
|
|
93
99
|
end
|
94
100
|
|
95
101
|
def parse_key(row)
|
96
|
-
key = row.field(CSV_WORDING_KEYS_COLUMN)
|
102
|
+
key = row.field(CSV_WORDING_KEYS_COLUMN).strip
|
97
103
|
plural_prefix = key.match(PLURAL_KEY_REGEXP)
|
98
104
|
plural_identifier = nil
|
99
105
|
invalid_plural = false
|
100
106
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
end
|
107
|
-
else
|
107
|
+
adaptive_prefix = key.match(ADAPTIVE_KEY_REGEXP)
|
108
|
+
adaptive_identifier = nil
|
109
|
+
invalid_adaptive = false
|
110
|
+
|
111
|
+
if plural_prefix != nil
|
108
112
|
numeral_key = Constant::PLURAL_KEY_SYMBOL
|
109
113
|
key = plural_prefix.pre_match
|
110
114
|
plural_identifier = plural_prefix.captures&.first
|
111
115
|
LOGGER.log(:debug, :red, "Invalid key #{key}") if key.nil?
|
112
116
|
LOGGER.log(:debug, :red, "Empty plural prefix!") if plural_identifier.nil?
|
113
117
|
invalid_plural = plural_identifier.nil?
|
118
|
+
elsif adaptive_prefix != nil
|
119
|
+
numeral_key = Constant::ADAPTIVE_KEY_SYMBOL
|
120
|
+
key = adaptive_prefix.pre_match
|
121
|
+
adaptive_identifier = adaptive_prefix.captures&.first
|
122
|
+
LOGGER.log(:debug, :red, "Invalid key #{key}") if key.nil?
|
123
|
+
LOGGER.log(:debug, :red, "Empty adaptive prefix!") if adaptive_identifier.nil?
|
124
|
+
invalid_adaptive = adaptive_identifier.nil?
|
125
|
+
elsif key.match(INFO_PLIST_KEY_REGEXP) != nil
|
126
|
+
numeral_key = Constant::INFO_PLIST_KEY_SYMBOL
|
127
|
+
else
|
128
|
+
numeral_key = Constant::SINGULAR_KEY_SYMBOL
|
114
129
|
end
|
115
130
|
|
116
|
-
(key.nil? or invalid_plural) ? nil : { key: key.to_sym, numeral_key: numeral_key, plural_identifier: plural_identifier&.to_sym }
|
131
|
+
(key.nil? or invalid_plural or invalid_adaptive) ? nil : { key: key.to_sym, numeral_key: numeral_key, plural_identifier: plural_identifier&.to_sym, adaptive_identifier: adaptive_identifier&.to_sym }
|
117
132
|
end
|
118
133
|
|
119
134
|
def default_wording(locale, key)
|
@@ -122,7 +137,7 @@ module AdLocalize
|
|
122
137
|
|
123
138
|
def trace_wording(wording, present_message, missing_message)
|
124
139
|
if wording
|
125
|
-
LOGGER.log(:debug, :
|
140
|
+
LOGGER.log(:debug, :green, present_message)
|
126
141
|
else
|
127
142
|
LOGGER.log(:debug, :yellow, missing_message)
|
128
143
|
end
|
@@ -20,11 +20,15 @@ module AdLocalize
|
|
20
20
|
end
|
21
21
|
opts.on("-k", "--drive-key #{GOOGLE_DRIVE_DOCUMENT_ID.dig(:length)}_characters", String, "Use google drive spreadsheets") do |key|
|
22
22
|
is_valid_drive_key = !!(key =~ GOOGLE_DRIVE_DOCUMENT_ID.dig(:regexp)) && (key.size >= GOOGLE_DRIVE_DOCUMENT_ID.dig(:length))
|
23
|
-
|
23
|
+
raise ArgumentError.new("Invalid google drive spreadsheet key \"#{key}\"") unless is_valid_drive_key
|
24
|
+
args[:drive_key] = key
|
24
25
|
end
|
25
26
|
opts.on("-s", "--drive-sheet SHEET_ID", String, "Use a specific sheet id for Google Drive spreadsheets with several sheets") do |value|
|
26
27
|
args[:sheet_id] = value
|
27
28
|
end
|
29
|
+
opts.on("-a", "--use-service-account", "Use a Google Cloud Service Account to access the file. An GCLOUD_CLIENT_SECRET environment variable containting the client_secret.json content is needed.") do
|
30
|
+
args[:use_service_account] = true
|
31
|
+
end
|
28
32
|
opts.on("-o", "--only platform1,platform2", Array, "Only generate localisation files for the specified platforms. Supported platforms : #{Constant::SUPPORTED_PLATFORMS.join(', ')}") do |platforms|
|
29
33
|
args[:only] = filter_option_args("-o", platforms) { |platform| !!Constant::SUPPORTED_PLATFORMS.index(platform) }
|
30
34
|
end
|
@@ -44,6 +48,7 @@ module AdLocalize
|
|
44
48
|
LOGGER.log(:error, :red, "Missing argument for option #{e.args.join(',')}")
|
45
49
|
rescue ArgumentError => e
|
46
50
|
LOGGER.log(:error, :red, e.message)
|
51
|
+
raise e
|
47
52
|
end
|
48
53
|
args
|
49
54
|
end
|
@@ -57,7 +57,7 @@ module AdLocalize::Platform
|
|
57
57
|
add_wording_text_to_xml(plural_text, xml)
|
58
58
|
}
|
59
59
|
end
|
60
|
-
}
|
60
|
+
} unless plural_hash.values.all? &:empty?
|
61
61
|
end
|
62
62
|
|
63
63
|
def add_wording_text_to_xml(wording_text, xml)
|
@@ -67,4 +67,4 @@ module AdLocalize::Platform
|
|
67
67
|
)
|
68
68
|
end
|
69
69
|
end
|
70
|
-
end
|
70
|
+
end
|
@@ -6,10 +6,16 @@ module AdLocalize::Platform
|
|
6
6
|
|
7
7
|
def export(locale, data, export_extension = nil, substitution_format = nil)
|
8
8
|
create_locale_dir(locale)
|
9
|
-
|
9
|
+
all_symbols = [
|
10
|
+
AdLocalize::Constant::PLURAL_KEY_SYMBOL,
|
11
|
+
AdLocalize::Constant::ADAPTIVE_KEY_SYMBOL,
|
12
|
+
AdLocalize::Constant::SINGULAR_KEY_SYMBOL,
|
13
|
+
AdLocalize::Constant::INFO_PLIST_KEY_SYMBOL
|
14
|
+
]
|
15
|
+
all_symbols.each do |numeral_key|
|
10
16
|
numeral_data = data.select {|key, wording| wording.dig(locale.to_sym)&.key? numeral_key}
|
11
17
|
if numeral_data.empty?
|
12
|
-
AdLocalize::LOGGER.log(:info, :
|
18
|
+
AdLocalize::LOGGER.log(:info, :green, "[#{locale.upcase}] no #{numeral_key.to_s} keys were found to generate the file")
|
13
19
|
else
|
14
20
|
send("write_#{numeral_key}", locale, numeral_data)
|
15
21
|
end
|
@@ -36,53 +42,102 @@ module AdLocalize::Platform
|
|
36
42
|
)
|
37
43
|
end
|
38
44
|
|
45
|
+
def write_plural(locale, plurals)
|
46
|
+
locale = locale.to_sym
|
47
|
+
|
48
|
+
append_to_localizable_plist(locale) do |xml|
|
49
|
+
plurals.each do |wording_key, translations|
|
50
|
+
xml.key wording_key
|
51
|
+
xml.dict {
|
52
|
+
xml.key "NSStringLocalizedFormatKey"
|
53
|
+
xml.string "%\#@key@"
|
54
|
+
xml.key "key"
|
55
|
+
xml.dict {
|
56
|
+
xml.key "NSStringFormatSpecTypeKey"
|
57
|
+
xml.string "NSStringPluralRuleType"
|
58
|
+
xml.key "NSStringFormatValueTypeKey"
|
59
|
+
xml.string "d"
|
60
|
+
translations[locale][AdLocalize::Constant::PLURAL_KEY_SYMBOL].each do |wording_type, wording_value|
|
61
|
+
xml.key wording_type
|
62
|
+
xml.string wording_value
|
63
|
+
end
|
64
|
+
}
|
65
|
+
}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
AdLocalize::LOGGER.log(:debug, :green, "iOS plural [#{locale}] ---> DONE!")
|
69
|
+
end
|
70
|
+
|
71
|
+
def write_adaptive(locale, adaptives)
|
72
|
+
locale = locale.to_sym
|
73
|
+
|
74
|
+
append_to_localizable_plist(locale) do |xml|
|
75
|
+
adaptives.each do |wording_key, translations|
|
76
|
+
xml.key wording_key
|
77
|
+
xml.dict {
|
78
|
+
xml.key "NSStringVariableWidthRuleType"
|
79
|
+
xml.dict {
|
80
|
+
translations[locale][AdLocalize::Constant::ADAPTIVE_KEY_SYMBOL].each do |wording_type, wording_value|
|
81
|
+
xml.key wording_type
|
82
|
+
xml.string wording_value
|
83
|
+
end
|
84
|
+
}
|
85
|
+
}
|
86
|
+
end
|
87
|
+
end
|
88
|
+
AdLocalize::LOGGER.log(:debug, :black, "iOS adaptive [#{locale}] ---> DONE!")
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def escape_quotes_if_needed(value)
|
94
|
+
value.gsub(/(?<!\\)\"/, "\\\"") # match " unless there is a \ before
|
95
|
+
end
|
96
|
+
|
39
97
|
def write_localizable(locale:, singulars:, wording_type:, filename:)
|
40
98
|
locale = locale.to_sym
|
41
99
|
|
42
100
|
singulars.each do |key, locales_wording|
|
43
101
|
value = locales_wording.dig(locale, wording_type)
|
102
|
+
value = escape_quotes_if_needed(value)
|
44
103
|
comment = locales_wording.dig(locale, AdLocalize::Constant::COMMENT_KEY_SYMBOL)
|
45
104
|
export_dir(locale).join(filename).open("a") do |file|
|
46
|
-
line =
|
105
|
+
line = ""
|
106
|
+
if wording_type == AdLocalize::Constant::INFO_PLIST_KEY_SYMBOL
|
107
|
+
line = %(#{key} = "#{value}";)
|
108
|
+
else
|
109
|
+
line = %("#{key}" = "#{value}";)
|
110
|
+
end
|
47
111
|
line << " // #{comment}" unless comment.nil?
|
48
112
|
line << "\n"
|
49
113
|
file.puts line
|
50
114
|
end
|
51
115
|
end
|
52
|
-
AdLocalize::LOGGER.log(:debug, :
|
116
|
+
AdLocalize::LOGGER.log(:debug, :green, "iOS #{wording_type} [#{locale}] ---> DONE!")
|
53
117
|
end
|
54
118
|
|
55
|
-
def
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
xml.string "d"
|
72
|
-
translations[locale][AdLocalize::Constant::PLURAL_KEY_SYMBOL].each do |wording_type, wording_value|
|
73
|
-
xml.key wording_type
|
74
|
-
xml.string wording_value
|
75
|
-
end
|
76
|
-
}
|
77
|
-
}
|
78
|
-
end
|
119
|
+
def append_to_localizable_plist(locale)
|
120
|
+
filename = export_dir(locale).join(AdLocalize::Constant::IOS_PLURAL_EXPORT_FILENAME)
|
121
|
+
xml_doc = nil
|
122
|
+
if File.exist?(filename)
|
123
|
+
xml_content = Nokogiri::XML(open(filename)) do |config|
|
124
|
+
config.default_xml.noblanks # minimify xml
|
125
|
+
end
|
126
|
+
xml_doc = Nokogiri::XML::Builder.with(xml_content.css('plist>dict').first) do |xml|
|
127
|
+
yield(xml)
|
128
|
+
end
|
129
|
+
else
|
130
|
+
xml_doc = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
|
131
|
+
xml.plist {
|
132
|
+
xml.dict {
|
133
|
+
yield(xml)
|
134
|
+
}
|
79
135
|
}
|
80
|
-
|
136
|
+
end
|
81
137
|
end
|
82
|
-
|
138
|
+
filename.open("w") do |file|
|
83
139
|
file.puts xml_doc.to_xml(indent: 4)
|
84
140
|
end
|
85
|
-
AdLocalize::LOGGER.log(:debug, :black, "iOS plural [#{locale}] ---> DONE!")
|
86
141
|
end
|
87
142
|
end
|
88
|
-
end
|
143
|
+
end
|
@@ -4,15 +4,14 @@ module AdLocalize::Platform
|
|
4
4
|
:json
|
5
5
|
end
|
6
6
|
|
7
|
-
def export(locale, data, export_extension = "json", substitution_format = "
|
8
|
-
|
7
|
+
def export(locale, data, export_extension = "json", substitution_format = "react")
|
8
|
+
locale = locale.to_sym
|
9
|
+
json_data = build_platform_data_splitting_on_dots(locale, data)
|
10
|
+
platform_dir.join("#{locale.to_s}.#{export_extension}").open("w") do |file|
|
9
11
|
file.puts json_data.to_json
|
10
12
|
end
|
11
|
-
end
|
12
13
|
|
13
|
-
|
14
|
-
def ios_converter(value)
|
15
|
-
value.gsub(/(%(?!)?(\d+\$)?[@isd])/, "VARIABLE_TO_SET")
|
14
|
+
AdLocalize::LOGGER.log(:debug, :green, "JSON [#{locale}] ---> DONE!")
|
16
15
|
end
|
17
16
|
end
|
18
|
-
end
|
17
|
+
end
|
@@ -5,12 +5,13 @@ module AdLocalize::Platform
|
|
5
5
|
OPTIONS = {output_path: ".."}
|
6
6
|
|
7
7
|
attr_accessor :platform_dir
|
8
|
-
attr_reader :default_locale, :output_path
|
8
|
+
attr_reader :default_locale, :output_path, :add_intermediate_platform_dir
|
9
9
|
|
10
|
-
def initialize(default_locale, output_path)
|
10
|
+
def initialize(default_locale, output_path, add_intermediate_platform_dir)
|
11
11
|
@default_locale = default_locale.to_sym
|
12
12
|
@output_path = output_path # Must be set before platform_dir
|
13
|
-
@platform_dir = export_base_directory.join(platform.to_s)
|
13
|
+
@platform_dir = add_intermediate_platform_dir ? export_base_directory.join(platform.to_s) : export_base_directory
|
14
|
+
@add_intermediate_platform_dir = add_intermediate_platform_dir
|
14
15
|
create_platform_dir
|
15
16
|
end
|
16
17
|
|
@@ -39,7 +40,7 @@ module AdLocalize::Platform
|
|
39
40
|
yield(formatted_data, file)
|
40
41
|
end
|
41
42
|
|
42
|
-
AdLocalize::LOGGER.log(:debug, :
|
43
|
+
AdLocalize::LOGGER.log(:debug, :green, "#{platform.to_s.upcase} [#{locale}] ---> DONE!")
|
43
44
|
end
|
44
45
|
|
45
46
|
protected
|
@@ -52,7 +53,7 @@ module AdLocalize::Platform
|
|
52
53
|
end
|
53
54
|
|
54
55
|
def create_platform_dir
|
55
|
-
if platform_dir.directory?
|
56
|
+
if platform_dir.directory? && add_intermediate_platform_dir
|
56
57
|
FileUtils.rm_rf("#{platform_dir}/.", secure: true)
|
57
58
|
else
|
58
59
|
platform_dir.mkpath
|
@@ -72,5 +73,37 @@ module AdLocalize::Platform
|
|
72
73
|
export_dir(locale).mkdir
|
73
74
|
end
|
74
75
|
end
|
76
|
+
|
77
|
+
def build_platform_data_splitting_on_dots(locale, data)
|
78
|
+
data.each_with_object({}) do |(key, wording), hash_acc|
|
79
|
+
hash_acc[locale.to_s] = {} unless hash_acc.key? locale.to_s
|
80
|
+
keys = key.to_s.split('.')
|
81
|
+
hash = hash_acc[locale.to_s]
|
82
|
+
keys.each_with_index do |inner_key, index|
|
83
|
+
if index === keys.count - 1
|
84
|
+
fill_hash(wording, locale, hash, inner_key)
|
85
|
+
else
|
86
|
+
if hash[inner_key].nil?
|
87
|
+
hash[inner_key] = {}
|
88
|
+
end
|
89
|
+
hash = hash[inner_key]
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def fill_hash(wording, locale, hash, key)
|
96
|
+
if wording.dig(locale)&.key? :singular
|
97
|
+
value = wording.dig(locale, :singular)
|
98
|
+
hash[key.to_s] = value
|
99
|
+
end
|
100
|
+
if wording.dig(locale)&.key? :plural
|
101
|
+
hash[key.to_s] = {}
|
102
|
+
wording.dig(locale, :plural).each do |plural_type, plural_text|
|
103
|
+
value = plural_text
|
104
|
+
hash[key.to_s][plural_type.to_s] = value
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
75
108
|
end
|
76
109
|
end
|
@@ -5,14 +5,15 @@ module AdLocalize::Platform
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def export(locale, data, export_extension = "yml", substitution_format = "yml")
|
8
|
-
|
8
|
+
locale = locale.to_sym
|
9
|
+
yml_data = build_platform_data_splitting_on_dots(locale, data)
|
10
|
+
|
11
|
+
platform_dir.join("#{locale.to_s}.#{export_extension}").open("w") do |file|
|
9
12
|
file.puts yml_data.to_yaml
|
10
13
|
end
|
11
|
-
end
|
12
14
|
|
13
|
-
|
14
|
-
def ios_converter(value)
|
15
|
-
value.gsub(/(%(?!)?(\d+\$)?[@isd])/, "VARIABLE_TO_SET")
|
15
|
+
AdLocalize::LOGGER.log(:debug, :green, "YAML [#{locale}] ---> DONE!")
|
16
16
|
end
|
17
|
+
|
17
18
|
end
|
18
19
|
end
|
data/lib/ad_localize/runner.rb
CHANGED
@@ -7,7 +7,7 @@ module AdLocalize
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def run(args = ARGV)
|
10
|
-
LOGGER.log(:info, :
|
10
|
+
LOGGER.log(:info, :green, "OPTIONS : #{options}")
|
11
11
|
input_files = (args + [options.dig(:drive_key)]).compact # drive_key can be nil
|
12
12
|
if input_files.length.zero?
|
13
13
|
LOGGER.log(:error, :red, "No CSV to parse. Use option -h to see how to use this script")
|
@@ -15,26 +15,36 @@ module AdLocalize
|
|
15
15
|
file_to_parse = args.first
|
16
16
|
LOGGER.log(:warn, :yellow, "Only one CSV can be treated - the priority goes to #{file_to_parse}") if input_files.length > 1
|
17
17
|
if args.empty?
|
18
|
-
options[:drive_file] = CsvFileManager.download_from_drive(options.dig(:drive_key), options.dig(:sheet_id))
|
18
|
+
options[:drive_file] = CsvFileManager.download_from_drive(options.dig(:drive_key), options.dig(:sheet_id), options.dig(:use_service_account))
|
19
19
|
file_to_parse = options.dig(:drive_file)
|
20
20
|
end
|
21
|
-
CsvFileManager.csv?(file_to_parse)
|
21
|
+
if CsvFileManager.csv?(file_to_parse)
|
22
|
+
export(file_to_parse)
|
23
|
+
else
|
24
|
+
LOGGER.log(:error, :red, "#{file_to_parse} is not a csv. Make sure to enable \"Allow external access\" in sharing options.")
|
25
|
+
end
|
22
26
|
CsvFileManager.delete_drive_file(options[:drive_file]) if options[:drive_file]
|
23
27
|
end
|
24
28
|
end
|
25
29
|
|
26
30
|
private
|
31
|
+
|
27
32
|
def export(file)
|
28
|
-
LOGGER.log(:info, :
|
29
|
-
LOGGER.log(:info, :
|
33
|
+
LOGGER.log(:info, :green, "********* PARSING #{file} *********")
|
34
|
+
LOGGER.log(:info, :green, "Extracting data from file...")
|
30
35
|
parser = CsvParser.new
|
31
36
|
data = parser.extract_data(file)
|
32
37
|
if data.empty?
|
33
38
|
LOGGER.log(:error, :red, "No data were found in the file - check if there is a key column in the file")
|
34
39
|
else
|
35
40
|
export_platforms = options.dig(:only) || Constant::SUPPORTED_PLATFORMS
|
41
|
+
add_intermediate_platform_dir = export_platforms.length > 1
|
36
42
|
export_platforms.each do |platform|
|
37
|
-
platform_formatter = "AdLocalize::Platform::#{platform.to_s.camelize}Formatter".constantize.new(
|
43
|
+
platform_formatter = "AdLocalize::Platform::#{platform.to_s.camelize}Formatter".constantize.new(
|
44
|
+
parser.locales.first,
|
45
|
+
options.dig(:output_path),
|
46
|
+
add_intermediate_platform_dir
|
47
|
+
)
|
38
48
|
parser.locales.each do |locale|
|
39
49
|
platform_formatter.export(locale, data)
|
40
50
|
end
|
@@ -42,4 +52,4 @@ module AdLocalize
|
|
42
52
|
end
|
43
53
|
end
|
44
54
|
end
|
45
|
-
end
|
55
|
+
end
|
data/lib/ad_localize/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ad_localize
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Edouard Siegel
|
@@ -15,6 +15,8 @@ authors:
|
|
15
15
|
- Corentin Huard
|
16
16
|
- Claire Peyron
|
17
17
|
- Claire Dufetrelle
|
18
|
+
- Pierre Felgines
|
19
|
+
- Satyan Jacquens
|
18
20
|
autorequire:
|
19
21
|
bindir: exe
|
20
22
|
cert_chain: []
|
@@ -97,45 +99,53 @@ dependencies:
|
|
97
99
|
- !ruby/object:Gem::Version
|
98
100
|
version: '1.3'
|
99
101
|
- !ruby/object:Gem::Dependency
|
100
|
-
name:
|
102
|
+
name: diffy
|
101
103
|
requirement: !ruby/object:Gem::Requirement
|
102
104
|
requirements:
|
103
105
|
- - "~>"
|
104
106
|
- !ruby/object:Gem::Version
|
105
|
-
version: '
|
107
|
+
version: '3.3'
|
108
|
+
type: :development
|
109
|
+
prerelease: false
|
110
|
+
version_requirements: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - "~>"
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '3.3'
|
115
|
+
- !ruby/object:Gem::Dependency
|
116
|
+
name: activesupport
|
117
|
+
requirement: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
106
119
|
- - ">="
|
107
120
|
- !ruby/object:Gem::Version
|
108
|
-
version:
|
121
|
+
version: '5.2'
|
122
|
+
- - "<"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '7.0'
|
109
125
|
type: :runtime
|
110
126
|
prerelease: false
|
111
127
|
version_requirements: !ruby/object:Gem::Requirement
|
112
128
|
requirements:
|
113
|
-
- - "~>"
|
114
|
-
- !ruby/object:Gem::Version
|
115
|
-
version: '4.2'
|
116
129
|
- - ">="
|
117
130
|
- !ruby/object:Gem::Version
|
118
|
-
version:
|
131
|
+
version: '5.2'
|
132
|
+
- - "<"
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '7.0'
|
119
135
|
- !ruby/object:Gem::Dependency
|
120
136
|
name: nokogiri
|
121
137
|
requirement: !ruby/object:Gem::Requirement
|
122
138
|
requirements:
|
123
139
|
- - "~>"
|
124
140
|
- !ruby/object:Gem::Version
|
125
|
-
version: '1.
|
126
|
-
- - ">="
|
127
|
-
- !ruby/object:Gem::Version
|
128
|
-
version: 1.8.2
|
141
|
+
version: '1.10'
|
129
142
|
type: :runtime
|
130
143
|
prerelease: false
|
131
144
|
version_requirements: !ruby/object:Gem::Requirement
|
132
145
|
requirements:
|
133
146
|
- - "~>"
|
134
147
|
- !ruby/object:Gem::Version
|
135
|
-
version: '1.
|
136
|
-
- - ">="
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: 1.8.2
|
148
|
+
version: '1.10'
|
139
149
|
- !ruby/object:Gem::Dependency
|
140
150
|
name: colorize
|
141
151
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,6 +160,20 @@ dependencies:
|
|
150
160
|
- - "~>"
|
151
161
|
- !ruby/object:Gem::Version
|
152
162
|
version: '0.8'
|
163
|
+
- !ruby/object:Gem::Dependency
|
164
|
+
name: googleauth
|
165
|
+
requirement: !ruby/object:Gem::Requirement
|
166
|
+
requirements:
|
167
|
+
- - "~>"
|
168
|
+
- !ruby/object:Gem::Version
|
169
|
+
version: '0.12'
|
170
|
+
type: :runtime
|
171
|
+
prerelease: false
|
172
|
+
version_requirements: !ruby/object:Gem::Requirement
|
173
|
+
requirements:
|
174
|
+
- - "~>"
|
175
|
+
- !ruby/object:Gem::Version
|
176
|
+
version: '0.12'
|
153
177
|
description: |-
|
154
178
|
AdLocalize produces localization files from platform agnostic wording.
|
155
179
|
Supported wording format : CSV. Supported export format: iOS, Android, JSON and YAML
|
@@ -162,12 +186,15 @@ executables:
|
|
162
186
|
extensions: []
|
163
187
|
extra_rdoc_files: []
|
164
188
|
files:
|
189
|
+
- ".github/workflows/ruby.yml"
|
165
190
|
- ".gitignore"
|
166
191
|
- ".travis.yml"
|
167
192
|
- CHANGELOG.md
|
168
193
|
- CODE_OF_CONDUCT.md
|
169
194
|
- Gemfile
|
195
|
+
- Gemfile.lock
|
170
196
|
- LICENSE.txt
|
197
|
+
- Makefile
|
171
198
|
- README.md
|
172
199
|
- Rakefile
|
173
200
|
- ad_localize.gemspec
|
@@ -188,7 +215,7 @@ files:
|
|
188
215
|
- lib/ad_localize/platform/yml_formatter.rb
|
189
216
|
- lib/ad_localize/runner.rb
|
190
217
|
- lib/ad_localize/version.rb
|
191
|
-
homepage: https://
|
218
|
+
homepage: https://github.com/applidium/ad_localize
|
192
219
|
licenses:
|
193
220
|
- MIT
|
194
221
|
metadata: {}
|
@@ -207,7 +234,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
207
234
|
- !ruby/object:Gem::Version
|
208
235
|
version: '0'
|
209
236
|
requirements: []
|
210
|
-
rubygems_version: 3.0.
|
237
|
+
rubygems_version: 3.0.3
|
211
238
|
signing_key:
|
212
239
|
specification_version: 4
|
213
240
|
summary: AdLocalize helps with mobile and web applications wording
|