deliver 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 221e6f16252aa538e403f17cdf318edb2dd6ea20
4
- data.tar.gz: fb4058c128cc42e5f871714c41c23b521949557e
3
+ metadata.gz: 1aa9678c4c8f492ca46805f1ac07c306a14c7675
4
+ data.tar.gz: eb392c8ca031399725e9a106e88599356b7ae508
5
5
  SHA512:
6
- metadata.gz: 860cdd383422e8e531c73db2bc549d2a56d8db91465275b3c4266746fad5cb2dd7e65b870adf71f81aac5abfe18c387ec76b6905362b697cf725bb3dab8beb6e
7
- data.tar.gz: a76927b8bbbcf2b4f63b1a10410f0b55d82c96d6a130d8eb124ed7a345b1ae462d0f6753e4cb0357ef001752c67b56761cd8e68f812d340e6b492d5729d37620
6
+ metadata.gz: 03ebce1c92b8cf19827ef6a70c7b6a686235e3fa424ff2ad44f46281a8f04d30d80e7077da9661448a7969b0f04afd5cf6a26e87cd4b93d0d813385138bbf0b9
7
+ data.tar.gz: 5400a931ee5717062c523f47e2e0d828e0f20bf29458d80ea3340b0885899bde6a043020b0d5fbc3d78e9477607469333fdc083b29fa44168393b63c301435b7
data/README.md CHANGED
@@ -108,7 +108,9 @@ Run ```deliver init``` to create a new ```Deliverfile```. You can either let the
108
108
 
109
109
  Once you created your configuration, just run ```deliver```.
110
110
 
111
- Here are a few example files:
111
+ All available commands with a short description can be found in [Deliverfile.md](https://github.com/KrauseFx/deliver/blob/master/Deliverfile.md).
112
+
113
+ Here are a few examples:
112
114
  #### Upload screenshots to iTunes Connect
113
115
  ```ruby
114
116
  app_identifier "net.sunapps.1"
@@ -175,7 +177,7 @@ end
175
177
  ```
176
178
 
177
179
 
178
- #### Set a default language if you are lucky enough to only maintain one language
180
+ #### Set a default language if you only maintain one language
179
181
  ```ruby
180
182
  default_language "en-US"
181
183
  version "1.2"
@@ -223,7 +225,7 @@ As you can see, the ```Deliverfile``` is a normal Ruby file, which is executed w
223
225
  running a deployment. Therefore it's possible to fully customise the behaviour
224
226
  on a deployment.
225
227
 
226
- All available commands with a short description can be found in the [wiki](https://github.com/KrauseFx/deliver/wiki/All-available-commands-of-the-Deliverfile).
228
+ All available commands with a short description can be found in [Deliverfile.md](https://github.com/KrauseFx/deliver/blob/master/Deliverfile.md).
227
229
 
228
230
  **Some examples:**
229
231
 
data/bin/deliver CHANGED
@@ -3,31 +3,76 @@
3
3
  $:.push File.expand_path("../../lib", __FILE__)
4
4
 
5
5
  require 'deliver'
6
- require 'commander/import'
6
+ require 'commander'
7
7
 
8
8
  HighLine.track_eof = false
9
9
 
10
+ class FastlaneApplication
11
+ include Commander::Methods
10
12
 
11
- # Commander
12
- program :version, Deliver::VERSION
13
- program :description, 'CLI for \'Deliver\' - Upload screenshots, metadata and your app to the App Store using a single command'
14
- program :help, 'Author', 'Felix Krause <deliver@krausefx.com>'
15
- program :help, 'Website', 'http://fastlane.tools'
16
- program :help, 'GitHub', 'https://github.com/krausefx/deliver'
17
- program :help_formatter, :compact
13
+ def run
14
+ program :version, Deliver::VERSION
15
+ program :description, 'CLI for \'Deliver\' - Upload screenshots, metadata and your app to the App Store using a single command'
16
+ program :help, 'Author', 'Felix Krause <deliver@krausefx.com>'
17
+ program :help, 'Website', 'http://fastlane.tools'
18
+ program :help, 'GitHub', 'https://github.com/krausefx/deliver'
19
+ program :help_formatter, :compact
18
20
 
19
- global_option('--verbose') { $verbose = true }
21
+ global_option('--verbose') { $verbose = true }
20
22
 
23
+ command :run do |c|
24
+ c.syntax = 'deliver'
25
+ c.description = 'Run a deploy process using the Deliverfile in the current folder'
26
+ c.option '--force', 'Runs a deployment without verifying any information (PDF file). This can be used for build servers.'
27
+ c.option '--beta', 'Runs a deployment to beta build on iTunes Connect'
28
+ c.option '--skip-deploy', 'Skips deployment on iTunes Connect'
29
+ c.action do |args, options|
30
+ path = (Deliver::Helper.fastlane_enabled?? './fastlane' : '.')
31
+ Dir.chdir(path) do # switch the context
32
+ if File.exists?(deliver_path)
33
+ # Everything looks alright, use the given Deliverfile
34
+ options.default :beta => false, :skip_deploy => false
35
+ Deliver::Deliverer.new(deliver_path, force: options.force, is_beta_ipa: options.beta, skip_deploy: options.skip_deploy)
36
+ else
37
+ Deliver::Helper.log.warn("No Deliverfile found at path '#{deliver_path}'.")
38
+ if agree("Do you want to create a new Deliverfile at the current directory? (y/n)", true)
39
+ Deliver::DeliverfileCreator.create(enclosed_directory)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
21
45
 
22
- default_command :run
46
+ command :init do |c|
47
+ c.syntax = 'deliver init'
48
+ c.description = "Creates a new Deliverfile in the current directory"
23
49
 
24
- require 'deliver/commands'
50
+ c.action do |args, options|
51
+ Deliver::DeliverfileCreator.create(enclosed_directory)
52
+ end
53
+ end
54
+
55
+
56
+ def set_username(username)
57
+ user = username
58
+ user ||= ENV["DELIVER_USERNAME"]
59
+ user ||= CredentialsManager::AppfileConfig.try_fetch_value(:apple_id)
60
+ CredentialsManager::PasswordManager.shared_manager(user) if user
61
+ end
62
+
63
+ default_command :run
64
+
65
+ run!
66
+ end
67
+ end
25
68
 
26
69
  def deliver_path
27
- [enclosed_directory, Deliver::Deliverfile::Deliverfile::FILE_NAME].join('/')
70
+ File.join(enclosed_directory, Deliver::Deliverfile::Deliverfile::FILE_NAME)
28
71
  end
29
72
 
30
73
  # The directoy in which the Deliverfile and metadata should be created
31
74
  def enclosed_directory
32
75
  "."
33
- end
76
+ end
77
+
78
+ FastlaneApplication.new.run
@@ -8,10 +8,6 @@
8
8
  # App Metadata
9
9
  ########################################
10
10
 
11
- # The app identifier is required
12
- app_identifier "[[APP_IDENTIFIER]]"
13
- apple_id "[[APPLE_ID]]"
14
-
15
11
 
16
12
  # This folder has to include one folder for each language
17
13
  # More information about automatic screenshot upload:
@@ -23,7 +19,6 @@ screenshots_path "./deliver/screenshots/"
23
19
 
24
20
  config_json_folder './deliver'
25
21
 
26
-
27
22
  ########################################
28
23
  # Building and Testing
29
24
  ########################################
data/lib/deliver.rb CHANGED
@@ -5,7 +5,7 @@ require 'deliver/app'
5
5
  require 'deliver/app_metadata'
6
6
  require 'deliver/metadata_item'
7
7
  require 'deliver/app_screenshot'
8
- require 'deliver/itunes_connect'
8
+ require 'deliver/itunes_connect/itunes_connect'
9
9
  require 'deliver/itunes_search_api'
10
10
  require 'deliver/itunes_transporter'
11
11
  require 'deliver/deliverfile/deliverfile'
data/lib/deliver/app.rb CHANGED
@@ -45,6 +45,7 @@ module Deliver
45
45
  rescue
46
46
  unless Helper.is_test?
47
47
  Helper.log.info "Could not find Apple ID based on the app identifier in the US App Store. Maybe the app is not yet in the store?".yellow
48
+ Helper.log.info "You can provde the Apple ID of your app using `apple_id '974739333'` in your `Deliverfile`".green
48
49
 
49
50
  while ((self.apple_id || '').to_s.length == 0) || ((self.apple_id || 0).to_i == 0)
50
51
  self.apple_id = ask("\nApple ID of your app (e.g. 284882215): ")
@@ -118,12 +119,12 @@ module Deliver
118
119
  end
119
120
 
120
121
 
121
- # # Uploads a new app icon to iTunesConnect. This uses a headless browser
122
- # # which makes this command quite slow.
123
- # # @param (path) a path to the new app icon. The image must have the resolution of 1024x1024
124
- # def update_app_icon!(path)
125
- # itc.update_app_icon!(self, path)
126
- # end
122
+ # Uploads a new app icon to iTunesConnect. This uses a headless browser
123
+ # which makes this command quite slow.
124
+ # @param (path) a path to the new app icon. The image must have the resolution of 1024x1024
125
+ def upload_app_icon!(path)
126
+ itc.upload_app_icon!(self, path)
127
+ end
127
128
 
128
129
  #####################################################
129
130
  # @!group Destructive/Constructive methods
@@ -1,4 +1,5 @@
1
1
  require 'nokogiri'
2
+ require 'deliver/app_metadata_screenshots'
2
3
 
3
4
  module Deliver
4
5
  class AppMetadataError < StandardError
@@ -197,157 +198,16 @@ module Deliver
197
198
  end
198
199
  end
199
200
 
200
- #####################################################
201
- # @!group Screenshot related
202
- #####################################################
203
-
204
- # Removes all currently enabled screenshots for the given language.
205
- # @param (String) language The language, which has to be in this list: {Deliver::Languages}.
206
- def clear_all_screenshots(language)
207
- raise AppMetadataParameterError.new(INVALID_LANGUAGE_ERROR) unless Languages::ALL_LANGUAGES.include?language
208
-
209
- update_localized_value('software_screenshots', {language => {}}) do |field, useless, language|
210
- field.children.remove # remove all the screenshots
211
- end
212
- information[language][:screenshots] = []
213
- true
214
- end
215
-
216
- # Appends another screenshot to the already existing ones
217
- # @param (String) language The language, which has to be in this list: {Deliver::Languages}.
218
- # @param (Deliver::AppScreenshot) app_screenshot The screenshot you want to add to the app metadata.
219
- # @raise (AppMetadataTooManyScreenshotsError) When there are already 5 screenshots (MAXIMUM_NUMBER_OF_SCREENSHOTS).
220
-
221
- def add_screenshot(language, app_screenshot)
222
- raise AppMetadataParameterError.new(INVALID_LANGUAGE_ERROR) unless Languages::ALL_LANGUAGES.include?language
223
-
224
- create_locale_if_not_exists(language)
225
-
226
- # Fetch the 'software_screenshots' node (array) for the specific locale
227
- locales = self.fetch_value("//x:locale[@name='#{language}']")
228
-
229
- screenshots = self.fetch_value("//x:locale[@name='#{language}']/x:software_screenshots").first
201
+ # Updates the price tier of the given app
202
+ # @param (Integer) tier The tier that should be used from now on
203
+ def update_price_tier(tier)
204
+ raise "Price Tier '#{tier}' must be of type integer".red unless tier.kind_of?Integer
205
+ raise "Invalid price tier '#{tier}' given, must be 0 to 94".red unless (tier.to_i >= 0 and tier.to_i <= 87)
230
206
 
231
- if not screenshots or screenshots.children.count == 0
232
- screenshots.remove if screenshots
233
-
234
- # First screenshot ever
235
- screenshots = Nokogiri::XML::Node.new('software_screenshots', @data)
236
- locales.first << screenshots
237
-
238
- node_set = Nokogiri::XML::NodeSet.new(@data)
239
- node_set << app_screenshot.create_xml_node(@data, 1)
240
- screenshots.children = node_set
241
- else
242
- # There is already at least one screenshot
243
- next_index = 1
244
- screenshots.children.each do |screen|
245
- if screen['display_target'] == app_screenshot.screen_size
246
- next_index += 1
247
- end
248
- end
249
-
250
- if next_index > MAXIMUM_NUMBER_OF_SCREENSHOTS
251
- raise AppMetadataTooManyScreenshotsError.new("Only #{MAXIMUM_NUMBER_OF_SCREENSHOTS} screenshots are allowed per language per device type (#{app_screenshot.screen_size})")
252
- end
253
-
254
- # Ready for storing the screenshot into the metadata.xml now
255
- screenshots.children.after(app_screenshot.create_xml_node(@data, next_index))
256
- end
257
-
258
- information[language][:screenshots] << app_screenshot
259
-
260
- app_screenshot.store_file_inside_package(@package_path)
207
+ price = fetch_value("//x:wholesale_price_tier").last
208
+ price.content = tier
261
209
  end
262
210
 
263
- # This method will clear all screenshots and set the new ones you pass
264
- # @param new_screenshots
265
- # +code+
266
- # {
267
- # 'de-DE' => [
268
- # AppScreenshot.new('path/screenshot1.png', Deliver::ScreenSize::IOS_35),
269
- # AppScreenshot.new('path/screenshot2.png', Deliver::ScreenSize::IOS_40),
270
- # AppScreenshot.new('path/screenshot3.png', Deliver::ScreenSize::IOS_IPAD)
271
- # ]
272
- # }
273
- # This method uses {#clear_all_screenshots} and {#add_screenshot} under the hood.
274
- # @return [bool] true if everything was successful
275
- # @raise [AppMetadataParameterError] error is raised when parameters are invalid
276
- def set_all_screenshots(new_screenshots)
277
- error_text = "Please pass a hash, containing an array of AppScreenshot objects"
278
- raise AppMetadataParameterError.new(error_text) unless new_screenshots.kind_of?Hash
279
-
280
- new_screenshots.each do |key, value|
281
- if key.kind_of?String and value.kind_of?Array and value.count > 0 and value.first.kind_of?AppScreenshot
282
-
283
- self.clear_all_screenshots(key)
284
-
285
- value.each do |screen|
286
- add_screenshot(key, screen)
287
- end
288
- else
289
- raise AppMetadataParameterError.new(error_text)
290
- end
291
- end
292
- true
293
- end
294
-
295
- # Automatically add all screenshots contained in the given directory to the app.
296
- #
297
- # This method will automatically detect which device type each screenshot is.
298
- #
299
- # This will also clear all existing screenshots before setting the new ones.
300
- # @param (Hash) hash A hash containing a different path for each locale ({Deliver::Languages::ALL_LANGUAGES})
301
- def set_screenshots_for_each_language(hash)
302
- raise AppMetadataParameterError.new("Parameter needs to be an hash, containg strings with the new description") unless hash.kind_of?Hash
303
-
304
- hash.each do |language, current_path|
305
- resulting_path = "#{current_path}/**/*.{png,jpg,jpeg}"
306
-
307
- raise AppMetadataParameterError.new(INVALID_LANGUAGE_ERROR) unless Languages::ALL_LANGUAGES.include?language
308
-
309
- # https://stackoverflow.com/questions/21688855/
310
- # File::FNM_CASEFOLD = ignore case
311
- if Dir.glob(resulting_path, File::FNM_CASEFOLD).count == 0
312
- Helper.log.error("No screenshots found at the given path '#{resulting_path}'")
313
- else
314
- self.clear_all_screenshots(language)
315
-
316
- Dir.glob(resulting_path, File::FNM_CASEFOLD).sort.each do |path|
317
- next if path.include?"_framed."
318
-
319
- begin
320
- add_screenshot(language, Deliver::AppScreenshot.new(path))
321
- rescue AppMetadataTooManyScreenshotsError => ex
322
- # We just use the first 5 ones
323
- end
324
- end
325
- end
326
- end
327
-
328
- true
329
- end
330
-
331
- # This method will run through all the available locales, check if there is
332
- # a folder for this language (e.g. 'en-US') and use all screenshots in there
333
- # @param (String) path A path to the folder, which contains a folder for each locale
334
- def set_all_screenshots_from_path(path)
335
- raise AppMetadataParameterError.new("Parameter needs to be a path (string)") unless path.kind_of?String
336
-
337
- found = false
338
- Deliver::Languages::ALL_LANGUAGES.each do |language|
339
- full_path = path + "/#{language}"
340
- if File.directory?(full_path)
341
- found = true
342
- set_screenshots_for_each_language({
343
- language => full_path
344
- })
345
- end
346
- end
347
- return found
348
- end
349
-
350
-
351
211
  #####################################################
352
212
  # @!group Manually fetching elements from the metadata.xml
353
213
  #####################################################
@@ -0,0 +1,153 @@
1
+ module Deliver
2
+ class AppMetadata
3
+ #####################################################
4
+ # @!group Screenshot related
5
+ #####################################################
6
+
7
+ # Removes all currently enabled screenshots for the given language.
8
+ # @param (String) language The language, which has to be in this list: {Deliver::Languages}.
9
+ def clear_all_screenshots(language)
10
+ raise AppMetadataParameterError.new(INVALID_LANGUAGE_ERROR) unless Languages::ALL_LANGUAGES.include?language
11
+
12
+ update_localized_value('software_screenshots', {language => {}}) do |field, useless, language|
13
+ field.children.remove # remove all the screenshots
14
+ end
15
+ information[language][:screenshots] = []
16
+ true
17
+ end
18
+
19
+ # Appends another screenshot to the already existing ones
20
+ # @param (String) language The language, which has to be in this list: {Deliver::Languages}.
21
+ # @param (Deliver::AppScreenshot) app_screenshot The screenshot you want to add to the app metadata.
22
+ # @raise (AppMetadataTooManyScreenshotsError) When there are already 5 screenshots (MAXIMUM_NUMBER_OF_SCREENSHOTS).
23
+
24
+ def add_screenshot(language, app_screenshot)
25
+ raise AppMetadataParameterError.new(INVALID_LANGUAGE_ERROR) unless Languages::ALL_LANGUAGES.include?language
26
+
27
+ create_locale_if_not_exists(language)
28
+
29
+ # Fetch the 'software_screenshots' node (array) for the specific locale
30
+ locales = self.fetch_value("//x:locale[@name='#{language}']")
31
+
32
+ screenshots = self.fetch_value("//x:locale[@name='#{language}']/x:software_screenshots").first
33
+
34
+ if not screenshots or screenshots.children.count == 0
35
+ screenshots.remove if screenshots
36
+
37
+ # First screenshot ever
38
+ screenshots = Nokogiri::XML::Node.new('software_screenshots', @data)
39
+ locales.first << screenshots
40
+
41
+ node_set = Nokogiri::XML::NodeSet.new(@data)
42
+ node_set << app_screenshot.create_xml_node(@data, 1)
43
+ screenshots.children = node_set
44
+ else
45
+ # There is already at least one screenshot
46
+ next_index = 1
47
+ screenshots.children.each do |screen|
48
+ if screen['display_target'] == app_screenshot.screen_size
49
+ next_index += 1
50
+ end
51
+ end
52
+
53
+ if next_index > MAXIMUM_NUMBER_OF_SCREENSHOTS
54
+ raise AppMetadataTooManyScreenshotsError.new("Only #{MAXIMUM_NUMBER_OF_SCREENSHOTS} screenshots are allowed per language per device type (#{app_screenshot.screen_size})")
55
+ end
56
+
57
+ # Ready for storing the screenshot into the metadata.xml now
58
+ screenshots.children.after(app_screenshot.create_xml_node(@data, next_index))
59
+ end
60
+
61
+ information[language][:screenshots] << app_screenshot
62
+
63
+ app_screenshot.store_file_inside_package(@package_path)
64
+ end
65
+
66
+ # This method will clear all screenshots and set the new ones you pass
67
+ # @param new_screenshots
68
+ # +code+
69
+ # {
70
+ # 'de-DE' => [
71
+ # AppScreenshot.new('path/screenshot1.png', Deliver::ScreenSize::IOS_35),
72
+ # AppScreenshot.new('path/screenshot2.png', Deliver::ScreenSize::IOS_40),
73
+ # AppScreenshot.new('path/screenshot3.png', Deliver::ScreenSize::IOS_IPAD)
74
+ # ]
75
+ # }
76
+ # This method uses {#clear_all_screenshots} and {#add_screenshot} under the hood.
77
+ # @return [bool] true if everything was successful
78
+ # @raise [AppMetadataParameterError] error is raised when parameters are invalid
79
+ def set_all_screenshots(new_screenshots)
80
+ error_text = "Please pass a hash, containing an array of AppScreenshot objects"
81
+ raise AppMetadataParameterError.new(error_text) unless new_screenshots.kind_of?Hash
82
+
83
+ new_screenshots.each do |key, value|
84
+ if key.kind_of?String and value.kind_of?Array and value.count > 0 and value.first.kind_of?AppScreenshot
85
+
86
+ self.clear_all_screenshots(key)
87
+
88
+ value.each do |screen|
89
+ add_screenshot(key, screen)
90
+ end
91
+ else
92
+ raise AppMetadataParameterError.new(error_text)
93
+ end
94
+ end
95
+ true
96
+ end
97
+
98
+ # Automatically add all screenshots contained in the given directory to the app.
99
+ #
100
+ # This method will automatically detect which device type each screenshot is.
101
+ #
102
+ # This will also clear all existing screenshots before setting the new ones.
103
+ # @param (Hash) hash A hash containing a different path for each locale ({Deliver::Languages::ALL_LANGUAGES})
104
+ def set_screenshots_for_each_language(hash)
105
+ raise AppMetadataParameterError.new("Parameter needs to be an hash, containg strings with the new description") unless hash.kind_of?Hash
106
+
107
+ hash.each do |language, current_path|
108
+ resulting_path = "#{current_path}/**/*.{png,jpg,jpeg}"
109
+
110
+ raise AppMetadataParameterError.new(INVALID_LANGUAGE_ERROR) unless Languages::ALL_LANGUAGES.include?language
111
+
112
+ # https://stackoverflow.com/questions/21688855/
113
+ # File::FNM_CASEFOLD = ignore case
114
+ if Dir.glob(resulting_path, File::FNM_CASEFOLD).count == 0
115
+ Helper.log.error("No screenshots found at the given path '#{resulting_path}'")
116
+ else
117
+ self.clear_all_screenshots(language)
118
+
119
+ Dir.glob(resulting_path, File::FNM_CASEFOLD).sort.each do |path|
120
+ next if path.include?"_framed."
121
+
122
+ begin
123
+ add_screenshot(language, Deliver::AppScreenshot.new(path))
124
+ rescue AppMetadataTooManyScreenshotsError => ex
125
+ # We just use the first 5 ones
126
+ end
127
+ end
128
+ end
129
+ end
130
+
131
+ true
132
+ end
133
+
134
+ # This method will run through all the available locales, check if there is
135
+ # a folder for this language (e.g. 'en-US') and use all screenshots in there
136
+ # @param (String) path A path to the folder, which contains a folder for each locale
137
+ def set_all_screenshots_from_path(path)
138
+ raise AppMetadataParameterError.new("Parameter needs to be a path (string)") unless path.kind_of?String
139
+
140
+ found = false
141
+ Deliver::Languages::ALL_LANGUAGES.each do |language|
142
+ full_path = path + "/#{language}"
143
+ if File.directory?(full_path)
144
+ found = true
145
+ set_screenshots_for_each_language({
146
+ language => full_path
147
+ })
148
+ end
149
+ end
150
+ return found
151
+ end
152
+ end
153
+ end