produce 0.1.3 → 0.1.4

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: 09c6e37f6e105ecc5d01d4de15447525e62ec1e5
4
- data.tar.gz: 9d596759f7d94c96359b7f498f5e4c9e2d495625
3
+ metadata.gz: 943588dab52ad39c6de765497b027db1de2e10eb
4
+ data.tar.gz: e4682e29209151d0a9b55881632e56f005b75640
5
5
  SHA512:
6
- metadata.gz: 527fac5e5f2f45c45e046decb76f9b64970ca484f7bee42b8162b501ba0fa765ca09119e730971458f8edec5f9544f32b608b55c9ebee04d21d7a5d9b101d44a
7
- data.tar.gz: b8619a8ae4a5e886ba3831392239fb310b8db0e1850cfcabddaca4427109c408e4e634cc48de8d5f360c6a8dffa6436acfc405a432bb90279a52ca90f5fa49fd
6
+ metadata.gz: eabb9f04201e1e47927b7b48e2892235feb68363d0ff89297ab1c12d689e2c30c55f72d71eba4ccb7867bd904c0f7bb9f9f08f9200edd93234b96c13224d5b2c
7
+ data.tar.gz: 6650261476f7584cf3b94f810d6971a586cb08875dee1d60661d1553eaaefe28f49f670a43ded93765755b112e8dbd38ce36180ffa69e8b4714a188cc5ad30ad
data/bin/produce CHANGED
@@ -31,7 +31,6 @@ class FastlaneApplication
31
31
  c.action do |args, options|
32
32
  set_username(options.username)
33
33
 
34
- Produce::Config.shared_config # to ask for missing information right in the beginning
35
34
  puts Produce::Manager.start_producing
36
35
  end
37
36
  end
data/lib/produce.rb CHANGED
@@ -1,21 +1,17 @@
1
1
  require 'json'
2
2
  require 'produce/version'
3
- require 'produce/helper'
4
3
  require 'produce/config'
5
4
  require 'produce/manager'
6
5
  require 'produce/dependency_checker'
7
6
  require 'produce/developer_center'
8
7
  require 'produce/itunes_connect'
9
- require 'produce/update_checker'
10
8
  require 'produce/available_default_languages'
11
9
 
12
- # Third Party code
13
- require 'phantomjs/poltergeist'
14
- require 'colored'
15
-
16
10
  module Produce
17
- TMP_FOLDER = "/tmp/produce/"
11
+ Helper = FastlaneCore::Helper # you gotta love Ruby: Helper.* should use the Helper class contained in FastlaneCore
12
+
13
+ ENV['FASTLANE_TEAM_ID'] ||= ENV["PRODUCE_TEAM_ID"]
18
14
 
19
- # Produce::UpdateChecker.verify_latest_version
15
+ FastlaneCore::UpdateChecker.verify_latest_version('produce', Produce::VERSION)
20
16
  DependencyChecker.check_dependencies
21
17
  end
@@ -8,17 +8,51 @@ module Produce
8
8
  primary_language: "Primary Language (e.g. 'English', 'German'): "
9
9
  }
10
10
 
11
- attr_reader :config
12
-
11
+ # Left to prevent fastlane from crashing. Should be removed upon version bump.
13
12
  def self.shared_config
14
- @@shared ||= self.new
15
13
  end
16
14
 
17
- def self.shared_config= config
18
- @@shared = config
15
+ # Creates new Config instance using ENV variables.
16
+ # @param options (Hash) (optional) config options hash. If duplicates keys
17
+ # specified by ENV variable, `options` has value will be used.
18
+ # @return (Config) created Config instance
19
+ def initialize(options = {})
20
+ @config = env_options.merge(options)
21
+ end
22
+
23
+ # Retrieves the value for given `key`. If not found, will promt user with
24
+ # `ASK_MESSAGES[key]` till gets valid response. Thus, always returns value.
25
+ # Raises exception if given `key` is not Symbol or unknown.
26
+ def val(key)
27
+ raise "Please only pass symbols, no Strings to this method".red unless key.kind_of? Symbol
28
+
29
+ unless @config.has_key? key
30
+ @config[key] = ask(ASK_MESSAGES[key]) do |q|
31
+ case key
32
+ when :primary_language
33
+ q.validate = lambda { |val| is_valid_language?(val) }
34
+ q.responses[:not_valid] = "Please enter one of available languages: #{AvailableDefaultLanguages.all_langauges}"
35
+ else
36
+ q.validate = lambda { |val| !val.empty? }
37
+ q.responses[:not_valid] = "#{key.to_s.gsub('_', ' ').capitalize} can't be blank"
38
+ end
39
+ end
40
+ end
41
+
42
+ return @config[key]
43
+ end
44
+
45
+ # Aliases `[key]` to `val(key)` because Ruby can do it.
46
+ alias_method :[], :val
47
+
48
+ # Returns true if option for the given key is present.
49
+ def has_key?(key)
50
+ @config.has_key? key
19
51
  end
20
52
 
21
- def self.env_options
53
+ private
54
+
55
+ def env_options
22
56
  hash = {
23
57
  bundle_identifier: ENV['PRODUCE_APP_IDENTIFIER'],
24
58
  app_name: ENV['PRODUCE_APP_NAME'],
@@ -42,38 +76,12 @@ module Produce
42
76
  hash
43
77
  end
44
78
 
45
- def initialize(options = {})
46
- @config = Config.env_options.merge(options)
47
- end
48
-
49
- def self.val(key)
50
- raise "Please only pass symbols, no Strings to this method".red unless key.kind_of? Symbol
51
-
52
- unless shared_config.config.has_key? key
53
- shared_config.config[key] = ask(ASK_MESSAGES[key]) do |q|
54
- case key
55
- when :primary_language
56
- q.validate = lambda { |val| is_valid_language?(val) }
57
- q.responses[:not_valid] = "Please enter one of available languages: #{AvailableDefaultLanguages.all_langauges}"
58
- else
59
- q.validate = lambda { |val| !val.empty? }
60
- q.responses[:not_valid] = "#{key.to_s.gsub('_', ' ').capitalize} can't be blank"
61
- end
62
- end
63
- end
64
-
65
- return self.shared_config.config[key]
66
- end
67
-
68
- def self.has_key?(key)
69
- shared_config.config.has_key? key
70
- end
71
79
 
72
- def self.is_valid_language? language
80
+ def is_valid_language? language
73
81
  AvailableDefaultLanguages.all_langauges.include? language
74
82
  end
75
83
 
76
- def self.skip_itc? value
84
+ def skip_itc? value
77
85
  %w( true t 1 yes y ).include? value.to_s.downcase
78
86
  end
79
87
  end
@@ -1,192 +1,12 @@
1
- require 'credentials_manager/password_manager'
2
- require 'open-uri'
3
- require 'openssl'
1
+ require 'fastlane_core/developer_center/developer_center'
4
2
 
5
- require 'capybara'
6
- require 'capybara/poltergeist'
7
- require 'phantomjs/poltergeist'
8
-
9
- module Produce
3
+ module FastlaneCore
10
4
  class DeveloperCenter
11
- # This error occurs only if there is something wrong with the given login data
12
- class DeveloperCenterLoginError < StandardError
13
- end
14
-
15
- # This error can occur for many reaons. It is
16
- # usually raised when a UI element could not be found
17
- class DeveloperCenterGeneralError < StandardError
18
- end
19
-
20
- # Types of certificates
21
- APPSTORE = "AppStore"
22
- ADHOC = "AdHoc"
23
- DEVELOPMENT = "Development"
24
-
25
- include Capybara::DSL
26
-
27
- DEVELOPER_CENTER_URL = "https://developer.apple.com/devcenter/ios/index.action"
28
5
  APPS_URL = "https://developer.apple.com/account/ios/identifiers/bundle/bundleList.action"
29
6
  CREATE_APP_URL = "https://developer.apple.com/account/ios/identifiers/bundle/bundleCreate.action"
30
7
 
31
-
32
-
33
- def initialize
34
- FileUtils.mkdir_p TMP_FOLDER
35
-
36
- Capybara.run_server = false
37
- Capybara.default_driver = :poltergeist
38
- Capybara.javascript_driver = :poltergeist
39
- Capybara.current_driver = :poltergeist
40
- Capybara.app_host = DEVELOPER_CENTER_URL
41
-
42
- # Since Apple has some SSL errors, we have to configure the client properly:
43
- # https://github.com/ariya/phantomjs/issues/11239
44
- Capybara.register_driver :poltergeist do |a|
45
- conf = ['--debug=no', '--ignore-ssl-errors=yes', '--ssl-protocol=TLSv1']
46
- Capybara::Poltergeist::Driver.new(a, {
47
- phantomjs: Phantomjs.path,
48
- phantomjs_options: conf,
49
- phantomjs_logger: File.open("#{TMP_FOLDER}/poltergeist_log.txt", "a"),
50
- js_errors: false
51
- })
52
- end
53
-
54
- page.driver.headers = { "Accept-Language" => "en" }
55
-
56
- self.login
57
- end
58
-
59
- # Loggs in a user with the given login data on the Dev Center Frontend.
60
- # You don't need to pass a username and password. It will
61
- # Automatically be fetched using the {CredentialsManager::PasswordManager}.
62
- # This method will also automatically be called when triggering other
63
- # actions like {#open_app_page}
64
- # @param user (String) (optional) The username/email address
65
- # @param password (String) (optional) The password
66
- # @return (bool) true if everything worked fine
67
- # @raise [DeveloperCenterGeneralError] General error while executing
68
- # this action
69
- # @raise [DeveloperCenterLoginError] Login data is wrong
70
- def login(user = nil, password = nil)
71
- begin
72
- Helper.log.info "Login into iOS Developer Center"
73
-
74
- user ||= CredentialsManager::PasswordManager.shared_manager.username
75
- password ||= CredentialsManager::PasswordManager.shared_manager.password
76
-
77
- result = visit APPS_URL
78
- raise "Could not open Developer Center" unless result['status'] == 'success'
79
-
80
- if page.has_content?"Member Center"
81
- # Already logged in
82
- return true
83
- end
84
-
85
- (wait_for_elements(".button.blue").first.click rescue nil) # maybe already logged in
86
-
87
- (wait_for_elements('#accountpassword') rescue nil) # when the user is already logged in, this will raise an exception
88
-
89
- if page.has_content?"Member Center"
90
- # Already logged in
91
- return true
92
- end
93
-
94
- fill_in "accountname", with: user
95
- fill_in "accountpassword", with: password
96
-
97
- all(".button.large.blue.signin-button").first.click
98
-
99
- begin
100
- if page.has_content?"Select Team" # If the user is not on multiple teams
101
- select_team
102
- end
103
- rescue => ex
104
- Helper.log.debug ex
105
- raise DeveloperCenterLoginError.new("Error loggin in user #{user}. User is on multiple teams and we couldn't select the one specified.")
106
- end
107
-
108
- begin
109
- wait_for_elements('.toolbar-button.add.navLink')
110
- visit APPS_URL # again, since after the login, the dev center loses the GET value
111
- rescue => ex
112
- Helper.log.debug ex
113
- if page.has_content?"Getting Started"
114
- raise "There was no valid signing certificate found. Please log in and follow the 'Getting Started guide' on '#{current_url}'".red
115
- else
116
- raise DeveloperCenterLoginError.new("Error logging in user #{user} with the given password. Make sure you entered them correctly.")
117
- end
118
- end
119
-
120
-
121
- Helper.log.info "Login successful"
122
-
123
- true
124
- rescue => ex
125
- error_occured(ex)
126
- end
127
- end
128
-
129
- def select_team
130
- team_id = Config.val(:team_id) if Config.has_key?(:team_id)
131
- team_name = Config.val(:team_name) if Config.has_key?(:team_name)
132
-
133
- if team_id == nil and team_name == nil
134
- Helper.log.info "You can store you preferred team using the environment variable `PRODUCE_TEAM_ID` or `PRODUCE_TEAM_NAME`".green
135
- Helper.log.info "Your ID belongs to the following teams:".green
136
- end
137
-
138
- available_options = []
139
-
140
- teams = find("div.input").all('.team-value') # Grab all the teams data
141
- teams.each_with_index do |val, index|
142
- current_team_id = '"' + val.find("input").value + '"'
143
- team_text = val.find(".label-primary").text
144
- description_text = val.find(".label-secondary").text
145
- description_text = "(#{description_text})" unless description_text.empty? # Include the team description if any
146
- index_text = (index + 1).to_s + "."
147
-
148
- available_options << [index_text, current_team_id, team_text, description_text].join(" ")
149
- end
150
-
151
- if team_name
152
- # Search for name
153
- found_it = false
154
- all("label.label-primary").each do |current|
155
- if current.text.downcase.gsub(/\s+/, "") == team_name.downcase.gsub(/\s+/, "")
156
- current.click # select the team by name
157
- found_it = true
158
- end
159
- end
160
-
161
- unless found_it
162
- available_teams = all("label.label-primary").collect { |a| a.text }
163
- raise DeveloperCenterLoginError.new("Could not find Team with name '#{team_name}'. Available Teams: #{available_teams}".red)
164
- end
165
- else
166
- # Search by ID/Index
167
- unless team_id
168
- puts available_options.join("\n").green
169
- team_index = ask("Please select the team number you would like to access: ".green)
170
- team_id = teams[team_index.to_i - 1].find(".radio").value
171
- end
172
-
173
- team_button = first(:xpath, "//input[@type='radio' and @value='#{team_id}']") # Select the desired team
174
- if team_button
175
- team_button.click
176
- else
177
- Helper.log.fatal "Could not find given Team. Available options: ".red
178
- puts available_options.join("\n").yellow
179
- raise DeveloperCenterLoginError.new("Error finding given team #{team_id}.".red)
180
- end
181
- end
182
-
183
- all(".button.large.blue.submit").first.click
184
-
185
- result = visit APPS_URL
186
- raise "Could not open Developer Center" unless result['status'] == 'success'
187
- end
188
-
189
- def run
8
+ def run(config)
9
+ @config = config
190
10
  create_new_app
191
11
  rescue => ex
192
12
  error_occured(ex)
@@ -194,22 +14,27 @@ module Produce
194
14
 
195
15
  def create_new_app
196
16
  if app_exists?
197
- Helper.log.info "App '#{Config.val(:app_name)}' already exists, nothing to do on the Dev Center".green
17
+ Helper.log.info "App '#{@config[:app_name]}' already exists, nothing to do on the Dev Center".green
198
18
  ENV["CREATED_NEW_APP_ID"] = nil
199
19
  # Nothing to do here
200
20
  else
201
- Helper.log.info "Creating new app '#{Config.val(:app_name)}' on the Apple Dev Center".green
21
+ Helper.log.info "Creating new app '#{@config[:app_name]}' on the Apple Dev Center".green
202
22
  visit CREATE_APP_URL
203
- wait_for_elements("*[name='appIdName']").first.set Config.val(:app_name)
204
- wait_for_elements("*[name='explicitIdentifier']").first.set Config.val(:bundle_identifier)
23
+ wait_for_elements("*[name='appIdName']").first.set @config[:app_name]
24
+ wait_for_elements("*[name='explicitIdentifier']").first.set @config[:bundle_identifier]
205
25
  click_next
206
26
 
207
- sleep 3 # sometimes this takes a while and we don't want to timeout
27
+ sleep 5 # sometimes this takes a while and we don't want to timeout
28
+
29
+ if all(".form-error").count > 0
30
+ error = all(".form-error").collect { |a| a.text }.join("\n")
31
+ raise error.red
32
+ end
208
33
 
209
34
  wait_for_elements("form[name='bundleSubmit']") # this will show the summary of the given information
210
35
  click_next
211
36
 
212
- sleep 3 # sometimes this takes a while and we don't want to timeout
37
+ sleep 5 # sometimes this takes a while and we don't want to timeout
213
38
 
214
39
  wait_for_elements(".ios.bundles.confirmForm.complete")
215
40
  click_on "Done"
@@ -218,7 +43,7 @@ module Produce
218
43
 
219
44
  ENV["CREATED_NEW_APP_ID"] = Time.now.to_s
220
45
 
221
- Helper.log.info "Finished creating new app '#{Config.val(:app_name)}' on the Dev Center".green
46
+ Helper.log.info "Finished creating new app '#{@config[:app_name]}' on the Dev Center".green
222
47
  end
223
48
 
224
49
  return true
@@ -232,7 +57,7 @@ module Produce
232
57
  wait_for_elements("td[aria-describedby='grid-table_identifier']").each do |app|
233
58
  identifier = app['title']
234
59
 
235
- return true if identifier.to_s == Config.val(:bundle_identifier).to_s
60
+ return true if identifier.to_s == @config[:bundle_identifier].to_s
236
61
  end
237
62
 
238
63
  false
@@ -241,48 +66,5 @@ module Produce
241
66
  def click_next
242
67
  wait_for_elements('.button.small.blue.right.submit').last.click
243
68
  end
244
-
245
- def error_occured(ex)
246
- snap
247
- raise ex # re-raise the error after saving the snapshot
248
- end
249
-
250
- def snap
251
- path = "Error#{Time.now.to_i}.png"
252
- save_screenshot(path, :full => true)
253
- system("open '#{path}'")
254
- end
255
-
256
- def wait_for(method, parameter, success)
257
- counter = 0
258
- result = method.call(parameter)
259
- while !success.call(result)
260
- sleep 0.2
261
-
262
- result = method.call(parameter)
263
-
264
- counter += 1
265
- if counter > 100
266
- Helper.log.debug caller
267
- raise DeveloperCenterGeneralError.new("Couldn't find '#{parameter}' after waiting for quite some time")
268
- end
269
- end
270
- return result
271
- end
272
-
273
- def wait_for_elements(name)
274
- method = Proc.new { |n| all(name) }
275
- success = Proc.new { |r| r.count > 0 }
276
- return wait_for(method, name, success)
277
- end
278
-
279
- def wait_for_variable(name)
280
- method = Proc.new { |n|
281
- retval = page.html.match(/var #{n} = "(.*)"/)
282
- retval[1] unless retval == nil
283
- }
284
- success = Proc.new { |r| r != nil }
285
- return wait_for(method, name, success)
286
- end
287
69
  end
288
70
  end
@@ -1,109 +1,16 @@
1
- require 'capybara'
2
- require 'capybara/poltergeist'
3
- require 'credentials_manager/password_manager'
4
- require 'phantomjs/poltergeist'
1
+ require 'fastlane_core/itunes_connect/itunes_connect'
5
2
 
6
- module Produce
3
+ module FastlaneCore
7
4
  # Every method you call here, might take a time
8
5
  class ItunesConnect
9
- # This error occurs only if there is something wrong with the given login data
10
- class ItunesConnectLoginError < StandardError
11
- end
12
-
13
- # This error can occur for many reaons. It is
14
- # usually raised when a UI element could not be found
15
- class ItunesConnectGeneralError < StandardError
16
- end
17
-
18
- include Capybara::DSL
19
-
20
- ITUNESCONNECT_URL = "https://itunesconnect.apple.com/"
6
+
21
7
  APPS_URL = "https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa/ra/ng/app"
22
8
 
23
9
  NEW_APP_CLASS = ".new-button.ng-isolate-scope"
24
-
25
- def initialize
26
- super
27
10
 
28
- DependencyChecker.check_dependencies
29
-
30
- Capybara.run_server = false
31
- Capybara.default_driver = :poltergeist
32
- Capybara.javascript_driver = :poltergeist
33
- Capybara.current_driver = :poltergeist
34
- Capybara.app_host = ITUNESCONNECT_URL
35
-
36
- # Since Apple has some SSL errors, we have to configure the client properly:
37
- # https://github.com/ariya/phantomjs/issues/11239
38
- Capybara.register_driver :poltergeist do |a|
39
- conf = ['--debug=no', '--ignore-ssl-errors=yes', '--ssl-protocol=TLSv1']
40
- Capybara::Poltergeist::Driver.new(a, {
41
- phantomjs: Phantomjs.path,
42
- phantomjs_options: conf,
43
- phantomjs_logger: File.open("/tmp/poltergeist_log.txt", "a"),
44
- js_errors: false
45
- })
46
- end
47
-
48
- page.driver.headers = { "Accept-Language" => "en" }
49
-
50
- self.login
51
- end
11
+ def run(config)
12
+ @config = config
52
13
 
53
- # Loggs in a user with the given login data on the iTC Frontend.
54
- # You don't need to pass a username and password. It will
55
- # Automatically be fetched using the {CredentialsManager::PasswordManager}.
56
- # This method will also automatically be called when triggering other
57
- # actions like {#open_app_page}
58
- # @param user (String) (optional) The username/email address
59
- # @param password (String) (optional) The password
60
- # @return (bool) true if everything worked fine
61
- # @raise [ItunesConnectGeneralError] General error while executing
62
- # this action
63
- # @raise [ItunesConnectLoginError] Login data is wrong
64
- def login(user = nil, password = nil)
65
- begin
66
- Helper.log.info "Logging into iTunesConnect"
67
-
68
- user ||= CredentialsManager::PasswordManager.shared_manager.username
69
- password ||= CredentialsManager::PasswordManager.shared_manager.password
70
-
71
- result = visit ITUNESCONNECT_URL
72
- raise "Could not open iTunesConnect" unless result['status'] == 'success'
73
-
74
- (wait_for_elements('#accountpassword') rescue nil) # when the user is already logged in, this will raise an exception
75
-
76
- if page.has_content?"My Apps"
77
- # Already logged in
78
- return true
79
- end
80
-
81
- fill_in "accountname", with: user
82
- fill_in "accountpassword", with: password
83
-
84
- begin
85
- (wait_for_elements(".enabled").first.click rescue nil) # Login Button
86
- wait_for_elements('.homepageWrapper.ng-scope')
87
-
88
- if page.has_content?"My Apps"
89
- # Everything looks good
90
- else
91
- raise ItunesConnectLoginError.new("Looks like your login data was correct, but you do not have access to the apps.")
92
- end
93
- rescue => ex
94
- Helper.log.debug(ex)
95
- raise ItunesConnectLoginError.new("Error logging in user #{user} with the given password. Make sure you entered them correctly.")
96
- end
97
-
98
- Helper.log.info "Successfully logged into iTunesConnect"
99
-
100
- true
101
- rescue => ex
102
- error_occured(ex)
103
- end
104
- end
105
-
106
- def run
107
14
  if ENV["CREATED_NEW_APP_ID"].to_i > 0
108
15
  # We just created this App ID, this takes about 3 minutes to show up on iTunes Connect
109
16
  Helper.log.info "Waiting for 3 minutes to make sure, the App ID is synced to iTunes Connect".yellow
@@ -121,10 +28,10 @@ module Produce
121
28
 
122
29
  def create_new_app
123
30
  if app_exists?
124
- Helper.log.info "App '#{Config.val(:app_name)}' exists already, nothing to do on iTunes Connect".green
31
+ Helper.log.info "App '#{@config[:app_name]}' exists already, nothing to do on iTunes Connect".green
125
32
  # Nothing to do here
126
33
  else
127
- Helper.log.info "Creating new app '#{Config.val(:app_name)}' on iTunes Connect".green
34
+ Helper.log.info "Creating new app '#{@config[:app_name]}' on iTunes Connect".green
128
35
 
129
36
  initial_create
130
37
 
@@ -132,7 +39,7 @@ module Produce
132
39
 
133
40
  raise "Something went wrong when creating the new app - it's not listed in the App's list" unless app_exists?
134
41
 
135
- Helper.log.info "Finished creating new app '#{Config.val(:app_name)}' on iTunes Connect".green
42
+ Helper.log.info "Finished creating new app '#{@config[:app_name]}' on iTunes Connect".green
136
43
  end
137
44
 
138
45
  return fetch_apple_id
@@ -140,12 +47,12 @@ module Produce
140
47
 
141
48
  def fetch_apple_id
142
49
  # First try it using the Apple API
143
- data = JSON.parse(open("https://itunes.apple.com/lookup?bundleId=#{Config.val(:bundle_identifier)}").read)
50
+ data = JSON.parse(open("https://itunes.apple.com/lookup?bundleId=#{@config[:bundle_identifier]}").read)
144
51
 
145
52
  if data['resultCount'] == 0 or true
146
53
  visit current_url
147
54
  sleep 10
148
- first("input[ng-model='searchModel']").set Config.val(:bundle_identifier)
55
+ first("input[ng-model='searchModel']").set @config[:bundle_identifier]
149
56
 
150
57
  if all("div[bo-bind='app.name']").count == 2
151
58
  raise "There were multiple results when looking for the new app. This might be due to having same app identifiers included in each other (see generated screenshots)".red
@@ -165,12 +72,12 @@ module Produce
165
72
  open_new_app_popup
166
73
 
167
74
  # Fill out the initial information
168
- wait_for_elements("input[ng-model='createAppDetails.newApp.name.value']").first.set Config.val(:app_name)
169
- wait_for_elements("input[ng-model='createAppDetails.versionString.value']").first.set Config.val(:version)
170
- wait_for_elements("input[ng-model='createAppDetails.newApp.vendorId.value']").first.set Config.val(:sku)
75
+ wait_for_elements("input[ng-model='createAppDetails.newApp.name.value']").first.set @config[:app_name]
76
+ wait_for_elements("input[ng-model='createAppDetails.versionString.value']").first.set @config[:version]
77
+ wait_for_elements("input[ng-model='createAppDetails.newApp.vendorId.value']").first.set @config[:sku]
171
78
 
172
- wait_for_elements("option[value='#{Config.val(:bundle_identifier)}']").first.select_option
173
- all(:xpath, "//option[text()='#{Config.val(:primary_language)}']").first.select_option
79
+ wait_for_elements("option[value='#{@config[:bundle_identifier]}']").first.select_option
80
+ all(:xpath, "//option[text()='#{@config[:primary_language]}']").first.select_option
174
81
 
175
82
  click_on "Create"
176
83
  sleep 5 # this usually takes some time
@@ -181,7 +88,7 @@ module Produce
181
88
 
182
89
  wait_for_elements(".language.hasPopOver") # looking good
183
90
 
184
- Helper.log.info "Successfully created new app '#{Config.val(:app_name)}' on iTC. Setting up the initial information now.".green
91
+ Helper.log.info "Successfully created new app '#{@config[:app_name]}' on iTC. Setting up the initial information now.".green
185
92
  end
186
93
 
187
94
  def initial_pricing
@@ -197,12 +104,12 @@ module Produce
197
104
 
198
105
  sleep 4
199
106
 
200
- return (all("option[value='#{Config.val(:bundle_identifier)}']").count == 0)
107
+ return (all("option[value='#{@config[:bundle_identifier]}']").count == 0)
201
108
  end
202
109
 
203
110
  def open_new_app_popup
204
111
  visit APPS_URL
205
- sleep 5 # this usually takes some time
112
+ sleep 8 # this usually takes some time
206
113
 
207
114
  wait_for_elements(NEW_APP_CLASS).first.click
208
115
  wait_for_elements('#new-menu > * > a').first.click # Create a new App
@@ -210,34 +117,5 @@ module Produce
210
117
  sleep 5 # this usually takes some time - this is important
211
118
  wait_for_elements("input[ng-model='createAppDetails.newApp.name.value']") # finish loading
212
119
  end
213
-
214
- def error_occured(ex)
215
- snap
216
- raise ex # re-raise the error after saving the snapshot
217
- end
218
-
219
- def snap
220
- path = "Error#{Time.now.to_i}.png"
221
- save_screenshot(path, :full => true)
222
- system("open '#{path}'")
223
- end
224
-
225
- def wait_for_elements(name)
226
- counter = 0
227
- results = all(name)
228
- while results.count == 0
229
- # Helper.log.debug "Waiting for #{name}"
230
- sleep 0.2
231
-
232
- results = all(name)
233
-
234
- counter += 1
235
- if counter > 100
236
- Helper.log.debug caller
237
- raise ItunesConnectGeneralError.new("Couldn't find element '#{name}' after waiting for quite some time")
238
- end
239
- end
240
- return results
241
- end
242
120
  end
243
121
  end
@@ -1,8 +1,11 @@
1
1
  module Produce
2
2
  class Manager
3
- def self.start_producing
4
- DeveloperCenter.new.run
5
- return ItunesConnect.new.run unless Config.val(:skip_itc)
3
+ # Produces app at DeveloperCenter and ItunesConnect
4
+ # @param config (Config) (optional) config to use. Will fallback to
5
+ # config with ENV values if not specified.
6
+ def self.start_producing(config = Config.new)
7
+ FastlaneCore::DeveloperCenter.new.run(config)
8
+ return FastlaneCore::ItunesConnect.new.run(config) unless config[:skip_itc]
6
9
  end
7
10
  end
8
11
  end
@@ -1,3 +1,3 @@
1
1
  module Produce
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.4"
3
3
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: produce
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Felix Krause
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-04 00:00:00.000000000 Z
11
+ date: 2015-02-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: json
14
+ name: fastlane_core
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - '>='
@@ -24,104 +24,6 @@ dependencies:
24
24
  - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: highline
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ~>
32
- - !ruby/object:Gem::Version
33
- version: 1.6.21
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ~>
39
- - !ruby/object:Gem::Version
40
- version: 1.6.21
41
- - !ruby/object:Gem::Dependency
42
- name: colored
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - '>='
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - '>='
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: commander
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ~>
60
- - !ruby/object:Gem::Version
61
- version: 4.2.0
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ~>
67
- - !ruby/object:Gem::Version
68
- version: 4.2.0
69
- - !ruby/object:Gem::Dependency
70
- name: credentials_manager
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - '>='
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :runtime
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - '>='
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: phantomjs
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ~>
88
- - !ruby/object:Gem::Version
89
- version: 1.9.8
90
- type: :runtime
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ~>
95
- - !ruby/object:Gem::Version
96
- version: 1.9.8
97
- - !ruby/object:Gem::Dependency
98
- name: capybara
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ~>
102
- - !ruby/object:Gem::Version
103
- version: 2.4.3
104
- type: :runtime
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ~>
109
- - !ruby/object:Gem::Version
110
- version: 2.4.3
111
- - !ruby/object:Gem::Dependency
112
- name: poltergeist
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ~>
116
- - !ruby/object:Gem::Version
117
- version: 1.5.1
118
- type: :runtime
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ~>
123
- - !ruby/object:Gem::Version
124
- version: 1.5.1
125
27
  - !ruby/object:Gem::Dependency
126
28
  name: bundler
127
29
  requirement: !ruby/object:Gem::Requirement
@@ -237,10 +139,8 @@ files:
237
139
  - lib/produce/config.rb
238
140
  - lib/produce/dependency_checker.rb
239
141
  - lib/produce/developer_center.rb
240
- - lib/produce/helper.rb
241
142
  - lib/produce/itunes_connect.rb
242
143
  - lib/produce/manager.rb
243
- - lib/produce/update_checker.rb
244
144
  - lib/produce/version.rb
245
145
  homepage: http://fastlane.tools
246
146
  licenses:
@@ -1,49 +0,0 @@
1
- require 'logger'
2
-
3
- module Produce
4
- module Helper
5
-
6
- # Logging happens using this method
7
- def self.log
8
- if is_test?
9
- @@log ||= Logger.new(STDOUT) # don't show any logs when running tests
10
- else
11
- @@log ||= Logger.new(STDOUT)
12
- end
13
-
14
- @@log.formatter = proc do |severity, datetime, progname, msg|
15
- string = "#{severity} [#{datetime.strftime('%Y-%m-%d %H:%M:%S.%2N')}]: "
16
- second = "#{msg}\n"
17
-
18
- if severity == "DEBUG"
19
- string = string.magenta
20
- elsif severity == "INFO"
21
- string = string.white
22
- elsif severity == "WARN"
23
- string = string.yellow
24
- elsif severity == "ERROR"
25
- string = string.red
26
- elsif severity == "FATAL"
27
- string = string.red.bold
28
- end
29
-
30
-
31
- [string, second].join("")
32
- end
33
-
34
- @@log
35
- end
36
-
37
- # @return true if the currently running program is a unit test
38
- def self.is_test?
39
- defined?SpecHelper
40
- end
41
-
42
- # @return the full path to the Xcode developer tools of the currently
43
- # running system
44
- def self.xcode_path
45
- return "" if self.is_test? and not OS.mac?
46
- `xcode-select -p`.gsub("\n", '') + "/"
47
- end
48
- end
49
- end
@@ -1,44 +0,0 @@
1
- require 'open-uri'
2
-
3
- module Produce
4
- # Verifies, the user runs the latest version of this gem
5
- class UpdateChecker
6
- # This method will check if the latest version is installed and show a warning if that's not the case
7
- def self.verify_latest_version
8
- if self.update_available?
9
- v = fetch_latest
10
- puts '#######################################################################'.green
11
- puts "# produce #{v} is available.".green
12
- puts "# It is recommended to use the latest version.".green
13
- puts "# Update using '(sudo) gem update produce'.".green
14
- puts "# To see what's new, open https://github.com/KrauseFx/produce/releases.".green
15
- puts '#######################################################################'.green
16
- return true
17
- end
18
- false
19
- end
20
-
21
- # Is a new official release available (this does not include pre-releases)
22
- def self.update_available?
23
- begin
24
- latest = fetch_latest
25
- if latest and Gem::Version.new(latest) > Gem::Version.new(current_version)
26
- return true
27
- end
28
- rescue => ex
29
- Helper.log.error("Could not check if 'produce' is up to date.")
30
- end
31
- return false
32
- end
33
-
34
- # The currently used version of this gem
35
- def self.current_version
36
- Produce::VERSION
37
- end
38
-
39
- private
40
- def self.fetch_latest
41
- JSON.parse(open("http://rubygems.org/api/v1/gems/produce.json").read)["version"]
42
- end
43
- end
44
- end