localeapp 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.rvmrc CHANGED
@@ -1 +1 @@
1
- rvm ruby-1.9.2@localeapp
1
+ rvm ruby-1.9.3@localeapp
data/.travis.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  rvm:
2
2
  - 1.8.7
3
- - 1.9.2
3
+ - 1.9.3
4
4
  gemfile:
5
5
  - Gemfile.i18n_037
6
6
  - Gemfile.i18n_050
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ # HEAD
2
+
3
+ * Add `localeapp add` command for sending keys and translations from the command line
4
+ * Add `secure` configuration setting for api communications. Default: true
5
+ * Add `ssl_verify` and `ssl_ca_file` configuration settings for ssl cert verification.
6
+ Off by default, see the README for more details
7
+ * Add `proxy` configuration setting
8
+
1
9
  # Version 0.1.2
2
10
 
3
11
  * Fix incorrect documentation
data/README.md CHANGED
@@ -10,10 +10,6 @@ The gem hooks into the i18n exception mechanism to send missing translations to
10
10
  the app. When translated content has been added it's automatically pulled down
11
11
  so you can see it straight away.
12
12
 
13
- We're still in private beta but if you think Locale would be useful to you and
14
- are willing to provide feedback then please get in touch at info@localeapp.com
15
- and we'll see what we can do.
16
-
17
13
  ## Installation
18
14
 
19
15
  ### Rails 3
@@ -59,11 +55,9 @@ localeapp.com and the localeapp import command accept zip files.
59
55
 
60
56
  ## Default Rails Translations
61
57
 
62
- Locale will hide default rails translations to avoid cluttering up your
63
- translation view with content you haven't changed. This can make it look like
64
- we didn't import all of your translations but we promise they're there and will
65
- appear again when you export. If you want to override a default translation you
66
- can create the key manually in Locale and we'll use your version instead.
58
+ Locale will automatically add the standard rails translations when a project is
59
+ created. If for some reason you don't want these, you can remove them using in
60
+ the project libraries area on localeapp.com
67
61
 
68
62
  ## Automatically sending missing translations
69
63
 
@@ -79,6 +73,15 @@ environment then edit `config/initializers/localeapp.rb` to include:
79
73
  This is just an array, so you can configure it to match send in any environment
80
74
  you wish.
81
75
 
76
+ ## Manually create translations
77
+
78
+ You can create translations on the command line by running:
79
+
80
+ localeapp add key.name en:"test content" es:"spanish content"
81
+
82
+ You must provide at least one translation and the locale code must already
83
+ exist in the project.
84
+
82
85
  ## Automatically pulling translations
83
86
 
84
87
  There are two ways to do this, one that suits a single developer working the
@@ -109,7 +112,10 @@ Run the daemon with:
109
112
  localeapp daemon
110
113
 
111
114
  The listeners will automatically reload translations when they see there are
112
- new ones.
115
+ new ones. The daemon has two options:
116
+
117
+ -b will run in the background and put a pid file in tmp/pids/localeapp.pid
118
+ -i X will change the polling interval to X from it's default five seconds.
113
119
 
114
120
  ### Disabling Reloading
115
121
 
@@ -131,6 +137,26 @@ You can also add a new locale to a project via localeapp.com. This will create
131
137
  missing translations for every translation key. You will need to restart any
132
138
  listeners completely to pick up the new locale.
133
139
 
140
+ ### Proxies
141
+
142
+ If you need to go through a proxy server, you can configure it with:
143
+
144
+ config.proxy = "http://my.proxy.com:8888"
145
+
146
+ ### SSL Certificate verification
147
+
148
+ localeapp.com uses https everywhere but certificate validation is turned off by
149
+ default. This is because ruby doesn't know how to read the certs from the OSX
150
+ keychain. You can turn verification on and tell the gem where the latest CA
151
+ certificates are by adding:
152
+
153
+ config.ssl_verify = true
154
+ config.ssl_ca_file = /path/to/ca_cert.pm
155
+
156
+ See [this article on Ruby Inside][1] for some more details.
157
+
158
+ [1]: http://www.rubyinside.com/how-to-cure-nethttps-risky-default-https-behavior-4010.html
159
+
134
160
  ### Support and feedback
135
161
 
136
162
  You can contact us via the support link at the bottom of the page, emailing
data/bin/localeapp CHANGED
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
3
3
 
4
- require 'slop'
5
4
  require 'localeapp'
6
5
 
7
6
  # Don't connect to the net if we're running under cucumber for testing
@@ -21,71 +20,104 @@ def include_config_file
21
20
  exit 1
22
21
  end
23
22
  end
24
- slop = Slop.new(ARGV, :help => true, :strict => true) do
25
- banner "Usage: localeapp COMMAND [options]"
26
- description <<-COMMANDS
27
- COMMAND:
28
- install <api_key> - Creates new configuration files and confirms key works
29
- pull - Pulls all translations from localeapp.com
30
- push <file> - Pushes a translation file to localeapp.com
31
- update - Gets any changes since the last poll and updates the yml
32
- daemon - Simple daemon (checks every 5 seconds for new translations)
33
- COMMANDS
34
-
35
- on_empty { puts self.to_s }
36
- end
37
23
 
38
- slop.command :install do
39
- execute do |opts, args|
24
+ require 'gli'
25
+ include GLI
26
+
27
+ version Localeapp::VERSION
28
+
29
+ desc "Creates new configuration files and confirms key works"
30
+ arg_name "<api_key>"
31
+ command :install do |c|
32
+ c.action do |global_options, options, args|
40
33
  key = args.first
41
34
  installer = Localeapp::CLI::Install.new
42
- if installer.execute(key)
43
- exit 0
35
+ unless installer.execute(key)
36
+ exit_now! "", 1
37
+ end
38
+ end
39
+ end
40
+
41
+ desc "Sends the key and content to localeapp.com"
42
+ arg_name "<key> <locale:content> (<locale:content> ...)"
43
+ command :add do |c|
44
+ c.action do |global_options, options, args|
45
+ key = args.shift
46
+ if key.nil? || args.size.zero?
47
+ exit_now! "localeapp add requires a key name and at least one translation", 1
44
48
  else
45
- exit 1
49
+ include_config_file
50
+ Localeapp::CLI::Add.new.execute(key, *args)
46
51
  end
47
52
  end
48
53
  end
49
54
 
50
- slop.command :pull do
51
- execute do |opts, args|
55
+ desc "Pulls all translations from localeapp.com"
56
+ command :pull do |c|
57
+ c.action do |global_options, options, args|
52
58
  include_config_file
53
59
  Localeapp::CLI::Pull.new.execute
54
60
  end
55
61
  end
56
62
 
57
- slop.command :push do
58
- on_empty { puts "localeapp push requires an file to push" }
59
-
60
- execute do |opts, args|
61
- file = args.first
62
- exit 1 if file.nil?
63
- include_config_file
64
- pusher = Localeapp::CLI::Push.new
65
- pusher.execute(file)
63
+ desc "Pushes a translation file to localeapp.com"
64
+ arg_name "<file>"
65
+ command :push do |c|
66
+ c.action do |global_options, options, args|
67
+ if args.empty?
68
+ exit_now! "localeapp push requires an file to push", 1
69
+ else
70
+ file = args.first
71
+ include_config_file
72
+ pusher = Localeapp::CLI::Push.new
73
+ pusher.execute(file)
74
+ end
66
75
  end
67
76
  end
68
77
 
69
- slop.command :update do
70
- execute do |opts, args|
78
+ desc "Gets any changes since the last poll and updates the yml"
79
+ command :update do |c|
80
+ c.action do |global_options, options, args|
71
81
  include_config_file
72
82
  Localeapp::CLI::Update.new.execute
73
83
  end
74
84
  end
75
85
 
76
- slop.command :daemon do
77
- execute do |opts, args|
86
+ desc "Simple daemon (checks for new translations in the background)"
87
+ command :daemon do |c|
88
+ c.desc "Interval to wait between checks"
89
+ c.arg_name 'interval'
90
+ c.default_value 5
91
+ c.flag [:i, :interval]
92
+
93
+ c.desc "run the daemon in the background"
94
+ c.switch [:b, 'background']
95
+
96
+ c.action do |global_options, options, args|
78
97
  include_config_file
79
- while true do
80
- Localeapp::CLI::Update.new.execute
81
- sleep 5
98
+
99
+ interval = options[:interval].to_i
100
+
101
+ if interval <= 0
102
+ exit_now! "interval must be a positive integer greater than 0", 1
103
+ end
104
+
105
+ command = Proc.new do
106
+ loop do
107
+ Localeapp::CLI::Update.new.execute
108
+ sleep interval
109
+ end
110
+ end
111
+ if options[:background]
112
+ pid = fork do
113
+ command.call
114
+ end
115
+ pids_directory = "tmp/pids"
116
+ File.open("#{File.directory?(pids_directory) ? pids_directory : "./"}/localeapp.pid", 'w') {|f| f << pid}
117
+ else
118
+ command.call
82
119
  end
83
120
  end
84
121
  end
85
122
 
86
- begin
87
- slop.parse
88
- rescue Slop::InvalidOptionError
89
- puts slop
90
- end
91
- puts slop unless ARGV.empty?
123
+ exit GLI.run(ARGV)
@@ -2,14 +2,10 @@ Feature: localeapp executable
2
2
 
3
3
  Scenario: Viewing help
4
4
  In order to see what options I have
5
- When I run `localeapp --help`
5
+ When I run `localeapp help`
6
6
  Then the output should contain:
7
7
  """
8
- Usage: localeapp COMMAND [options]
9
-
10
- COMMAND:
11
- install <api_key> - Creates new configuration files and confirms key works
12
- pull - Pulls all translations from localeapp.com
8
+ usage: localeapp command [command options]
13
9
  """
14
10
 
15
11
  Scenario: Running a command that doesn't exist
@@ -17,11 +13,7 @@ Feature: localeapp executable
17
13
  When I run `localeapp foo`
18
14
  Then the output should contain:
19
15
  """
20
- Usage: localeapp COMMAND [options]
21
-
22
- COMMAND:
23
- install <api_key> - Creates new configuration files and confirms key works
24
- pull - Pulls all translations from localeapp.com
16
+ error: Unknown command 'foo'. Use 'localeapp help' for a list of commands
25
17
  """
26
18
 
27
19
  Scenario: Running install
@@ -37,6 +29,7 @@ Feature: localeapp executable
37
29
  Project: Test Project
38
30
  Default Locale: en (English)
39
31
  """
32
+ And help should not be displayed
40
33
  And a file named "config/initializers/localeapp.rb" should exist
41
34
  And the exit status should be 0
42
35
 
@@ -51,19 +44,47 @@ Feature: localeapp executable
51
44
  Checking API key: BADAPIKEY
52
45
  ERROR: Project not found
53
46
  """
47
+ And help should not be displayed
54
48
  And a file named "config/initializers/localeapp.rb" should not exist
55
49
  And the exit status should not be 0
56
50
 
51
+ Scenario: Running add
52
+ In order to add a key and translation content
53
+ When I have a valid project on localeapp.com with api key "MYAPIKEY"
54
+ And an initializer file
55
+ When I run `localeapp add foo.baz en:"test en content" es:"test es content"`
56
+ Then the output should contain:
57
+ """
58
+ Localeapp Add
59
+
60
+ Sending key: foo.baz
61
+ Success!
62
+ """
63
+
64
+ Scenario: Running add with no arguments
65
+ In order to add a key and translation content
66
+ When I have a valid project on localeapp.com with api key "MYAPIKEY"
67
+ And an initializer file
68
+ When I run `localeapp add`
69
+ Then the output should contain:
70
+ """
71
+ localeapp add requires a key name and at least one translation
72
+ """
73
+
74
+ Scenario: Running add with just a key name
75
+ In order to add a key and translation content
76
+ When I have a valid project on localeapp.com with api key "MYAPIKEY"
77
+ And an initializer file
78
+ When I run `localeapp add foo.bar`
79
+ Then the output should contain:
80
+ """
81
+ localeapp add requires a key name and at least one translation
82
+ """
83
+
57
84
  Scenario: Running pull
58
85
  In order to retreive my translations
59
86
  Given I have a translations on localeapp.com for the project with api key "MYAPIKEY"
60
- And a file named "config/initializers/localeapp.rb" with:
61
- """
62
- require 'localeapp/rails'
63
- Localeapp.configure do |config|
64
- config.api_key = 'MYAPIKEY'
65
- end
66
- """
87
+ And an initializer file
67
88
  And a directory named "config/locales"
68
89
  When I run `localeapp pull`
69
90
  Then the output should contain:
@@ -75,18 +96,13 @@ Feature: localeapp executable
75
96
  Updating backend:
76
97
  Success!
77
98
  """
99
+ And help should not be displayed
78
100
  And a file named "config/locales/en.yml" should exist
79
101
 
80
102
  Scenario: Running push
81
103
  In order to send my translations
82
104
  When I have a valid project on localeapp.com with api key "MYAPIKEY"
83
- And a file named "config/initializers/localeapp.rb" with:
84
- """
85
- require 'localeapp/rails'
86
- Localeapp.configure do |config|
87
- config.api_key = 'MYAPIKEY'
88
- end
89
- """
105
+ And an initializer file
90
106
  And an empty file named "config/locales/en.yml"
91
107
  When I run `localeapp push config/locales/en.yml`
92
108
  Then the output should contain:
@@ -98,17 +114,12 @@ Feature: localeapp executable
98
114
 
99
115
  config/locales/en.yml queued for processing.
100
116
  """
117
+ And help should not be displayed
101
118
 
102
119
  Scenario: Running update
103
120
  In order to receive the translations that have been updated since the last check
104
121
  When I have a valid project on localeapp.com with api key "MYAPIKEY"
105
- And a file named "config/initializers/localeapp.rb" with:
106
- """
107
- require 'localeapp/rails'
108
- Localeapp.configure do |config|
109
- config.api_key = 'MYAPIKEY'
110
- end
111
- """
122
+ And an initializer file
112
123
  And a file named "log/localeapp.yml" with:
113
124
  """
114
125
  ---
@@ -123,6 +134,7 @@ Feature: localeapp executable
123
134
  Localeapp update: checking for translations since 120
124
135
  Found and updated new translations
125
136
  """
137
+ And help should not be displayed
126
138
  And a file named "config/locales/en.yml" should exist
127
139
  # check the content here
128
140
  # and the localeapp.yml file
@@ -2,26 +2,48 @@ require 'net/http'
2
2
  require 'time'
3
3
 
4
4
  When /^I have a valid project on localeapp\.com with api key "([^"]*)"$/ do |api_key|
5
- uri = "http://api.localeapp.com/v1/projects/#{api_key}.json"
5
+ uri = "https://api.localeapp.com/v1/projects/#{api_key}.json"
6
6
  body = valid_project_data.to_json
7
7
  add_fake_web_uri(:get, uri, ['200', 'OK'], body)
8
- add_fake_web_uri(:post, "http://api.localeapp.com/v1/projects/#{api_key}/import/", ['202', 'OK'], '')
8
+ add_fake_web_uri(:post, "https://api.localeapp.com/v1/projects/#{api_key}/import/", ['202', 'OK'], '')
9
+ add_fake_web_uri(:post, "https://api.localeapp.com/v1/projects/#{api_key}/translations/missing.json", ["202", "OK"], '')
9
10
  end
10
11
 
11
12
  When /^I have a valid project on localeapp\.com but an incorrect api key "([^"]*)"$/ do |bad_api_key|
12
- uri = "http://api.localeapp.com/v1/projects/#{bad_api_key}.json"
13
+ uri = "https://api.localeapp.com/v1/projects/#{bad_api_key}.json"
13
14
  body = valid_project_data.to_json
14
15
  add_fake_web_uri(:get, uri, ['404', 'Not Found'], body)
15
16
  end
16
17
 
17
18
  When /^I have a translations on localeapp\.com for the project with api key "([^"]*)"$/ do |api_key|
18
- uri = "http://api.localeapp.com/v1/projects/#{api_key}/translations.json"
19
+ uri = "https://api.localeapp.com/v1/projects/#{api_key}/translations.json"
19
20
  body = valid_translation_data.to_json
20
21
  add_fake_web_uri(:get, uri, ['200', 'OK'], body)
21
22
  end
22
23
 
23
24
  When /^new translations for the api key "([^"]*)" since "([^"]*)" with time "([^"]*)"$/ do |api_key, update_time, new_time|
24
- uri = "http://api.localeapp.com/v1/projects/#{api_key}/translations.json?updated_at=#{update_time}"
25
+ uri = "https://api.localeapp.com/v1/projects/#{api_key}/translations.json?updated_at=#{update_time}"
25
26
  body = valid_translation_data.to_json
26
27
  add_fake_web_uri(:get, uri, ['200', 'OK'], body, 'date' => Time.at(new_time.to_i).httpdate)
27
28
  end
29
+
30
+ When /^an initializer file$/ do
31
+ steps %Q{
32
+ And a file named "config/initializers/localeapp.rb" with:
33
+ """
34
+ require 'localeapp/rails'
35
+ Localeapp.configure do |config|
36
+ config.api_key = 'MYAPIKEY'
37
+ end
38
+ """
39
+ }
40
+ end
41
+
42
+ When /^help should not be displayed$/ do
43
+ steps %Q{
44
+ And the output should not contain:
45
+ """
46
+ Usage: localeapp COMMAND [options]
47
+ """
48
+ }
49
+ end
@@ -47,12 +47,19 @@ module Localeapp
47
47
  begin
48
48
  @connection_attempts += 1
49
49
  Localeapp.debug("ATTEMPT #{@connection_attempts}")
50
- request_options = options[:request_options] || {}
50
+ headers = { :x_localeapp_gem_version => Localeapp::VERSION }.merge(options[:headers] || {})
51
+ parameters = {
52
+ :url => url,
53
+ :method => method,
54
+ :headers => headers,
55
+ :verify_ssl => (Localeapp.configuration.ssl_verify ? OpenSSL::SSL::VERIFY_PEER : false)
56
+ }
57
+ parameters[:ca_file] = Localeapp.configuration.ssl_ca_file if Localeapp.configuration.ssl_ca_file
51
58
  if method == :post
52
- RestClient.send(method, url, options[:payload], request_options)
53
- else
54
- RestClient.send(method, url, request_options)
59
+ parameters[:payload] = options[:payload]
55
60
  end
61
+ RestClient.proxy = Localeapp.configuration.proxy if Localeapp.configuration.proxy
62
+ RestClient::Request.execute(parameters)
56
63
  rescue RestClient::ResourceNotFound,
57
64
  RestClient::NotModified,
58
65
  RestClient::InternalServerError,
@@ -0,0 +1,26 @@
1
+ module Localeapp
2
+ module CLI
3
+ class Add
4
+ def initialize(output = $stdout)
5
+ @output = output
6
+ end
7
+
8
+ def execute(key, *translations)
9
+ @output.puts "Localeapp Add"
10
+ @output.puts ""
11
+ translations.each do |translation|
12
+ if translation =~ /([\w\-]+):(.*)/
13
+ locale, description = $1, $2
14
+ Localeapp.missing_translations.add(locale, key, description)
15
+ else
16
+ @output.puts "Ignoring bad translation #{translation}"
17
+ @output.puts "format should be <locale>:<translation content>"
18
+ end
19
+ end
20
+ @output.puts "Sending key: #{key}"
21
+ Localeapp.sender.post_missing_translations
22
+ @output.puts "Success!"
23
+ end
24
+ end
25
+ end
26
+ end
@@ -7,7 +7,19 @@ module Localeapp
7
7
  # The host to connect to (defaults to api.localeapp.com)
8
8
  attr_accessor :host
9
9
 
10
- # The port to connect to (defaults to 80)
10
+ # The proxy to connect via
11
+ attr_accessor :proxy
12
+
13
+ # Whether to use https or not (defaults to true)
14
+ attr_accessor :secure
15
+
16
+ # Whether to verify ssl server certificates or not (defaults to false, see README)
17
+ attr_accessor :ssl_verify
18
+
19
+ # Path to local CA certs bundle
20
+ attr_accessor :ssl_ca_file
21
+
22
+ # The port to connect to if it's not the default one
11
23
  attr_accessor :port
12
24
 
13
25
  attr_accessor :http_auth_username
@@ -80,7 +92,8 @@ module Localeapp
80
92
 
81
93
  def initialize
82
94
  @host = 'api.localeapp.com'
83
- @port = 80
95
+ @secure = true
96
+ @ssl_verify = false
84
97
  @disabled_sending_environments = %w(test cucumber production)
85
98
  @disabled_reloading_environments = %w(test cucumber production)
86
99
  @disabled_polling_environments = %w(test cucumber production)
@@ -7,7 +7,7 @@ module Localeapp
7
7
  Localeapp.log("Detected missing translation for key(s) #{key.inspect}")
8
8
 
9
9
  [*key].each do |key|
10
- Localeapp.missing_translations.add(locale, key, options || {})
10
+ Localeapp.missing_translations.add(locale, key, nil, options || {})
11
11
  end
12
12
 
13
13
  [locale, key].join(', ')
@@ -1,13 +1,13 @@
1
1
  module Localeapp
2
- MissingTranslationRecord = Struct.new(:key, :locale, :options)
2
+ MissingTranslationRecord = Struct.new(:key, :locale, :description, :options)
3
3
 
4
4
  class MissingTranslations
5
5
  def initialize
6
6
  @translations = Hash.new { |h, k| h[k] = {} }
7
7
  end
8
8
 
9
- def add(locale, key, options = {})
10
- record = MissingTranslationRecord.new(key, locale, options)
9
+ def add(locale, key, description = nil, options = {})
10
+ record = MissingTranslationRecord.new(key, locale, description, options)
11
11
  @translations[locale][key] = record
12
12
  end
13
13
 
@@ -26,6 +26,7 @@ module Localeapp
26
26
  missing_data = {}
27
27
  missing_data[:key] = key
28
28
  missing_data[:locale] = locale
29
+ missing_data[:description] = record.description if record.description
29
30
  missing_data[:options] = record.options
30
31
  data << missing_data
31
32
  end
@@ -8,12 +8,12 @@ module Localeapp
8
8
 
9
9
  def project_url(options = {})
10
10
  options[:format] ||= 'json'
11
- URI::HTTP.build(base_options.merge(:path => project_path(options[:format]))).to_s
11
+ http_scheme.build(base_options.merge(:path => project_path(options[:format]))).to_s
12
12
  end
13
13
 
14
14
  def translations_url(options={})
15
15
  options[:format] ||= 'json'
16
- url = URI::HTTP.build(base_options.merge(:path => translations_path(options[:format])))
16
+ url = http_scheme.build(base_options.merge(:path => translations_path(options[:format])))
17
17
  url.query = options[:query].map { |k,v| "#{k}=#{v}" }.join('&') if options[:query]
18
18
  url.to_s
19
19
  end
@@ -32,7 +32,7 @@ module Localeapp
32
32
 
33
33
  def missing_translations_url(options={})
34
34
  options[:format] ||= 'json'
35
- url = URI::HTTP.build(base_options.merge(:path => missing_translations_path(options[:format])))
35
+ url = http_scheme.build(base_options.merge(:path => missing_translations_path(options[:format])))
36
36
  url.query = options[:query].map { |k,v| "#{k}=#{v}" }.join('&') if options[:query]
37
37
  url.to_s
38
38
  end
@@ -42,10 +42,17 @@ module Localeapp
42
42
  end
43
43
 
44
44
  def import_url(options={})
45
- URI::HTTP.build(base_options.merge(:path => import_path)).to_s
45
+ http_scheme.build(base_options.merge(:path => import_path)).to_s
46
46
  end
47
47
 
48
48
  private
49
+ def http_scheme
50
+ if Localeapp.configuration.secure
51
+ URI::HTTPS
52
+ else
53
+ URI::HTTP
54
+ end
55
+ end
49
56
 
50
57
  def base_options
51
58
  options = {:host => Localeapp.configuration.host, :port => Localeapp.configuration.port}
@@ -12,7 +12,7 @@ module Localeapp
12
12
  @data = { :translation => translation }
13
13
  api_call :create_translation,
14
14
  :payload => @data.to_json,
15
- :request_options => { :content_type => :json },
15
+ :headers => { :content_type => :json },
16
16
  :success => :handle_single_translation_success,
17
17
  :failure => :handle_single_translation_failure,
18
18
  :max_connection_attempts => 1
@@ -32,7 +32,7 @@ module Localeapp
32
32
  @data = { :translations => to_send }
33
33
  api_call :missing_translations,
34
34
  :payload => @data.to_json,
35
- :request_options => { :content_type => :json },
35
+ :headers => { :content_type => :json },
36
36
  :success => :handle_missing_translation_success,
37
37
  :failure => :handle_missing_translation_failure,
38
38
  :max_connection_attempts => 1
@@ -1,3 +1,3 @@
1
1
  module Localeapp
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/localeapp.rb CHANGED
@@ -38,6 +38,7 @@ require 'localeapp/cli/install'
38
38
  require 'localeapp/cli/pull'
39
39
  require 'localeapp/cli/push'
40
40
  require 'localeapp/cli/update'
41
+ require 'localeapp/cli/add'
41
42
 
42
43
  # AUDIT: Will this work on ruby 1.9.x
43
44
  $KCODE="UTF8" if RUBY_VERSION < '1.9'
data/localeapp.gemspec CHANGED
@@ -23,12 +23,12 @@ Gem::Specification.new do |s|
23
23
  s.add_dependency('json')
24
24
  s.add_dependency('rest-client')
25
25
  s.add_dependency('ya2yaml')
26
- s.add_dependency('slop')
26
+ s.add_dependency('gli')
27
27
 
28
28
  s.add_development_dependency('rake')
29
29
  s.add_development_dependency('rspec', '2.5.0')
30
30
  s.add_development_dependency('yard', '0.6.7')
31
- s.add_development_dependency('RedCloth', '4.2.7')
31
+ s.add_development_dependency('RedCloth', '4.2.8')
32
32
  s.add_development_dependency('aruba', '0.3.6')
33
33
  s.add_development_dependency('fakeweb', '1.3.0')
34
34
  end
@@ -10,34 +10,85 @@ end
10
10
 
11
11
  describe Localeapp::ApiCaller, "#call(object)" do
12
12
  before do
13
- @api_caller = Localeapp::ApiCaller.new(:test)
14
- @url = 'http://example.com/test'
13
+ with_configuration do
14
+ @api_caller = Localeapp::ApiCaller.new(:test)
15
+ end
16
+ @url = 'https://example.com/test'
15
17
  @api_caller.stub!(:test_endpoint).and_return([:get, @url])
16
18
  @api_caller.stub!(:sleep_if_retrying)
17
19
  end
18
20
 
19
21
  it "gets the method and url for the endpoint" do
20
22
  @api_caller.should_receive(:test_endpoint).with({}).and_return([:get, @url])
21
- RestClient.stub!(:get).and_return(double('response', :code => 200))
23
+ RestClient::Request.stub!(:execute).and_return(double('response', :code => 200))
22
24
  @api_caller.call(self)
23
25
  end
24
26
 
25
27
  it "passes through any url options" do
26
28
  @api_caller.should_receive(:test_endpoint).with({:foo => :bar}).and_return([:get, @url])
27
29
  @api_caller.options[:url_options] = { :foo => :bar }
28
- RestClient.stub!(:get).and_return(double('response', :code => 200))
30
+ RestClient::Request.stub!(:execute).and_return(double('response', :code => 200))
31
+ @api_caller.call(self)
32
+ end
33
+
34
+ it "adds the gem version to the headers" do
35
+ RestClient::Request.should_receive(:execute).with(hash_including(:headers => { :x_localeapp_gem_version => Localeapp::VERSION })).and_return(double('response', :code => 200))
29
36
  @api_caller.call(self)
30
37
  end
31
38
 
39
+ context "Proxy" do
40
+ before do
41
+ RestClient::Request.stub!(:execute).and_return(double('response', :code => 200))
42
+ end
43
+
44
+ it "sets the proxy if configured" do
45
+ Localeapp.configuration.proxy = "http://localhost:8888"
46
+ RestClient.should_receive(:proxy=).with('http://localhost:8888')
47
+ @api_caller.call(self)
48
+ end
49
+
50
+ it "doesn't set the proxy if it's not configured" do
51
+ RestClient.should_not_receive(:proxy=)
52
+ @api_caller.call(self)
53
+ end
54
+ end
55
+
56
+ context "SSL Certificate Validation" do
57
+ it "set the HTTPClient verify_ssl to VERIFY_PEER if ssl_verify is set to true" do
58
+ Localeapp.configuration.ssl_verify = true
59
+ RestClient::Request.should_receive(:execute).with(hash_including(:verify_ssl => OpenSSL::SSL::VERIFY_PEER)).and_return(double('response', :code => 200))
60
+ @api_caller.call(self)
61
+ end
62
+
63
+ it "set the HTTPClient verify_ssl to false if ssl_verify is set to false" do
64
+ RestClient::Request.should_receive(:execute).with(hash_including(:verify_ssl => false)).and_return(double('response', :code => 200))
65
+ @api_caller.call(self)
66
+ end
67
+ end
68
+
69
+ context "SSL Certificate Validation" do
70
+ it "set the HTTPClient ca_file to the value given to ssl_ca_file if it's not nil" do
71
+ Localeapp.configuration.ssl_ca_file = '/tmp/test'
72
+ RestClient::Request.should_receive(:execute).with(hash_including(:ca_file => '/tmp/test')).and_return(double('response', :code => 200))
73
+ @api_caller.call(self)
74
+ end
75
+
76
+ it "doesn't set the HTTPClient ca_file if ssl_ca_file is nil" do
77
+ Localeapp.configuration.ssl_ca_file = nil
78
+ RestClient::Request.should_receive(:execute).with(hash_not_including(:ca_file => nil)).and_return(double('response', :code => 200))
79
+ @api_caller.call(self)
80
+ end
81
+ end
82
+
32
83
  context "a GET request" do
33
84
  it "makes the call to the api" do
34
- RestClient.should_receive(:get).with(@url, {}).and_return(double('response', :code => 200))
85
+ RestClient::Request.should_receive(:execute).with(hash_including(:url => @url, :method => :get)).and_return(double('response', :code => 200))
35
86
  @api_caller.call(self)
36
87
  end
37
88
 
38
- it "adds any :request_options to the api call" do
39
- RestClient.should_receive(:get).with(@url, :foo => :bar).and_return(double('response', :code => 200))
40
- @api_caller.options[:request_options] = { :foo => :bar }
89
+ it "adds any :headers to the api call" do
90
+ RestClient::Request.should_receive(:execute).with(hash_including(:headers => { :x_localeapp_gem_version => Localeapp::VERSION, :foo => :bar })).and_return(double('response', :code => 200))
91
+ @api_caller.options[:headers] = { :foo => :bar }
41
92
  @api_caller.call(self)
42
93
  end
43
94
  end
@@ -50,13 +101,13 @@ describe Localeapp::ApiCaller, "#call(object)" do
50
101
  end
51
102
 
52
103
  it "makes the call to the api using :payload as the payload" do
53
- RestClient.should_receive(:post).with(@url, "test data", {}).and_return(double('response', :code => 200))
104
+ RestClient::Request.should_receive(:execute).with(hash_including(:url => @url, :payload => "test data", :method => :post)).and_return(double('response', :code => 200))
54
105
  @api_caller.call(self)
55
106
  end
56
107
 
57
- it "adds any :request_options to the api call" do
58
- RestClient.should_receive(:post).with(@url, "test data", :foo => :bar).and_return(double('response', :code => 200))
59
- @api_caller.options[:request_options] = { :foo => :bar }
108
+ it "adds any :headers to the api call" do
109
+ RestClient::Request.should_receive(:execute).with(hash_including(:headers => { :x_localeapp_gem_version => Localeapp::VERSION, :foo => :bar })).and_return(double('response', :code => 200))
110
+ @api_caller.options[:headers] = { :foo => :bar }
60
111
  @api_caller.call(self)
61
112
  end
62
113
  end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe Localeapp::CLI::Add, "#execute(key, *translations)" do
4
+ def do_action(key = 'test.key', args = nil)
5
+ args ||= ['en:test en', 'es:test es']
6
+ @command.execute(key, *args)
7
+ end
8
+
9
+ before(:each) do
10
+ @output = StringIO.new
11
+ @command = Localeapp::CLI::Add.new(@output)
12
+ end
13
+
14
+ it "adds the translations to missing_translations" do
15
+ with_configuration do
16
+ Localeapp.sender.stub!(:post_missing_translations)
17
+ do_action
18
+ end
19
+ en_missing = Localeapp.missing_translations['en']
20
+ en_missing.size.should == 1
21
+ en_missing['test.key'].locale.should == 'en'
22
+ en_missing['test.key'].description.should == 'test en'
23
+ es_missing = Localeapp.missing_translations['es']
24
+ es_missing.size.should == 1
25
+ es_missing['test.key'].locale.should == 'es'
26
+ es_missing['test.key'].description.should == 'test es'
27
+ end
28
+
29
+ it "ignores badly formed arguments" do
30
+ with_configuration do
31
+ Localeapp.sender.stub!(:post_missing_translations)
32
+ do_action('test.key', ["en:this is fine", "esbad"])
33
+ end
34
+ Localeapp.missing_translations['en'].size.should == 1
35
+ Localeapp.missing_translations['es'].size.should == 0
36
+ Localeapp.missing_translations['esbad'].size.should == 0
37
+ @output.string.should include("Ignoring bad translation esbad")
38
+ @output.string.should include("format should be <locale>:<translation content>")
39
+ end
40
+
41
+ it "tells the sender to send the missing translations" do
42
+ with_configuration do
43
+ Localeapp.sender.should_receive(:post_missing_translations)
44
+ do_action
45
+ end
46
+ end
47
+ end
@@ -11,6 +11,38 @@ describe Localeapp::Configuration do
11
11
  expect { configuration.host = 'test.host' }.to change(configuration, :host).to('test.host')
12
12
  end
13
13
 
14
+ it "sets proxy to nil by default" do
15
+ configuration.proxy.should == nil
16
+ end
17
+
18
+ it "allows proxy setting to be overridden" do
19
+ expect { configuration.proxy = 'http://localhost:8888' }.to change(configuration, :proxy).to('http://localhost:8888')
20
+ end
21
+
22
+ it "sets secure to true by default" do
23
+ configuration.secure.should == true
24
+ end
25
+
26
+ it "allows secure setting to be overridden" do
27
+ expect { configuration.secure = false }.to change(configuration, :secure).to(false)
28
+ end
29
+
30
+ it "sets ssl_verify to false by default" do
31
+ configuration.ssl_verify.should == false
32
+ end
33
+
34
+ it "allows ssl_verify setting to be overridden" do
35
+ expect { configuration.ssl_verify = true }.to change(configuration, :ssl_verify).to(true)
36
+ end
37
+
38
+ it "sets ssl_ca_file to nil by default" do
39
+ configuration.ssl_ca_file.should == nil
40
+ end
41
+
42
+ it "allows ssl_ca_file setting to be overridden" do
43
+ expect { configuration.ssl_ca_file = '/foo/bar' }.to change(configuration, :ssl_ca_file).to('/foo/bar')
44
+ end
45
+
14
46
  it "includes http_auth_username defaulting to nil" do
15
47
  configuration.http_auth_username.should == nil
16
48
  configuration.http_auth_username = "test"
@@ -9,13 +9,13 @@ describe Localeapp::ExceptionHandler, '#call(exception, locale, key, options)' d
9
9
  end
10
10
 
11
11
  it "adds the missing translation to the missing translation list" do
12
- Localeapp.missing_translations.should_receive(:add).with(:en, 'foo', { :baz => 'bam' })
12
+ Localeapp.missing_translations.should_receive(:add).with(:en, 'foo', nil, { :baz => 'bam' })
13
13
  I18n.t('foo', :baz => 'bam')
14
14
  end
15
15
 
16
16
  it "handles when the key is an array of keys" do
17
- Localeapp.missing_translations.should_receive(:add).with(:en, 'foo', {})
18
- Localeapp.missing_translations.should_receive(:add).with(:en, 'bar', {})
17
+ Localeapp.missing_translations.should_receive(:add).with(:en, 'foo', nil, {})
18
+ Localeapp.missing_translations.should_receive(:add).with(:en, 'bar', nil, {})
19
19
  I18n.t(['foo', 'bar'])
20
20
  end
21
21
 
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Localeapp::KeyChecker, "#check(key)" do
4
4
  it "returns false and an empty hash if the response from locale app is a 404" do
5
- FakeWeb.register_uri(:get, 'http://api.localeapp.com/v1/projects/TEST_KEY.json', :body => "", :status => ['404', 'Not Found'])
5
+ FakeWeb.register_uri(:get, 'https://api.localeapp.com/v1/projects/TEST_KEY.json', :body => "", :status => ['404', 'Not Found'])
6
6
  with_configuration do
7
7
  @checker = Localeapp::KeyChecker.new
8
8
  end
@@ -10,7 +10,7 @@ describe Localeapp::KeyChecker, "#check(key)" do
10
10
  end
11
11
 
12
12
  it "returns true and and the parsed json hash if the response from locale app is a 200" do
13
- FakeWeb.register_uri(:get, 'http://api.localeapp.com/v1/projects/TEST_KEY.json', :body => valid_project_data.to_json, :status => ['200', 'OK'])
13
+ FakeWeb.register_uri(:get, 'https://api.localeapp.com/v1/projects/TEST_KEY.json', :body => valid_project_data.to_json, :status => ['200', 'OK'])
14
14
  with_configuration do
15
15
  @checker = Localeapp::KeyChecker.new
16
16
  end
@@ -1,11 +1,12 @@
1
1
  require 'spec_helper'
2
2
  require 'localeapp/missing_translations'
3
3
 
4
- describe Localeapp::MissingTranslations, "#add(locale, key, options = {})" do
4
+ describe Localeapp::MissingTranslations, "#add(locale, key, description = nil, options = {})" do
5
5
  it "stores the missing translation data" do
6
6
  translations = Localeapp::MissingTranslations.new
7
- translations.add(:en, 'foo', { :baz => 'bam' })
7
+ translations.add(:en, 'foo', 'bar', { :baz => 'bam' })
8
8
  translations[:en].should include('foo')
9
+ translations[:en]['foo'].description.should == 'bar'
9
10
  translations[:en]['foo'].options.should == { :baz => 'bam' }
10
11
  end
11
12
  end
@@ -13,16 +14,18 @@ end
13
14
  describe Localeapp::MissingTranslations, "#to_send" do
14
15
  it "returns an array of missing translation data that needs to be sent to localeapp.com" do
15
16
  translations = Localeapp::MissingTranslations.new
16
- translations.add(:en, 'foo', { :baz => 'bam' })
17
- translations.add(:es, 'bar')
17
+ translations.add(:en, 'foo', nil, { :baz => 'bam' })
18
+ translations.add(:es, 'bar', 'baz')
18
19
 
19
20
  to_send = translations.to_send
20
21
  to_send.size.should == 2
21
22
  to_send[0][:key].should == 'foo'
22
23
  to_send[0][:locale].should == :en
24
+ to_send[0].should_not have_key(:description)
23
25
  to_send[0][:options].should == { :baz => 'bam' }
24
26
  to_send[1][:key].should == 'bar'
25
27
  to_send[1][:locale].should == :es
28
+ to_send[1][:description].should == 'baz'
26
29
  to_send[1][:options].should == {}
27
30
  end
28
31
  end
@@ -38,22 +38,22 @@ describe Localeapp::Poller do
38
38
 
39
39
  describe "#poll!" do
40
40
  it "returns false if get returns 304 Not Modified" do
41
- FakeWeb.register_uri(:get, "http://api.localeapp.com/v1/projects/TEST_KEY/translations.json?updated_at=#{@updated_at}", :body => '', :status => ['304', 'Not Modified'])
41
+ FakeWeb.register_uri(:get, "https://api.localeapp.com/v1/projects/TEST_KEY/translations.json?updated_at=#{@updated_at}", :body => '', :status => ['304', 'Not Modified'])
42
42
  @poller.poll!.should == false
43
43
  end
44
44
 
45
45
  it "returns false if get returns a 50x response" do
46
- FakeWeb.register_uri(:get, "http://api.localeapp.com/v1/projects/TEST_KEY/translations.json?updated_at=#{@updated_at}", :body => '', :status => ['500', 'Internal Server Error'])
46
+ FakeWeb.register_uri(:get, "https://api.localeapp.com/v1/projects/TEST_KEY/translations.json?updated_at=#{@updated_at}", :body => '', :status => ['500', 'Internal Server Error'])
47
47
  @poller.poll!.should == false
48
48
  end
49
49
 
50
50
  it "returns false if get returns 200 OK" do
51
- FakeWeb.register_uri(:get, "http://api.localeapp.com/v1/projects/TEST_KEY/translations.json?updated_at=#{@updated_at}", :body => @hash.to_json, :status => ['200', 'OK'], :date => Time.now.httpdate)
51
+ FakeWeb.register_uri(:get, "https://api.localeapp.com/v1/projects/TEST_KEY/translations.json?updated_at=#{@updated_at}", :body => @hash.to_json, :status => ['200', 'OK'], :date => Time.now.httpdate)
52
52
  @poller.poll!.should == true
53
53
  end
54
54
 
55
55
  it "passes the data through to the Updater" do
56
- FakeWeb.register_uri(:get, "http://api.localeapp.com/v1/projects/TEST_KEY/translations.json?updated_at=#{@updated_at}", :body => @hash.to_json, :status => ['200', 'OK'], :date => Time.now.httpdate)
56
+ FakeWeb.register_uri(:get, "https://api.localeapp.com/v1/projects/TEST_KEY/translations.json?updated_at=#{@updated_at}", :body => @hash.to_json, :status => ['200', 'OK'], :date => Time.now.httpdate)
57
57
  Localeapp.updater.should_receive(:update).with(@hash)
58
58
  @poller.poll!
59
59
  end
@@ -21,21 +21,21 @@ describe Localeapp::Routes do
21
21
  end
22
22
 
23
23
  describe '#project_url' do
24
- it "is constructed from the configuration host and port and defaults to json" do
25
- with_configuration(@config.merge(:port => 1234)) do
24
+ it "is constructed from the configuration host, port and secure and defaults to json" do
25
+ with_configuration(@config.merge(:port => 1234, :secure => false)) do
26
26
  @routes.project_url.should == "http://test.host:1234/v1/projects/API_KEY.json"
27
27
  end
28
28
  end
29
29
 
30
30
  it "includes http auth if in configuration" do
31
31
  with_configuration(@config.merge(:port => 1234, :http_auth_username => 'foo', :http_auth_password => 'bar')) do
32
- @routes.project_url.should == "http://foo:bar@test.host:1234/v1/projects/API_KEY.json"
32
+ @routes.project_url.should == "https://foo:bar@test.host:1234/v1/projects/API_KEY.json"
33
33
  end
34
34
  end
35
35
 
36
36
  it "can be changed to another content type" do
37
37
  with_configuration(@config) do
38
- @routes.project_url(:format => :yml).should == 'http://test.host/v1/projects/API_KEY.yml'
38
+ @routes.project_url(:format => :yml).should == 'https://test.host/v1/projects/API_KEY.yml'
39
39
  end
40
40
  end
41
41
  end
@@ -43,7 +43,7 @@ describe Localeapp::Routes do
43
43
  describe "#translations_url" do
44
44
  it "it extends the project_url and defaults to json" do
45
45
  with_configuration(@config) do
46
- @routes.translations_url.should == "http://test.host/v1/projects/API_KEY/translations.json"
46
+ @routes.translations_url.should == "https://test.host/v1/projects/API_KEY/translations.json"
47
47
  end
48
48
  end
49
49
 
@@ -57,7 +57,7 @@ describe Localeapp::Routes do
57
57
 
58
58
  it "can be changed to another content type" do
59
59
  with_configuration(@config) do
60
- @routes.translations_url(:format => :yml).should == 'http://test.host/v1/projects/API_KEY/translations.yml'
60
+ @routes.translations_url(:format => :yml).should == 'https://test.host/v1/projects/API_KEY/translations.yml'
61
61
  end
62
62
  end
63
63
  end
@@ -95,7 +95,7 @@ describe Localeapp::Routes do
95
95
  describe "#missing_translations_url" do
96
96
  it "it extends the project_url and defaults to json" do
97
97
  with_configuration(@config) do
98
- @routes.missing_translations_url.should == "http://test.host/v1/projects/API_KEY/translations/missing.json"
98
+ @routes.missing_translations_url.should == "https://test.host/v1/projects/API_KEY/translations/missing.json"
99
99
  end
100
100
  end
101
101
 
@@ -109,7 +109,7 @@ describe Localeapp::Routes do
109
109
 
110
110
  it "can be changed to another content type" do
111
111
  with_configuration(@config) do
112
- @routes.missing_translations_url(:format => :yml).should == 'http://test.host/v1/projects/API_KEY/translations/missing.yml'
112
+ @routes.missing_translations_url(:format => :yml).should == 'https://test.host/v1/projects/API_KEY/translations/missing.yml'
113
113
  end
114
114
  end
115
115
  end
@@ -117,7 +117,7 @@ describe Localeapp::Routes do
117
117
  describe "#import_url" do
118
118
  it "appends 'import to the project url" do
119
119
  with_configuration(@config) do
120
- @routes.import_url.should == 'http://test.host/v1/projects/API_KEY/import/'
120
+ @routes.import_url.should == 'https://test.host/v1/projects/API_KEY/import/'
121
121
  end
122
122
  end
123
123
  end
@@ -17,7 +17,13 @@ describe Localeapp::Sender, "#post_translation(locale, key, options, value = nil
17
17
  }
18
18
  }
19
19
  # have to stub RestClient here as FakeWeb doesn't support looking at the post body yet
20
- RestClient.should_receive(:post).with(@sender.translations_url, data.to_json, :content_type => :json).and_return(double('response', :code => 200))
20
+ RestClient::Request.should_receive(:execute).with(hash_including(
21
+ :url => @sender.translations_url,
22
+ :payload => data.to_json,
23
+ :headers => {
24
+ :x_localeapp_gem_version => Localeapp::VERSION,
25
+ :content_type => :json },
26
+ :method => :post)).and_return(double('response', :code => 200))
21
27
  @sender.post_translation('en', 'test.key', { 'foo' => 'foo', 'bar' => 'bar' }, 'test content')
22
28
  end
23
29
  end
@@ -37,7 +43,13 @@ describe Localeapp::Sender, "#post_missing_translations" do
37
43
  Localeapp.missing_translations.should_receive(:to_send).and_return(missing_to_send)
38
44
  data = { :translations => missing_to_send }
39
45
  # have to stub RestClient here as FakeWeb doesn't support looking at the post body yet
40
- RestClient.should_receive(:post).with(@sender.missing_translations_url, data.to_json, :content_type => :json).and_return(double('response', :code => 200))
46
+ RestClient::Request.should_receive(:execute).with(hash_including(
47
+ :url => @sender.missing_translations_url,
48
+ :payload => data.to_json,
49
+ :headers => {
50
+ :x_localeapp_gem_version => Localeapp::VERSION,
51
+ :content_type => :json },
52
+ :method => :post)).and_return(double('response', :code => 200))
41
53
  @sender.post_missing_translations
42
54
  end
43
55
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: localeapp
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 1
9
8
  - 2
10
- version: 0.1.2
9
+ - 0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Christopher Dell
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-09-07 00:00:00 Z
19
+ date: 2011-11-17 00:00:00 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: i18n
@@ -75,7 +75,7 @@ dependencies:
75
75
  type: :runtime
76
76
  version_requirements: *id004
77
77
  - !ruby/object:Gem::Dependency
78
- name: slop
78
+ name: gli
79
79
  prerelease: false
80
80
  requirement: &id005 !ruby/object:Gem::Requirement
81
81
  none: false
@@ -142,12 +142,12 @@ dependencies:
142
142
  requirements:
143
143
  - - "="
144
144
  - !ruby/object:Gem::Version
145
- hash: 57
145
+ hash: 39
146
146
  segments:
147
147
  - 4
148
148
  - 2
149
- - 7
150
- version: 4.2.7
149
+ - 8
150
+ version: 4.2.8
151
151
  type: :development
152
152
  version_requirements: *id009
153
153
  - !ruby/object:Gem::Dependency
@@ -215,6 +215,7 @@ files:
215
215
  - lib/localeapp.rb
216
216
  - lib/localeapp/api_call.rb
217
217
  - lib/localeapp/api_caller.rb
218
+ - lib/localeapp/cli/add.rb
218
219
  - lib/localeapp/cli/install.rb
219
220
  - lib/localeapp/cli/pull.rb
220
221
  - lib/localeapp/cli/push.rb
@@ -240,6 +241,7 @@ files:
240
241
  - spec/fixtures/es.yml
241
242
  - spec/localeapp/api_call_spec.rb
242
243
  - spec/localeapp/api_caller_spec.rb
244
+ - spec/localeapp/cli/add_spec.rb
243
245
  - spec/localeapp/cli/install_spec.rb
244
246
  - spec/localeapp/cli/pull_spec.rb
245
247
  - spec/localeapp/cli/push_spec.rb
@@ -286,7 +288,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
286
288
  requirements: []
287
289
 
288
290
  rubyforge_project: localeapp
289
- rubygems_version: 1.8.6
291
+ rubygems_version: 1.8.10
290
292
  signing_key:
291
293
  specification_version: 3
292
294
  summary: Add missing translation keys to localeapp.com
@@ -299,6 +301,7 @@ test_files:
299
301
  - spec/fixtures/es.yml
300
302
  - spec/localeapp/api_call_spec.rb
301
303
  - spec/localeapp/api_caller_spec.rb
304
+ - spec/localeapp/cli/add_spec.rb
302
305
  - spec/localeapp/cli/install_spec.rb
303
306
  - spec/localeapp/cli/pull_spec.rb
304
307
  - spec/localeapp/cli/push_spec.rb