deliver 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 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