poeditor-cli 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +114 -25
- data/lib/poeditor.rb +3 -4
- data/lib/poeditor/commands/command.rb +2 -2
- data/lib/poeditor/commands/help_command.rb +1 -1
- data/lib/poeditor/commands/{export_command.rb → pull_command.rb} +9 -7
- data/lib/poeditor/configuration.rb +73 -0
- data/lib/poeditor/{core/exporter.rb → core.rb} +34 -10
- data/lib/poeditor/version.rb +1 -1
- metadata +5 -6
- data/lib/poeditor/configurations/export_configuration.rb +0 -46
- data/lib/poeditor/core/formatter.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6fbda657a807e50916c5267d8fce2241ada1d793
|
4
|
+
data.tar.gz: d9fdd116dd94f743e15ba290b1ab25ba24712ce3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9fadb20d2c78f046d02aca7ad03dd1d7eaa7543d7bb46facff717366491944f7c81afe0b49c3b4a206b57b657ea81b7ee4411a448dc0cca5d6fae1de8f4c842e
|
7
|
+
data.tar.gz: 3a485b69c6e1d4ad31b0daef4fa5ca6f73aa199cc12c7b210631ad2a0efa644ff5a3ff217f4bbf5ef02f8086a84f03a67aa74a49d2ee4a8949f1cd462053a60f
|
data/README.md
CHANGED
@@ -1,49 +1,138 @@
|
|
1
1
|
# poeditor-cli
|
2
2
|
|
3
|
-
[![Gem](https://img.shields.io/gem/v/
|
3
|
+
[![Gem](https://img.shields.io/gem/v/poeditor-cli.svg)](https://rubygems.org/gems/poeditor-cli)
|
4
4
|
[![Build Status](https://travis-ci.org/StyleShare/poeditor-cli.svg?branch=master)](https://travis-ci.org/StyleShare/poeditor-cli)
|
5
5
|
|
6
6
|
Command line application for [POEditor](https://poeditor.com).
|
7
7
|
|
8
|
-
<img
|
8
|
+
<img alt="poeditor-cli" src="https://cloud.githubusercontent.com/assets/931655/22522393/c6d3db32-e8fe-11e6-97f1-259445bc04d1.png" width="680">
|
9
|
+
|
10
|
+
## Features
|
11
|
+
|
12
|
+
* Exporting translation files directly from POEditor to your project directory
|
13
|
+
* Mapping translation directory dynamically
|
14
|
+
* Replacing `%s` with `%@` for Apple strings
|
15
|
+
* We use it on our products
|
16
|
+
|
17
|
+
## Installation
|
18
|
+
|
19
|
+
```console
|
20
|
+
$ [sudo] gem install poeditor-cli
|
21
|
+
```
|
9
22
|
|
10
23
|
## Usage
|
11
24
|
|
12
|
-
|
25
|
+
A single command will do almost everything for you.
|
26
|
+
|
27
|
+
```console
|
28
|
+
$ poeditor pull
|
29
|
+
```
|
30
|
+
|
31
|
+
Before you do this, you have to create a **poeditor.yml** file. This is a configuration file for poeditor-cli. Here is an example **`poeditor.yml`**:
|
32
|
+
|
33
|
+
```yaml
|
34
|
+
api_key: YOUR_API_KEY
|
35
|
+
project_id: PROJECT_ID
|
36
|
+
type: apple_strings
|
37
|
+
tags: [ios]
|
38
|
+
|
39
|
+
languages: [en, ko, ja, zh-Hans, zh-Hant, fr, es]
|
40
|
+
language_alias:
|
41
|
+
zh: zh-Hans
|
42
|
+
|
43
|
+
path: Resources/{LANGUAGE}.lproj/Localizable.strings
|
44
|
+
path_replace:
|
45
|
+
en: Resources/Base.lproj/Localizable.strings
|
46
|
+
```
|
47
|
+
|
48
|
+
> See **[Example `poeditor.yml` files](#example-poeditoryml-files)** section for more examples.
|
49
|
+
|
50
|
+
* **api_key**
|
51
|
+
|
52
|
+
Your POEditor API key. You can check it on [POEditor API Access](https://poeditor.com/account/api). Use such like `$MY_API_KEY` to use environment variable.
|
53
|
+
|
54
|
+
* **project_id**
|
55
|
+
|
56
|
+
POEditor project ID. You can check this value on the web browser's address bar. (For example: `https://poeditor.com/projects/view?id=XXXXX`) Use such like `$MY_PROJECT_ID` to use environment variable.
|
57
|
+
|
58
|
+
* **languages**
|
59
|
+
|
60
|
+
Language codes to export. Use the language codes that your project uses. For example, use `zh-Hans` for Xcode project and `zh-rCN` for Android project even though POEditor uses `zh-CN` for simplified chinese.
|
61
|
+
|
62
|
+
* **language_alias** *(Optional)*
|
63
|
+
|
64
|
+
Specify this value to copy the translation file to another language. For example, `zh` is same with the translation of `zh-Hans` or `zh-rCN`. In this case, you can specify the `language_alias` value as follows:
|
13
65
|
|
14
|
-
|
66
|
+
```yaml
|
67
|
+
languages: [ko, ja, zh-Hans, zh-Hant]
|
68
|
+
language_alias:
|
69
|
+
zh: zh-Hans
|
70
|
+
```
|
71
|
+
|
72
|
+
* **path**
|
73
|
+
|
74
|
+
The path for translation files to be downloaded. Each values of `languages` will be used for filling `{LANGUAGE}` placeholder.
|
75
|
+
|
76
|
+
* **path_replace** *(Optional)*
|
77
|
+
|
78
|
+
Specify this value to enforce the translation file path. For example, Android uses `values/strings.xml` for default language and `values-ko/strings.xml` or `values-ja/strings.xml` for others. In this case, you can specify the `path_replace` as follows:
|
15
79
|
|
16
80
|
```yaml
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
81
|
+
path: myapp/src/main/res/values-{LANGUAGE}/strings.xml
|
82
|
+
path_replace:
|
83
|
+
en: myapp/src/main/res/values/strings.xml
|
84
|
+
```
|
85
|
+
|
86
|
+
* **type**
|
87
|
+
|
88
|
+
Translation file format. (po, pot, mo, xls, csv, resw, resx, android_strings, apple_strings, xliff, properties, key_value_json, json, xmb, xtb)
|
89
|
+
|
90
|
+
* **tags** *(Optional)*
|
91
|
+
|
92
|
+
Terms which contain whole tags will be exported. (`&&`)
|
93
|
+
|
94
|
+
## Example `poeditor.yml` files
|
95
|
+
|
96
|
+
* Xcode project
|
97
|
+
|
98
|
+
```yaml
|
99
|
+
api_key: $POEDITOR_API_KEY # from envvar
|
100
|
+
project_id: $POEDITOR_PROJECT_ID # from envvar
|
21
101
|
type: apple_strings
|
22
|
-
tags: [ios]
|
102
|
+
tags: [ios]
|
103
|
+
|
104
|
+
languages: [en, ko, ja, zh-Hans, zh-Hant]
|
105
|
+
path: Resources/{LANGUAGE}.lproj/Localizable.strings
|
23
106
|
```
|
24
107
|
|
25
|
-
|
26
|
-
|---|---|
|
27
|
-
| `api_key` | Your POEditor API key. You can check it on [POEditor API Access](https://poeditor.com/account/api). |
|
28
|
-
| `project_id` | POEditor project ID. You can check this value on the web browser's address bar.<br />For example: `https://poeditor.com/projects/view?id=XXXXX` |
|
29
|
-
| `languages` | Language codes to export. Use your project's language code.<br />For example, use `zh-Hans` if you're working on Xcode project even though POEditor uses `zh-CN` for simplified chinese. |
|
30
|
-
| `path` | The path for translation files to be downloaded. Each values of `languages` will be used for filling `{LANGUAGE}` placeholder. |
|
31
|
-
| `type` | Translation file format. (po, pot, mo, xls, csv, resw, resx, android_strings, apple_strings, xliff, properties, key_value_json, json, xmb, xtb) |
|
32
|
-
| `tags` | (Optional) Terms which contain whole tags will be exported. (`&&`) |
|
108
|
+
* Android project
|
33
109
|
|
34
|
-
|
110
|
+
```yaml
|
111
|
+
api_key: $POEDITOR_API_KEY # from envvar
|
112
|
+
project_id: $POEDITOR_PROJECT_ID # from envvar
|
113
|
+
type: android_strings
|
114
|
+
tags: [android]
|
115
|
+
|
116
|
+
languages: [en, ko, ja, zh-rCN, zh-rTW]
|
35
117
|
|
36
|
-
|
37
|
-
|
118
|
+
path: myapp/src/main/res/values-{LANGUAGE}/strings.xml
|
119
|
+
path_replace:
|
120
|
+
en: myapp/src/main/res/values/strings.xml
|
38
121
|
```
|
39
122
|
|
40
|
-
|
123
|
+
* Projects using gettext
|
41
124
|
|
42
|
-
|
125
|
+
```yaml
|
126
|
+
api_key: $POEDITOR_API_KEY # from envvar
|
127
|
+
project_id: $POEDITOR_PROJECT_ID # from envvar
|
128
|
+
type: po
|
43
129
|
|
44
|
-
|
45
|
-
|
46
|
-
|
130
|
+
languages: [en, ko, ja, zh_Hans, zh_Hant]
|
131
|
+
language_alias:
|
132
|
+
zh: zh_Hans
|
133
|
+
|
134
|
+
path: myservice/translations/{LANGUAGE}/LC_MESSAGES/messages.po
|
135
|
+
```
|
47
136
|
|
48
137
|
## License
|
49
138
|
|
data/lib/poeditor.rb
CHANGED
@@ -9,15 +9,14 @@ module POEditor
|
|
9
9
|
autoload :UI, "poeditor/ui"
|
10
10
|
|
11
11
|
# core
|
12
|
-
autoload :
|
13
|
-
autoload :Formatter, "poeditor/core/formatter"
|
12
|
+
autoload :Core, "poeditor/core"
|
14
13
|
|
15
14
|
# command
|
16
15
|
autoload :Command, "poeditor/commands/command"
|
17
|
-
autoload :
|
16
|
+
autoload :PullCommand, "poeditor/commands/pull_command"
|
18
17
|
autoload :HelpCommand, "poeditor/commands/help_command"
|
19
18
|
autoload :VersionCommand, "poeditor/commands/version_command"
|
20
19
|
|
21
20
|
# configuration
|
22
|
-
autoload :
|
21
|
+
autoload :Configuration, "poeditor/configuration"
|
23
22
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module POEditor
|
2
|
-
class
|
2
|
+
class PullCommand
|
3
3
|
def run(argv)
|
4
4
|
UI.puts "Reading configuration"
|
5
5
|
configuration = get_configuration(argv)
|
6
6
|
UI.puts configuration
|
7
|
-
|
8
|
-
|
7
|
+
client = POEditor::Core.new(configuration)
|
8
|
+
client.pull()
|
9
9
|
end
|
10
10
|
|
11
11
|
# Detects and returns the location of `poeditor.yml` file from the given
|
@@ -23,11 +23,11 @@ module POEditor
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
# Returns {#POEditor::
|
26
|
+
# Returns {#POEditor::Configuration} from the given system arguments.
|
27
27
|
#
|
28
28
|
# @param argv [Array<String>] System arguments
|
29
29
|
#
|
30
|
-
# @return [POEditor::
|
30
|
+
# @return [POEditor::Configuration] The export configuration
|
31
31
|
def get_configuration(argv)
|
32
32
|
config_path = get_configuration_file_path(argv)
|
33
33
|
unless File.exist?(config_path)
|
@@ -37,13 +37,15 @@ Configuration file doesn't exist: #{config_path}.
|
|
37
37
|
}
|
38
38
|
end
|
39
39
|
yaml = YAML.load(File.read(config_path))
|
40
|
-
|
40
|
+
Configuration.new(
|
41
41
|
api_key: get_or_raise(yaml, "api_key"),
|
42
42
|
project_id: get_or_raise(yaml, "project_id"),
|
43
|
-
languages: get_or_raise(yaml, "languages"),
|
44
43
|
type: get_or_raise(yaml, "type"),
|
45
44
|
tags: yaml["tags"],
|
45
|
+
languages: get_or_raise(yaml, "languages"),
|
46
|
+
language_alias: yaml["language_alias"],
|
46
47
|
path: get_or_raise(yaml, "path"),
|
48
|
+
path_replace: yaml["path_replace"],
|
47
49
|
)
|
48
50
|
end
|
49
51
|
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module POEditor
|
2
|
+
class Configuration
|
3
|
+
# @return [String] POEditor API key
|
4
|
+
# @see https://poeditor.com/account/api POEditor API Access
|
5
|
+
attr_accessor :api_key
|
6
|
+
|
7
|
+
# @return [String] POEditor project ID
|
8
|
+
attr_accessor :project_id
|
9
|
+
|
10
|
+
# @return [String] Export file type (po, apple_strings, android_strings)
|
11
|
+
attr_accessor :type
|
12
|
+
|
13
|
+
# @return [Array<String>] Tag filters (optional)
|
14
|
+
attr_accessor :tags
|
15
|
+
|
16
|
+
# @return [Array<String>] The languages codes
|
17
|
+
attr_accessor :languages
|
18
|
+
|
19
|
+
# @return [Hash{Sting => String}] The languages aliases
|
20
|
+
attr_accessor :language_alias
|
21
|
+
|
22
|
+
# @return [String] The path template
|
23
|
+
attr_accessor :path
|
24
|
+
|
25
|
+
# @return [Hash{Sting => String}] The path replacements
|
26
|
+
attr_accessor :path_replace
|
27
|
+
|
28
|
+
def initialize(api_key:, project_id:, type:, tags:nil,
|
29
|
+
languages:, language_alias:nil,
|
30
|
+
path:, path_replace:nil)
|
31
|
+
@api_key = from_env(api_key)
|
32
|
+
@project_id = from_env(project_id.to_s)
|
33
|
+
@type = type
|
34
|
+
@tags = tags || []
|
35
|
+
|
36
|
+
@languages = languages
|
37
|
+
@language_alias = language_alias || {}
|
38
|
+
|
39
|
+
@path = path
|
40
|
+
@path_replace = path_replace || {}
|
41
|
+
end
|
42
|
+
|
43
|
+
def from_env(value)
|
44
|
+
if value.start_with?("$")
|
45
|
+
key = value[1..-1]
|
46
|
+
ENV[key]
|
47
|
+
else
|
48
|
+
value
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_s
|
53
|
+
values = {
|
54
|
+
"type" => self.type,
|
55
|
+
"tags" => self.tags,
|
56
|
+
"languages" => self.languages,
|
57
|
+
"language_alias" => self.language_alias,
|
58
|
+
"path" => self.path,
|
59
|
+
"path_replace" => self.path_replace,
|
60
|
+
}
|
61
|
+
YAML.dump(values)[4..-2]
|
62
|
+
.each_line
|
63
|
+
.map { |line|
|
64
|
+
if line.start_with?("-") or line.start_with?(" ")
|
65
|
+
" #{line}"
|
66
|
+
else
|
67
|
+
" - #{line}"
|
68
|
+
end
|
69
|
+
}
|
70
|
+
.join("")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -2,15 +2,15 @@ require "json"
|
|
2
2
|
require "net/http"
|
3
3
|
|
4
4
|
module POEditor
|
5
|
-
class
|
6
|
-
# @return [POEditor::
|
5
|
+
class Core
|
6
|
+
# @return [POEditor::Configuration] The configuration for export
|
7
7
|
attr_accessor :configuration
|
8
8
|
|
9
|
-
# @param configuration [POEditor::
|
9
|
+
# @param configuration [POEditor::Configuration]
|
10
10
|
def initialize(configuration)
|
11
|
-
unless configuration.is_a?
|
11
|
+
unless configuration.is_a? Configuration
|
12
12
|
raise POEditor::Exception.new \
|
13
|
-
"`configuration` should be an `
|
13
|
+
"`configuration` should be an `Configuration`"
|
14
14
|
end
|
15
15
|
@configuration = configuration
|
16
16
|
end
|
@@ -31,8 +31,8 @@ module POEditor
|
|
31
31
|
return Net::HTTP.post_form(uri, options)
|
32
32
|
end
|
33
33
|
|
34
|
-
#
|
35
|
-
def
|
34
|
+
# Pull translations
|
35
|
+
def pull()
|
36
36
|
UI.puts "\nExport translations"
|
37
37
|
for language in @configuration.languages
|
38
38
|
UI.puts " - Exporting '#{language}'"
|
@@ -41,7 +41,13 @@ module POEditor
|
|
41
41
|
:language => language,
|
42
42
|
:type => @configuration.type,
|
43
43
|
:tags => @configuration.tags)
|
44
|
-
|
44
|
+
write(language, content)
|
45
|
+
|
46
|
+
for alias_to, alias_from in @configuration.language_alias
|
47
|
+
if language == alias_from
|
48
|
+
write(alias_to, content)
|
49
|
+
end
|
50
|
+
end
|
45
51
|
end
|
46
52
|
end
|
47
53
|
|
@@ -83,14 +89,32 @@ module POEditor
|
|
83
89
|
end
|
84
90
|
|
85
91
|
def convert_to_poeditor_language(language)
|
86
|
-
if language.downcase.match(/zh.+hans/)
|
92
|
+
if language.downcase.match(/zh.+(hans|cn)/)
|
87
93
|
'zh-CN'
|
88
|
-
elsif language.downcase.match(/zh.+hant/)
|
94
|
+
elsif language.downcase.match(/zh.+(hant|tw)/)
|
89
95
|
'zh-TW'
|
90
96
|
else
|
91
97
|
language
|
92
98
|
end
|
93
99
|
end
|
94
100
|
|
101
|
+
# Write translation file
|
102
|
+
def write(language, content)
|
103
|
+
path = path_for_language(language)
|
104
|
+
unless File.exist?(path)
|
105
|
+
raise POEditor::Exception.new "#{path} doesn't exist"
|
106
|
+
end
|
107
|
+
File.write(path, content)
|
108
|
+
UI.puts " #{"\xe2\x9c\x93".green} Saved at '#{path}'"
|
109
|
+
end
|
110
|
+
|
111
|
+
def path_for_language(language)
|
112
|
+
if @configuration.path_replace[language]
|
113
|
+
@configuration.path_replace[language]
|
114
|
+
else
|
115
|
+
@configuration.path.gsub("{LANGUAGE}", language)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
95
119
|
end
|
96
120
|
end
|
data/lib/poeditor/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: poeditor-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Suyeol Jeon
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-02-
|
11
|
+
date: 2017-02-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorize
|
@@ -36,12 +36,11 @@ files:
|
|
36
36
|
- bin/poeditor
|
37
37
|
- lib/poeditor.rb
|
38
38
|
- lib/poeditor/commands/command.rb
|
39
|
-
- lib/poeditor/commands/export_command.rb
|
40
39
|
- lib/poeditor/commands/help_command.rb
|
40
|
+
- lib/poeditor/commands/pull_command.rb
|
41
41
|
- lib/poeditor/commands/version_command.rb
|
42
|
-
- lib/poeditor/
|
43
|
-
- lib/poeditor/core
|
44
|
-
- lib/poeditor/core/formatter.rb
|
42
|
+
- lib/poeditor/configuration.rb
|
43
|
+
- lib/poeditor/core.rb
|
45
44
|
- lib/poeditor/exception.rb
|
46
45
|
- lib/poeditor/ui.rb
|
47
46
|
- lib/poeditor/version.rb
|
@@ -1,46 +0,0 @@
|
|
1
|
-
module POEditor
|
2
|
-
class ExportConfiguration
|
3
|
-
# @return [String] POEditor API key
|
4
|
-
# @see https://poeditor.com/account/api POEditor API Access
|
5
|
-
attr_accessor :api_key
|
6
|
-
|
7
|
-
# @return [String] POEditor project ID
|
8
|
-
attr_accessor :project_id
|
9
|
-
|
10
|
-
# @return [Array<String>] The languages codes
|
11
|
-
attr_accessor :languages
|
12
|
-
|
13
|
-
# @return [String] Export file type (po, apple_strings, android_strings)
|
14
|
-
attr_accessor :type
|
15
|
-
|
16
|
-
# @return [Array<String>] Tag filters (optional)
|
17
|
-
attr_accessor :tags
|
18
|
-
|
19
|
-
attr_accessor :path
|
20
|
-
|
21
|
-
def initialize(api_key:, project_id:, languages:, type:, tags:nil, path:)
|
22
|
-
@api_key = api_key
|
23
|
-
@project_id = project_id
|
24
|
-
@languages = languages
|
25
|
-
@type = type
|
26
|
-
@tags = tags or []
|
27
|
-
@path = path
|
28
|
-
end
|
29
|
-
|
30
|
-
def default_path(type)
|
31
|
-
Formatter.cls(type).default_path
|
32
|
-
end
|
33
|
-
|
34
|
-
def to_s
|
35
|
-
values = {
|
36
|
-
"api_key" => self.api_key,
|
37
|
-
"project_id" => self.project_id,
|
38
|
-
"languages" => self.languages,
|
39
|
-
"type" => self.type,
|
40
|
-
"tags" => self.tags,
|
41
|
-
"path" => self.path,
|
42
|
-
}
|
43
|
-
values.map { |key, value| " - #{key}: #{value}" }.join "\n"
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module POEditor
|
2
|
-
class Formatter
|
3
|
-
def self.build_path(path_template, language)
|
4
|
-
path_template.gsub "{LANGUAGE}", language
|
5
|
-
end
|
6
|
-
|
7
|
-
def self.write(path_template, language, content)
|
8
|
-
path = build_path(path_template, language)
|
9
|
-
unless File.exist?(path)
|
10
|
-
raise POEditor::Exception.new "#{path} doesn't exist"
|
11
|
-
end
|
12
|
-
File.write(path, content)
|
13
|
-
UI.puts " #{"\xe2\x9c\x93".green} Saved at '#{path}'"
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|