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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c3981c762a561c1d20ae5e66b5f200f00a2e3e6b
4
- data.tar.gz: adfdd3ff5b171bc1d4098af35299e87d677bb086
3
+ metadata.gz: 6fbda657a807e50916c5267d8fce2241ada1d793
4
+ data.tar.gz: d9fdd116dd94f743e15ba290b1ab25ba24712ce3
5
5
  SHA512:
6
- metadata.gz: 21c12379f59d9d8bfd10c4f56e5f22c6c230906cf9053d0ab358247ed46db22ef3d2d088623ebd35ccb249f20f8d8e5ad903811f374f96bcc8435b3af8ad3bfd
7
- data.tar.gz: 8cd8959d0dec9bd5e33b962ecb493fe75d936df16eac5bda2d9dff3e41afdb624e7bbd24781986c1dc8d69d39a23b4af89072c7529702a22118f06ad63f9310e
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/cocoaseeds.svg)](https://rubygems.org/gems/cocoaseeds)
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 width="682" alt="poeditor-cli" src="https://cloud.githubusercontent.com/assets/931655/22509884/2aebebc2-e8d3-11e6-86e2-a9915ca755b5.png">
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
- 1. **Create `poeditor.yml` file**
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
- Here is an example.
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
- api_key: YOUR_API_KEY
18
- project_id: PROJECT_ID
19
- languages: [en, ko, jp, zh-Hans, zh-Hant, fr, es]
20
- path: example/Resources/{LANGUAGE}.lproj/Localizable.strings
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] # optional
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
- | Field | Description |
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
- 2. **Export using CLI**
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
- ```console
37
- $ poeditor export
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
- 3. **You're done! 🎉**
123
+ * Projects using gettext
41
124
 
42
- ## Installation
125
+ ```yaml
126
+ api_key: $POEDITOR_API_KEY # from envvar
127
+ project_id: $POEDITOR_PROJECT_ID # from envvar
128
+ type: po
43
129
 
44
- ```console
45
- $ [sudo] gem install poeditor-cli
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
 
@@ -9,15 +9,14 @@ module POEditor
9
9
  autoload :UI, "poeditor/ui"
10
10
 
11
11
  # core
12
- autoload :Exporter, "poeditor/core/exporter"
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 :ExportCommand, "poeditor/commands/export_command"
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 :ExportConfiguration, "poeditor/configurations/export_configuration"
21
+ autoload :Configuration, "poeditor/configuration"
23
22
  end
@@ -13,8 +13,8 @@ module POEditor
13
13
 
14
14
  def self.command_class(argv)
15
15
  case argv[0]
16
- when "export"
17
- ExportCommand
16
+ when "pull"
17
+ PullCommand
18
18
  when "--version"
19
19
  VersionCommand
20
20
  else
@@ -1,7 +1,7 @@
1
1
  module POEditor
2
2
  class HelpCommand
3
3
  def run(argv)
4
- puts "Usage: poeditor export"
4
+ puts "Usage: poeditor [pull|help]"
5
5
  end
6
6
  end
7
7
  end
@@ -1,11 +1,11 @@
1
1
  module POEditor
2
- class ExportCommand
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
- exporter = POEditor::Exporter.new(configuration)
8
- exporter.export_all()
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::ExportConfiguration} from the given system arguments.
26
+ # Returns {#POEditor::Configuration} from the given system arguments.
27
27
  #
28
28
  # @param argv [Array<String>] System arguments
29
29
  #
30
- # @return [POEditor::ExportConfiguration] The export configuration
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
- ExportConfiguration.new(
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 Exporter
6
- # @return [POEditor::ExportConfiguration] The configuration for export
5
+ class Core
6
+ # @return [POEditor::Configuration] The configuration for export
7
7
  attr_accessor :configuration
8
8
 
9
- # @param configuration [POEditor::ExportConfiguration]
9
+ # @param configuration [POEditor::Configuration]
10
10
  def initialize(configuration)
11
- unless configuration.is_a? ExportConfiguration
11
+ unless configuration.is_a? Configuration
12
12
  raise POEditor::Exception.new \
13
- "`configuration` should be an `ExportConfiguration`"
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
- # Exports all translations
35
- def export_all()
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
- Formatter.write(@configuration.path, language, content)
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
@@ -1,3 +1,3 @@
1
1
  module POEditor
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
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.1.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-01 00:00:00.000000000 Z
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/configurations/export_configuration.rb
43
- - lib/poeditor/core/exporter.rb
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