deliver 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +37 -10
  3. data/.rspec +1 -0
  4. data/.travis.yml +8 -0
  5. data/.yardopts +1 -0
  6. data/Gemfile.lock +106 -0
  7. data/LICENSE +21 -0
  8. data/README.md +268 -17
  9. data/Rakefile +3 -0
  10. data/assets/PDFExample.png +0 -0
  11. data/assets/SubmitForReviewInformation.png +0 -0
  12. data/assets/deliver.png +0 -0
  13. data/assets/deliver.pxm +0 -0
  14. data/assets/deliverFullSize.png +0 -0
  15. data/bin/deliver +32 -0
  16. data/deliver.gemspec +15 -9
  17. data/lib/assets/DeliverfileDefault +47 -0
  18. data/lib/assets/DeliverfileExample +62 -0
  19. data/lib/assets/ScreenshotsHelp +4 -0
  20. data/lib/deliver.rb +20 -1
  21. data/lib/deliver/app.rb +146 -0
  22. data/lib/deliver/app_metadata.rb +487 -0
  23. data/lib/deliver/app_screenshot.rb +119 -0
  24. data/lib/deliver/commands.rb +4 -0
  25. data/lib/deliver/commands/init.rb +12 -0
  26. data/lib/deliver/commands/run.rb +20 -0
  27. data/lib/deliver/deliver_process.rb +241 -0
  28. data/lib/deliver/deliverer.rb +112 -0
  29. data/lib/deliver/deliverfile/deliverfile.rb +35 -0
  30. data/lib/deliver/deliverfile/deliverfile_creator.rb +115 -0
  31. data/lib/deliver/deliverfile/dsl.rb +124 -0
  32. data/lib/deliver/dependency_checker.rb +32 -0
  33. data/lib/deliver/helper.rb +55 -0
  34. data/lib/deliver/ipa_uploader.rb +160 -0
  35. data/lib/deliver/itunes_connect.rb +514 -0
  36. data/lib/deliver/itunes_search_api.rb +48 -0
  37. data/lib/deliver/itunes_transporter.rb +154 -0
  38. data/lib/deliver/languages.rb +6 -0
  39. data/lib/deliver/metadata_item.rb +94 -0
  40. data/lib/deliver/password_manager.rb +86 -0
  41. data/lib/deliver/pdf_generator.rb +131 -0
  42. data/lib/deliver/version.rb +1 -1
  43. data/spec/app_metadata_spec.rb +350 -0
  44. data/spec/app_screenshot_spec.rb +88 -0
  45. data/spec/app_spec.rb +85 -0
  46. data/spec/deliverer_spec.rb +48 -0
  47. data/spec/deliverfile_creator_spec.rb +73 -0
  48. data/spec/example_deliver_files_spec.rb +227 -0
  49. data/spec/fixtures/Deliverfiles/DeliverfileCallbacks +14 -0
  50. data/spec/fixtures/Deliverfiles/DeliverfileCallbacksFailingTests +14 -0
  51. data/spec/fixtures/Deliverfiles/DeliverfileCallbacksNoErrorBlock +6 -0
  52. data/spec/fixtures/Deliverfiles/DeliverfileDefaultLanguageNotOnTop +8 -0
  53. data/spec/fixtures/Deliverfiles/DeliverfileDuplicateIpa +2 -0
  54. data/spec/fixtures/Deliverfiles/DeliverfileLocales +16 -0
  55. data/spec/fixtures/Deliverfiles/DeliverfileMetadataJson +6 -0
  56. data/spec/fixtures/Deliverfiles/DeliverfileMissingAppVersion +1 -0
  57. data/spec/fixtures/Deliverfiles/DeliverfileMissingBlockForTests +7 -0
  58. data/spec/fixtures/Deliverfiles/DeliverfileMissingIdentifier +1 -0
  59. data/spec/fixtures/Deliverfiles/DeliverfileMissingLanguage +1 -0
  60. data/spec/fixtures/Deliverfiles/DeliverfileMissingValue +3 -0
  61. data/spec/fixtures/Deliverfiles/DeliverfileMixed +37 -0
  62. data/spec/fixtures/Deliverfiles/DeliverfileNoVersion +3 -0
  63. data/spec/fixtures/Deliverfiles/DeliverfileScreenshots +6 -0
  64. data/spec/fixtures/Deliverfiles/DeliverfileScreenshotsFallbackDefaultLanguage +7 -0
  65. data/spec/fixtures/Deliverfiles/DeliverfileSimple +8 -0
  66. data/spec/fixtures/Deliverfiles/DeliverfileVersionMismatchPackage +8 -0
  67. data/spec/fixtures/Deliverfiles/DeliverfileWrongIdentifier +5 -0
  68. data/spec/fixtures/Deliverfiles/DeliverfileWrongVersion +5 -0
  69. data/spec/fixtures/Deliverfiles/metadata.json +24 -0
  70. data/spec/fixtures/example1.itmsp/metadata.xml +121 -0
  71. data/spec/fixtures/example2.itmsp/metadata.xml +54 -0
  72. data/spec/fixtures/ipas/Example1.ipa +0 -0
  73. data/spec/fixtures/metadata/ipa_result.xml +12 -0
  74. data/spec/fixtures/metadata/ipa_result2.xml +12 -0
  75. data/spec/fixtures/packages/464686641.itmsp/metadata.xml +104 -0
  76. data/spec/fixtures/packages/794902327.itmsp/metadata.xml +107 -0
  77. data/spec/fixtures/packages/878567776.itmsp/metadata.xml +104 -0
  78. data/spec/fixtures/screenshots/de-DE/iPhone4.png +0 -0
  79. data/spec/fixtures/screenshots/de-DE/iPhone6.png +0 -0
  80. data/spec/fixtures/screenshots/de-DE/iPhone6Plus1.png +0 -0
  81. data/spec/fixtures/screenshots/de-DE/iPhone6Plus2.png +0 -0
  82. data/spec/fixtures/screenshots/de-DE/screenshot1.png +0 -0
  83. data/spec/fixtures/screenshots/de-DE/screenshot2.png +0 -0
  84. data/spec/fixtures/screenshots/de-DE/screenshot3.png +0 -0
  85. data/spec/fixtures/screenshots/de-DE/screenshot5.png +0 -0
  86. data/spec/fixtures/screenshots/en-US/english.png +0 -0
  87. data/spec/fixtures/screenshots/iPhone4.png +0 -0
  88. data/spec/fixtures/screenshots/invalidImage.png +0 -0
  89. data/spec/fixtures/screenshots/screenshot1.png +0 -0
  90. data/spec/fixtures/screenshots/tooMany/de-DE/iPhone4 2.png +0 -0
  91. data/spec/fixtures/screenshots/tooMany/de-DE/iPhone4 copy 2.png +0 -0
  92. data/spec/fixtures/screenshots/tooMany/de-DE/iPhone4 copy 3.png +0 -0
  93. data/spec/fixtures/screenshots/tooMany/de-DE/iPhone4 copy 4.png +0 -0
  94. data/spec/fixtures/screenshots/tooMany/de-DE/iPhone4 copy 5.png +0 -0
  95. data/spec/fixtures/screenshots/tooMany/de-DE/iPhone4 copy 6.png +0 -0
  96. data/spec/fixtures/screenshots/tooMany/de-DE/iPhone4 copy.png +0 -0
  97. data/spec/fixtures/screenshots/tooMany/de-DE/iPhone4.png +0 -0
  98. data/spec/helper_spec.rb +16 -0
  99. data/spec/ipa_uploader_spec.rb +61 -0
  100. data/spec/itunes_connect_spec.rb +12 -0
  101. data/spec/itunes_search_api_spec.rb +24 -0
  102. data/spec/itunes_transporter_spec.rb +52 -0
  103. data/spec/languages_spec.rb +7 -0
  104. data/spec/metadata_item_spec.rb +36 -0
  105. data/spec/mocking/transporter_mocking.rb +40 -0
  106. data/spec/mocking/webmocking.rb +31 -0
  107. data/spec/password_manager_spec.rb +27 -0
  108. data/spec/responses/itunesLookup-.json +4 -0
  109. data/spec/responses/itunesLookup-0.json +4 -0
  110. data/spec/responses/itunesLookup-284882215.json +106 -0
  111. data/spec/responses/itunesLookup-at.felixkrause.iTanky.json +8 -0
  112. data/spec/responses/itunesLookup-com.facebook.Facebook.json +106 -0
  113. data/spec/responses/itunesLookup-invalid.json +4 -0
  114. data/spec/responses/itunesLookup-net.sunapps.invalid.json +4 -0
  115. data/spec/responses/transporter/download_invalid_apple_id.txt +35 -0
  116. data/spec/responses/transporter/download_valid_apple_id.txt +32 -0
  117. data/spec/responses/transporter/upload_invalid.txt +174 -0
  118. data/spec/responses/transporter/upload_valid.txt +290 -0
  119. data/spec/spec_helper.rb +23 -0
  120. data/tasks/rspec.rake +3 -0
  121. metadata +242 -8
  122. data/LICENSE.txt +0 -22
@@ -0,0 +1,119 @@
1
+ require 'fastimage'
2
+
3
+
4
+ module Deliver
5
+ # AppScreenshot represents one screenshots for one specific locale and
6
+ # device type.
7
+ class AppScreenshot < MetadataItem
8
+ module ScreenSize
9
+ # iPhone 4
10
+ IOS_35 = "iOS-3.5-in"
11
+ # iPhone 5
12
+ IOS_40 = "iOS-4-in"
13
+ # iPhone 6
14
+ IOS_47 = "iOS-4.7-in"
15
+ # iPhone 6 Plus
16
+ IOS_55 = "iOS-5.5-in"
17
+ # iPad
18
+ IOS_IPAD = "iOS-iPad"
19
+ end
20
+
21
+ # @return [Deliver::ScreenSize] the screen size (device type)
22
+ # specified at {Deliver::ScreenSize}
23
+ attr_accessor :screen_size
24
+
25
+ # @param path (String) path to the screenshot file
26
+ # @param screen_size (Deliver::AppScreenshot::ScreenSize) the screen size, which
27
+ # will automatically be calculated when you don't set it.
28
+ def initialize(path, screen_size = nil)
29
+ super(path)
30
+
31
+ screen_size ||= self.class.calculate_screen_size(path)
32
+
33
+ self.screen_size = screen_size
34
+
35
+ Helper.log.error "Looks like the screenshot given (#{path}) does not match the requirements of #{screen_size}" unless self.is_valid?
36
+ end
37
+
38
+ def create_xml_node(doc, order_index)
39
+ node = super(doc)
40
+
41
+ # Screenshots have a slightly different xml code
42
+
43
+ # <software_screenshot display_target="iOS-4-in" position="1">
44
+ # <size>295276</size>
45
+ # <file_name>1-en-4-StartScreen.png</file_name>
46
+ # <checksum type="md5">c00bd122a3ffbc79e26f1ae6210c7efd</checksum>
47
+ # </software_screenshot>
48
+
49
+
50
+ node['display_target'] = self.screen_size
51
+ node['position'] = order_index
52
+
53
+ return node
54
+ end
55
+
56
+ def name_for_xml_node
57
+ 'software_screenshot'
58
+ end
59
+
60
+ # Validates the given screenshots (size and format)
61
+ def is_valid?
62
+ return false unless self.path.split(".").last == "png"
63
+
64
+ size = FastImage.size(self.path)
65
+
66
+ return self.screen_size == self.class.calculate_screen_size(self.path)
67
+ end
68
+
69
+ def self.calculate_screen_size(path)
70
+ size = FastImage.size(path)
71
+
72
+ raise "Could not find or parse file at path '#{path}'" if (size == nil or size.count == 0)
73
+
74
+ devices = {
75
+ ScreenSize::IOS_55 => [
76
+ [1080, 1920],
77
+ [1242, 2208]
78
+ ],
79
+ ScreenSize::IOS_47 => [
80
+ [750, 1334]
81
+ ],
82
+ ScreenSize::IOS_40 => [
83
+ [640, 1136],
84
+ [640, 1096],
85
+ [1136, 600] # landscape status bar is smaller
86
+ ],
87
+ ScreenSize::IOS_35 => [
88
+ [640, 960],
89
+ [640, 920],
90
+ [960, 600] # landscape status bar is smaller
91
+ ],
92
+ ScreenSize::IOS_IPAD => [
93
+ [1024, 748],
94
+ [1024, 768],
95
+ [2048, 1496],
96
+ [2048, 1536],
97
+ [768, 1004],
98
+ [768, 1024],
99
+ [1536, 2008],
100
+ [1536, 2048]
101
+ ]
102
+ }
103
+
104
+ devices.each do |device_type, array|
105
+ array.each do |resolution|
106
+ if (size[0] == resolution[0] and size[1] == resolution[1]) or # portrait
107
+ (size[1] == resolution[0] and size[0] == resolution[1]) # landscape
108
+ return device_type
109
+ end
110
+ end
111
+ end
112
+
113
+ error = "Unsupported screen size #{size} for path '#{path}'"
114
+ raise error
115
+ end
116
+ end
117
+
118
+ ScreenSize = AppScreenshot::ScreenSize
119
+ end
@@ -0,0 +1,4 @@
1
+ $:.push File.expand_path('../', __FILE__)
2
+
3
+ require 'commands/init'
4
+ require 'commands/run'
@@ -0,0 +1,12 @@
1
+
2
+
3
+ command :init do |c|
4
+ c.syntax = 'deliver init'
5
+ c.description = "Creates a new Deliverfile in the current directory"
6
+
7
+ c.action do |args, options|
8
+ Deliver::DependencyChecker.check_dependencies
9
+
10
+ Deliver::DeliverfileCreator.create(enclosed_directory)
11
+ end
12
+ end
@@ -0,0 +1,20 @@
1
+
2
+
3
+ command :run do |c|
4
+ c.syntax = 'deliver'
5
+ c.description = 'Run a deploy process using the Deliverfile in the current folder'
6
+ c.option '--force', 'Runs a deployment without verifying any information (PDF file). This can be used for build servers.'
7
+ c.action do |args, options|
8
+ Deliver::DependencyChecker.check_dependencies
9
+
10
+ if File.exists?(deliver_path)
11
+ # Everything looks alright, use the given Deliverfile
12
+ Deliver::Deliverer.new(deliver_path, force: options.force)
13
+ else
14
+ Deliver::Helper.log.warn("No Deliverfile found at path '#{deliver_path}'.")
15
+ if agree("Do you want to create a new Deliverfile at the current directory? (y/n)", true)
16
+ Deliver::DeliverfileCreator.create(enclosed_directory)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,241 @@
1
+ module Deliver
2
+ # This class takes care of verifying all inputs and triggering the upload process
3
+ class DeliverProcess
4
+
5
+ # DeliverUnitTestsError is triggered, when the unit tests of the given block failed.
6
+ class DeliverUnitTestsError < StandardError
7
+ end
8
+
9
+ # @return (Deliver::App) The App that is currently being edited.
10
+ attr_accessor :app
11
+
12
+ # @return (Hash) All the updated/new information we got from the Deliverfile.
13
+ # is used to store the deploy information until the Deliverfile finished running.
14
+ attr_accessor :deploy_information
15
+
16
+ def initialize(deploy_information = nil)
17
+ @deploy_information = deploy_information || {}
18
+ @deploy_information[:blocks] ||= {}
19
+ end
20
+
21
+ def run
22
+ begin
23
+ run_unit_tests
24
+ fetch_information_from_ipa_file
25
+
26
+ Helper.log.info("Got all information needed to deploy a new update ('#{@app_version}') for app '#{@app_identifier}'")
27
+
28
+ verify_ipa_file
29
+ create_app
30
+ verify_app_on_itunesconnect
31
+
32
+ load_metadata_from_config_json_folder # the json file generated from the quick start
33
+ set_app_metadata
34
+ set_screenshots
35
+
36
+ verify_pdf_file
37
+
38
+ trigger_metadata_upload
39
+ trigger_ipa_upload
40
+
41
+ call_success_block
42
+ rescue Exception => ex
43
+ call_error_block(ex)
44
+ end
45
+ end
46
+
47
+ #####################################################
48
+ # @!group All the methods
49
+ #####################################################
50
+
51
+ def run_unit_tests
52
+ if @deploy_information[:blocks][:unit_tests]
53
+ result = @deploy_information[:blocks][:unit_tests].call
54
+ if result
55
+ Helper.log.debug("Unit tests successful".green)
56
+ else
57
+ raise DeliverUnitTestsError.new("Unit tests failed. Got result: '#{result}'. Need 'true' or 1 to succeed.".red)
58
+ end
59
+ end
60
+ end
61
+
62
+ def fetch_information_from_ipa_file
63
+ @app_version = @deploy_information[Deliverer::ValKey::APP_VERSION]
64
+ @app_identifier = @deploy_information[Deliverer::ValKey::APP_IDENTIFIER]
65
+
66
+ used_ipa_file = @deploy_information[:ipa] || @deploy_information[:beta_ipa]
67
+
68
+ if used_ipa_file
69
+ @ipa = Deliver::IpaUploader.new(Deliver::App.new, '/tmp/', used_ipa_file, is_beta_build?)
70
+
71
+ # We are able to fetch some metadata directly from the ipa file
72
+ # If they were also given in the Deliverfile, we will compare the values
73
+ @app_identifier = verify_app_identifier(@app_identifier)
74
+ @app_version = verify_app_version(@app_version)
75
+ end
76
+ end
77
+
78
+ def verify_ipa_file
79
+ raise Deliverfile::Deliverfile::DeliverfileDSLError.new(Deliverfile::Deliverfile::MISSING_APP_IDENTIFIER_MESSAGE.red) unless @app_identifier
80
+ raise Deliverfile::Deliverfile::DeliverfileDSLError.new(Deliverfile::Deliverfile::MISSING_VERSION_NUMBER_MESSAGE.red) unless @app_version
81
+ if (@deploy_information[Deliverer::ValKey::IPA] and @deploy_information[Deliverer::ValKey::BETA_IPA])
82
+ raise Deliverfile::Deliverfile::DeliverfileDSLError.new("You can not set both ipa and beta_ipa in one file. Either it's a beta build or a release build".red)
83
+ end
84
+ end
85
+
86
+ def create_app
87
+ @app = Deliver::App.new(app_identifier: @app_identifier,
88
+ apple_id: @deploy_information[Deliverer::ValKey::APPLE_ID])
89
+ end
90
+
91
+ def verify_app_on_itunesconnect
92
+ if @ipa and not is_beta_build?
93
+ # This is a real release, which should also upload the ipa file onto production
94
+ @app.create_new_version!(@app_version) unless Helper.is_test?
95
+ @app.metadata.verify_version(@app_version)
96
+ end
97
+ end
98
+
99
+ def load_metadata_from_config_json_folder
100
+ return unless @deploy_information[Deliverer::ValKey::CONFIG_JSON_FOLDER]
101
+
102
+ matching = {
103
+ 'title' => Deliverer::ValKey::TITLE,
104
+ 'description' => Deliverer::ValKey::DESCRIPTION,
105
+ 'version_whats_new' => Deliverer::ValKey::CHANGELOG,
106
+ 'keywords' => Deliverer::ValKey::KEYWORDS,
107
+ 'privacy_url' => Deliverer::ValKey::PRIVACY_URL,
108
+ 'software_url' => Deliverer::ValKey::MARKETING_URL,
109
+ 'support_url' => Deliverer::ValKey::SUPPORT_URL
110
+ }
111
+
112
+ file_path = @deploy_information[:config_json_folder]
113
+ unless file_path.split("/").last.include?"metadata.json"
114
+ file_path += "/metadata.json"
115
+ end
116
+
117
+ raise "Could not find metadatafile at path '#{file_path}'".red unless File.exists?file_path
118
+
119
+ content = JSON.parse(File.read(file_path))
120
+ content.each do |language, current|
121
+
122
+ matching.each do |key, value|
123
+ if current[key]
124
+ @deploy_information[value] ||= {}
125
+ @deploy_information[value][language] = current[key]
126
+ end
127
+ end
128
+ end
129
+ end
130
+
131
+ def set_app_metadata
132
+ @app.metadata.update_title(@deploy_information[Deliverer::ValKey::TITLE]) if @deploy_information[Deliverer::ValKey::TITLE]
133
+ @app.metadata.update_description(@deploy_information[Deliverer::ValKey::DESCRIPTION]) if @deploy_information[Deliverer::ValKey::DESCRIPTION]
134
+
135
+ @app.metadata.update_support_url(@deploy_information[Deliverer::ValKey::SUPPORT_URL]) if @deploy_information[Deliverer::ValKey::SUPPORT_URL]
136
+ @app.metadata.update_changelog(@deploy_information[Deliverer::ValKey::CHANGELOG]) if @deploy_information[Deliverer::ValKey::CHANGELOG]
137
+ @app.metadata.update_marketing_url(@deploy_information[Deliverer::ValKey::MARKETING_URL]) if @deploy_information[Deliverer::ValKey::MARKETING_URL]
138
+ @app.metadata.update_privacy_url(@deploy_information[Deliverer::ValKey::PRIVACY_URL]) if @deploy_information[Deliverer::ValKey::PRIVACY_URL]
139
+
140
+ @app.metadata.update_keywords(@deploy_information[Deliverer::ValKey::KEYWORDS]) if @deploy_information[Deliverer::ValKey::KEYWORDS]
141
+ end
142
+
143
+ def set_screenshots
144
+ screens_path = @deploy_information[Deliverer::ValKey::SCREENSHOTS_PATH]
145
+ if screens_path
146
+ if not @app.metadata.set_all_screenshots_from_path(screens_path)
147
+ # This path does not contain folders for each language
148
+ if screens_path.kind_of?String
149
+ if @deploy_information[Deliverer::ValKey::DEFAULT_LANGUAGE]
150
+ screens_path = { @deploy_information[Deliverer::ValKey::DEFAULT_LANGUAGE] => screens_path } # use the default language
151
+ @deploy_information[Deliverer::ValKey::SCREENSHOTS_PATH] = screens_path
152
+ else
153
+ Helper.log.error "You must have folders for the screenshots (#{screens_path}) for each language (e.g. en-US, de-DE)."
154
+ screens_path = nil
155
+ end
156
+ end
157
+ @app.metadata.set_screenshots_for_each_language(screens_path) if screens_path
158
+ end
159
+ end
160
+ end
161
+
162
+ def verify_pdf_file
163
+ if @deploy_information[Deliverer::ValKey::SKIP_PDF] or is_beta_build?
164
+ Helper.log.debug "PDF verify was skipped"
165
+ else
166
+ # Everything is prepared for the upload
167
+ # We may have to ask the user if that's okay
168
+ pdf_path = PdfGenerator.new.render(self)
169
+ unless Helper.is_test?
170
+ puts "----------------------------------------------------------------------------"
171
+ puts "Verifying the upload via the PDF file can be disabled by either adding"
172
+ puts "'skip_pdf true' to your Deliverfile or using the flag --force."
173
+ puts "----------------------------------------------------------------------------"
174
+
175
+ system("open '#{pdf_path}'")
176
+ okay = agree("Does the PDF on path '#{pdf_path}' look okay for you? (blue = updated) (y/n)", true)
177
+ raise "Did not upload the metadata, because the PDF file was rejected by the user".yellow unless okay
178
+ end
179
+ end
180
+ end
181
+
182
+ def trigger_metadata_upload
183
+ result = @app.metadata.upload!
184
+ raise "Error uploading app metadata".red unless result == true
185
+ end
186
+
187
+ def trigger_ipa_upload
188
+ if @ipa
189
+ @ipa.app = @app # we now have the resulting app
190
+ result = @ipa.upload! # Important: this will also actually deploy the app on iTunesConnect
191
+ raise "Error uploading ipa file".red unless result == true
192
+ else
193
+ Helper.log.warn "No IPA file given. Only the metadata was uploaded. If you want to deploy a full update, provide an ipa file."
194
+ end
195
+ end
196
+
197
+ def call_success_block
198
+ @deploy_information[:blocks][:success].call if @deploy_information[:blocks][:success]
199
+ end
200
+
201
+ def call_error_block(ex)
202
+ if @deploy_information[:blocks][:error]
203
+ # Custom error handling, we just call this one
204
+ @deploy_information[:blocks][:error].call(ex)
205
+ else
206
+ # Re-Raise the exception
207
+ raise ex
208
+ end
209
+ end
210
+
211
+ private
212
+ #####################################################
213
+ # @!group All the helper methods
214
+ #####################################################
215
+ def verify_app_identifier(app_identifier)
216
+ if app_identifier
217
+ if @ipa.fetch_app_identifier and app_identifier != @ipa.fetch_app_identifier
218
+ raise Deliver::Deliverfile::Deliverfile::DeliverfileDSLError.new("App Identifier of IPA does not match with the given one ('#{app_identifier}' != '#{@ipa.fetch_app_identifier}')".red)
219
+ end
220
+ else
221
+ app_identifier = @ipa.fetch_app_identifier
222
+ end
223
+ return app_identifier
224
+ end
225
+
226
+ def verify_app_version(app_version)
227
+ if app_version
228
+ if @ipa.fetch_app_version and app_version != @ipa.fetch_app_version
229
+ raise Deliver::Deliverfile::Deliverfile::DeliverfileDSLError.new("App Version of IPA does not match with the given one (#{app_version} != #{@ipa.fetch_app_version})".red)
230
+ end
231
+ else
232
+ app_version = @ipa.fetch_app_version
233
+ end
234
+ return app_version
235
+ end
236
+
237
+ def is_beta_build?
238
+ @deploy_information[Deliverer::ValKey::BETA_IPA] != nil
239
+ end
240
+ end
241
+ end
@@ -0,0 +1,112 @@
1
+ module Deliver
2
+ # This class will collect the deploy data from different places
3
+ # This will trigger:
4
+ #
5
+ # - Parsing the Deliverfile
6
+ # - Temporary storing all the information got from the file, until the file finished executing
7
+ # - Triggering the upload process itself using the DeliverProcess class
8
+ class Deliverer
9
+ # @return (Deliver::Deliverfile::Deliverfile) A reference
10
+ # to the Deliverfile which is currently being used.
11
+ attr_accessor :deliver_file
12
+
13
+ # @return (Deliver::DeliverProcess) The class which handels the deployment process itself
14
+ attr_accessor :deliver_process
15
+
16
+ module ValKey
17
+ APP_IDENTIFIER = :app_identifier
18
+ APPLE_ID = :apple_id
19
+ APP_VERSION = :version
20
+ IPA = :ipa
21
+ BETA_IPA = :beta_ipa
22
+ DESCRIPTION = :description
23
+ TITLE = :title
24
+ CHANGELOG = :changelog
25
+ SUPPORT_URL = :support_url
26
+ PRIVACY_URL = :privacy_url
27
+ MARKETING_URL = :marketing_url
28
+ KEYWORDS = :keywords
29
+ SCREENSHOTS_PATH = :screenshots_path
30
+ DEFAULT_LANGUAGE = :default_language
31
+ CONFIG_JSON_FOLDER = :config_json_folder # Path to a folder containing a configuration file and including screenshots
32
+ SKIP_PDF = :skip_pdf
33
+ SUBMIT_FURTHER_INFORMATION = :submit_further_information # export compliance, content rights and advertising identifier
34
+ end
35
+
36
+ module AllBlocks
37
+ UNIT_TESTS = :unit_tests
38
+ SUCCESS = :success
39
+ ERROR = :error
40
+ end
41
+
42
+
43
+ # Start a new deployment process based on the given Deliverfile
44
+ # @param (String) path The path to the Deliverfile.
45
+ # @param (Hash) hash You can pass a hash instead of a path to basically
46
+ # give all the information required (see {Deliverer::ValKey} for available options)
47
+ # @param (Bool) force Runs a deployment without verifying any information. This can be
48
+ # used for build servers. If this is set to false a PDF summary will be generated and opened
49
+ def initialize(path = nil, hash: nil, force: false)
50
+ @deliver_process = DeliverProcess.new
51
+ @deliver_process.deploy_information[ValKey::SKIP_PDF] = true if force
52
+
53
+ if hash
54
+ hash.each do |key, value|
55
+ # we still call this interface to verify the inputs correctly
56
+ set_new_value(key, value)
57
+ end
58
+
59
+ finished_executing_deliver_file
60
+ else
61
+ @deliver_file = Deliver::Deliverfile::Deliverfile.new(self, path)
62
+ end
63
+
64
+ # Do not put code here...
65
+ end
66
+
67
+ # This method is internally called from the Deliverfile DSL
68
+ # to set a value for a given key. This method will also verify if
69
+ # the key is valid.
70
+ def set_new_value(key, value)
71
+ unless self.class.all_available_keys_to_set.include?key
72
+ raise "Invalid key '#{key}', must be contained in Deliverer::ValKey.".red
73
+ end
74
+
75
+ if @deliver_process.deploy_information[key]
76
+ Helper.log.warn("You already set a value for key '#{key}'. Overwriting value '#{value}' with new value.")
77
+ end
78
+
79
+ @deliver_process.deploy_information[key] = value
80
+ end
81
+
82
+ # Sets a new block for a specific key
83
+ def set_new_block(key, block)
84
+ @deliver_process.deploy_information[:blocks][key] = block
85
+ end
86
+
87
+ # An array of all available options to be set a deployment_information.
88
+ #
89
+ # Is used to verify user inputs
90
+ # @return (Hash) The array of symbols
91
+ def self.all_available_keys_to_set
92
+ Deliverer::ValKey.constants.collect { |a| Deliverer::ValKey.const_get(a) }
93
+ end
94
+
95
+ # An array of all available blocks to be set for a deployment
96
+ #
97
+ # Is used to verify user inputs
98
+ # @return (Hash) The array of symbols
99
+ def self.all_available_blocks_to_set
100
+ Deliverer::AllBlocks.constants.collect { |a| Deliverer::AllBlocks.const_get(a) }
101
+ end
102
+
103
+ # This method will take care of the actual deployment process, after we
104
+ # received all information from the Deliverfile.
105
+ #
106
+ # This method will be called from the {Deliver::Deliverfile} after
107
+ # it is finished executing the Ruby script.
108
+ def finished_executing_deliver_file
109
+ deliver_process.run
110
+ end
111
+ end
112
+ end