poeditor-cli 0.1.0 → 0.2.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 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