fastlane 1.111.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (558) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +76 -111
  3. data/bin/bin-proxy +19 -0
  4. data/cert/README.md +163 -0
  5. data/cert/lib/cert.rb +18 -0
  6. data/cert/lib/cert/commands_generator.rb +51 -0
  7. data/cert/lib/cert/options.rb +67 -0
  8. data/cert/lib/cert/runner.rb +181 -0
  9. data/credentials_manager/README.md +62 -0
  10. data/credentials_manager/lib/credentials_manager.rb +12 -0
  11. data/credentials_manager/lib/credentials_manager/account_manager.rb +104 -0
  12. data/credentials_manager/lib/credentials_manager/appfile_config.rb +186 -0
  13. data/credentials_manager/lib/credentials_manager/cli.rb +65 -0
  14. data/deliver/README.md +271 -0
  15. data/deliver/lib/assets/DeliverfileDefault +10 -0
  16. data/deliver/lib/assets/ScreenshotsHelp +7 -0
  17. data/deliver/lib/assets/summary.html.erb +210 -0
  18. data/deliver/lib/deliver.rb +31 -0
  19. data/deliver/lib/deliver/app_screenshot.rb +226 -0
  20. data/deliver/lib/deliver/commands_generator.rb +150 -0
  21. data/deliver/lib/deliver/detect_values.rb +69 -0
  22. data/deliver/lib/deliver/download_screenshots.rb +46 -0
  23. data/deliver/lib/deliver/generate_summary.rb +9 -0
  24. data/deliver/lib/deliver/html_generator.rb +58 -0
  25. data/deliver/lib/deliver/loader.rb +18 -0
  26. data/deliver/lib/deliver/options.rb +269 -0
  27. data/deliver/lib/deliver/runner.rb +99 -0
  28. data/deliver/lib/deliver/setup.rb +78 -0
  29. data/deliver/lib/deliver/submit_for_review.rb +87 -0
  30. data/deliver/lib/deliver/upload_assets.rb +22 -0
  31. data/deliver/lib/deliver/upload_metadata.rb +191 -0
  32. data/deliver/lib/deliver/upload_price_tier.rb +21 -0
  33. data/deliver/lib/deliver/upload_screenshots.rb +110 -0
  34. data/fastlane/README.md +193 -0
  35. data/{lib → fastlane/lib}/assets/Actions.md.erb +0 -0
  36. data/{lib → fastlane/lib}/assets/AppfileTemplate +0 -0
  37. data/{lib → fastlane/lib}/assets/AppfileTemplateAndroid +0 -0
  38. data/{lib → fastlane/lib}/assets/AvailablePlugins.md.erb +0 -0
  39. data/{lib → fastlane/lib}/assets/DefaultFastfileTemplate +2 -2
  40. data/{lib → fastlane/lib}/assets/FastfileTemplateAndroid +2 -2
  41. data/{lib → fastlane/lib}/assets/completions/completion.bash +0 -0
  42. data/{lib → fastlane/lib}/assets/completions/completion.sh +0 -0
  43. data/{lib → fastlane/lib}/assets/completions/completion.zsh +0 -0
  44. data/{lib → fastlane/lib}/assets/custom_action_template.rb +0 -0
  45. data/{lib → fastlane/lib}/assets/mailgun_html_template.erb +0 -0
  46. data/{lib → fastlane/lib}/assets/report_template.xml.erb +0 -0
  47. data/{lib → fastlane/lib}/assets/s3_html_template.erb +0 -0
  48. data/{lib → fastlane/lib}/assets/s3_plist_template.erb +0 -0
  49. data/{lib → fastlane/lib}/assets/s3_version_template.erb +0 -0
  50. data/{lib → fastlane/lib}/fastlane.rb +3 -3
  51. data/{lib → fastlane/lib}/fastlane/action.rb +0 -0
  52. data/{lib → fastlane/lib}/fastlane/action_collector.rb +0 -0
  53. data/{lib → fastlane/lib}/fastlane/actions/README.md +0 -0
  54. data/{lib → fastlane/lib}/fastlane/actions/actions_helper.rb +16 -0
  55. data/{lib → fastlane/lib}/fastlane/actions/adb.rb +0 -0
  56. data/{lib → fastlane/lib}/fastlane/actions/adb_devices.rb +0 -0
  57. data/{lib → fastlane/lib}/fastlane/actions/add_git_tag.rb +0 -0
  58. data/{lib → fastlane/lib}/fastlane/actions/app_store_build_number.rb +0 -0
  59. data/{lib → fastlane/lib}/fastlane/actions/appaloosa.rb +1 -0
  60. data/{lib → fastlane/lib}/fastlane/actions/appetize.rb +1 -0
  61. data/{lib → fastlane/lib}/fastlane/actions/appetize_viewing_url_generator.rb +1 -0
  62. data/{lib → fastlane/lib}/fastlane/actions/appium.rb +0 -0
  63. data/{lib → fastlane/lib}/fastlane/actions/appledoc.rb +0 -0
  64. data/{lib → fastlane/lib}/fastlane/actions/appstore.rb +0 -0
  65. data/{lib → fastlane/lib}/fastlane/actions/apteligent.rb +1 -0
  66. data/{lib → fastlane/lib}/fastlane/actions/artifactory.rb +2 -0
  67. data/{lib → fastlane/lib}/fastlane/actions/backup_file.rb +0 -0
  68. data/{lib → fastlane/lib}/fastlane/actions/backup_xcarchive.rb +0 -0
  69. data/{lib → fastlane/lib}/fastlane/actions/badge.rb +0 -0
  70. data/{lib → fastlane/lib}/fastlane/actions/build_and_upload_to_appetize.rb +1 -0
  71. data/{lib → fastlane/lib}/fastlane/actions/bundle_install.rb +0 -0
  72. data/{lib → fastlane/lib}/fastlane/actions/carthage.rb +1 -1
  73. data/{lib → fastlane/lib}/fastlane/actions/cert.rb +0 -4
  74. data/{lib → fastlane/lib}/fastlane/actions/changelog_from_git_commits.rb +0 -0
  75. data/{lib → fastlane/lib}/fastlane/actions/chatwork.rb +1 -0
  76. data/{lib → fastlane/lib}/fastlane/actions/clean_build_artifacts.rb +0 -0
  77. data/{lib → fastlane/lib}/fastlane/actions/clean_cocoapods_cache.rb +0 -0
  78. data/{lib → fastlane/lib}/fastlane/actions/clear_derived_data.rb +0 -0
  79. data/{lib → fastlane/lib}/fastlane/actions/clipboard.rb +0 -0
  80. data/{lib → fastlane/lib}/fastlane/actions/cloc.rb +0 -0
  81. data/{lib → fastlane/lib}/fastlane/actions/cocoapods.rb +0 -0
  82. data/{lib → fastlane/lib}/fastlane/actions/commit_version_bump.rb +0 -0
  83. data/{lib → fastlane/lib}/fastlane/actions/copy_artifacts.rb +0 -0
  84. data/{lib → fastlane/lib}/fastlane/actions/crashlytics.rb +2 -0
  85. data/{lib → fastlane/lib}/fastlane/actions/create_keychain.rb +1 -0
  86. data/{lib → fastlane/lib}/fastlane/actions/create_pull_request.rb +1 -0
  87. data/{lib → fastlane/lib}/fastlane/actions/danger.rb +1 -0
  88. data/{lib → fastlane/lib}/fastlane/actions/debug.rb +0 -0
  89. data/{lib → fastlane/lib}/fastlane/actions/default_platform.rb +0 -0
  90. data/{lib → fastlane/lib}/fastlane/actions/delete_keychain.rb +0 -0
  91. data/{lib → fastlane/lib}/fastlane/actions/deliver.rb +0 -4
  92. data/{lib → fastlane/lib}/fastlane/actions/deploygate.rb +34 -19
  93. data/{lib → fastlane/lib}/fastlane/actions/device_grid/README.md +0 -0
  94. data/{lib → fastlane/lib}/fastlane/actions/dotgpg_environment.rb +0 -0
  95. data/{lib → fastlane/lib}/fastlane/actions/download.rb +0 -0
  96. data/{lib → fastlane/lib}/fastlane/actions/download_dsyms.rb +0 -0
  97. data/{lib → fastlane/lib}/fastlane/actions/dsym_zip.rb +0 -0
  98. data/{lib → fastlane/lib}/fastlane/actions/ensure_git_branch.rb +0 -0
  99. data/{lib → fastlane/lib}/fastlane/actions/ensure_git_status_clean.rb +0 -0
  100. data/{lib → fastlane/lib}/fastlane/actions/ensure_no_debug_code.rb +10 -2
  101. data/{lib → fastlane/lib}/fastlane/actions/ensure_xcode_version.rb +0 -0
  102. data/{lib → fastlane/lib}/fastlane/actions/erb.rb +0 -0
  103. data/{lib → fastlane/lib}/fastlane/actions/fastlane_version.rb +0 -0
  104. data/{lib → fastlane/lib}/fastlane/actions/flock.rb +1 -0
  105. data/{lib → fastlane/lib}/fastlane/actions/frameit.rb +6 -10
  106. data/{lib → fastlane/lib}/fastlane/actions/gcovr.rb +0 -0
  107. data/{lib → fastlane/lib}/fastlane/actions/get_build_number.rb +0 -0
  108. data/{lib → fastlane/lib}/fastlane/actions/get_build_number_repository.rb +0 -0
  109. data/{lib → fastlane/lib}/fastlane/actions/get_github_release.rb +1 -0
  110. data/{lib → fastlane/lib}/fastlane/actions/get_info_plist_value.rb +0 -0
  111. data/{lib → fastlane/lib}/fastlane/actions/get_ipa_info_plist_value.rb +0 -0
  112. data/{lib → fastlane/lib}/fastlane/actions/get_version_number.rb +0 -0
  113. data/{lib → fastlane/lib}/fastlane/actions/git_add.rb +0 -0
  114. data/{lib → fastlane/lib}/fastlane/actions/git_branch.rb +0 -0
  115. data/{lib → fastlane/lib}/fastlane/actions/git_commit.rb +0 -0
  116. data/{lib → fastlane/lib}/fastlane/actions/git_pull.rb +0 -0
  117. data/{lib → fastlane/lib}/fastlane/actions/git_tag_exists.rb +0 -0
  118. data/{lib → fastlane/lib}/fastlane/actions/gradle.rb +0 -0
  119. data/fastlane/lib/fastlane/actions/gym.rb +84 -0
  120. data/{lib → fastlane/lib}/fastlane/actions/hg_add_tag.rb +0 -0
  121. data/{lib → fastlane/lib}/fastlane/actions/hg_commit_version_bump.rb +0 -0
  122. data/{lib → fastlane/lib}/fastlane/actions/hg_ensure_clean_status.rb +0 -0
  123. data/{lib → fastlane/lib}/fastlane/actions/hg_push.rb +0 -0
  124. data/{lib → fastlane/lib}/fastlane/actions/hipchat.rb +1 -0
  125. data/{lib → fastlane/lib}/fastlane/actions/hockey.rb +37 -11
  126. data/{lib → fastlane/lib}/fastlane/actions/ifttt.rb +1 -0
  127. data/{lib → fastlane/lib}/fastlane/actions/import.rb +0 -0
  128. data/{lib → fastlane/lib}/fastlane/actions/import_certificate.rb +2 -0
  129. data/{lib → fastlane/lib}/fastlane/actions/import_from_git.rb +0 -0
  130. data/{lib → fastlane/lib}/fastlane/actions/increment_build_number.rb +0 -0
  131. data/{lib → fastlane/lib}/fastlane/actions/increment_version_number.rb +0 -0
  132. data/{lib → fastlane/lib}/fastlane/actions/install_on_device.rb +0 -0
  133. data/{lib → fastlane/lib}/fastlane/actions/install_xcode_plugin.rb +0 -0
  134. data/{lib → fastlane/lib}/fastlane/actions/installr.rb +1 -0
  135. data/{lib → fastlane/lib}/fastlane/actions/ipa.rb +12 -4
  136. data/{lib → fastlane/lib}/fastlane/actions/is_ci.rb +0 -0
  137. data/{lib → fastlane/lib}/fastlane/actions/jazzy.rb +0 -0
  138. data/{lib → fastlane/lib}/fastlane/actions/jira.rb +1 -0
  139. data/{lib → fastlane/lib}/fastlane/actions/lane_context.rb +0 -0
  140. data/{lib → fastlane/lib}/fastlane/actions/last_git_commit.rb +0 -0
  141. data/{lib → fastlane/lib}/fastlane/actions/last_git_tag.rb +0 -0
  142. data/{lib → fastlane/lib}/fastlane/actions/latest_testflight_build_number.rb +0 -0
  143. data/{lib → fastlane/lib}/fastlane/actions/lcov.rb +0 -0
  144. data/{lib → fastlane/lib}/fastlane/actions/mailgun.rb +2 -0
  145. data/{lib → fastlane/lib}/fastlane/actions/make_changelog_from_jenkins.rb +0 -0
  146. data/{lib → fastlane/lib}/fastlane/actions/match.rb +3 -9
  147. data/{lib → fastlane/lib}/fastlane/actions/nexus_upload.rb +1 -0
  148. data/{lib → fastlane/lib}/fastlane/actions/notification.rb +0 -0
  149. data/{lib → fastlane/lib}/fastlane/actions/notify.rb +0 -0
  150. data/{lib → fastlane/lib}/fastlane/actions/number_of_commits.rb +0 -0
  151. data/{lib → fastlane/lib}/fastlane/actions/oclint.rb +0 -0
  152. data/{lib → fastlane/lib}/fastlane/actions/onesignal.rb +3 -0
  153. data/{lib → fastlane/lib}/fastlane/actions/opt_out_usage.rb +0 -0
  154. data/{lib → fastlane/lib}/fastlane/actions/pem.rb +9 -15
  155. data/{lib → fastlane/lib}/fastlane/actions/pilot.rb +6 -12
  156. data/{lib → fastlane/lib}/fastlane/actions/pod_lib_lint.rb +0 -0
  157. data/{lib → fastlane/lib}/fastlane/actions/pod_push.rb +0 -0
  158. data/{lib → fastlane/lib}/fastlane/actions/podio_item.rb +2 -0
  159. data/{lib → fastlane/lib}/fastlane/actions/produce.rb +7 -11
  160. data/{lib → fastlane/lib}/fastlane/actions/prompt.rb +5 -2
  161. data/{lib → fastlane/lib}/fastlane/actions/push_git_tags.rb +0 -0
  162. data/{lib → fastlane/lib}/fastlane/actions/push_to_git_remote.rb +0 -0
  163. data/{lib → fastlane/lib}/fastlane/actions/puts.rb +8 -0
  164. data/{lib → fastlane/lib}/fastlane/actions/read_podspec.rb +0 -0
  165. data/{lib → fastlane/lib}/fastlane/actions/recreate_schemes.rb +0 -0
  166. data/{lib → fastlane/lib}/fastlane/actions/register_devices.rb +0 -0
  167. data/{lib → fastlane/lib}/fastlane/actions/reset_git_repo.rb +0 -0
  168. data/fastlane/lib/fastlane/actions/reset_simulator_contents.rb +62 -0
  169. data/{lib → fastlane/lib}/fastlane/actions/resign.rb +0 -0
  170. data/{lib → fastlane/lib}/fastlane/actions/restore_file.rb +0 -0
  171. data/{lib → fastlane/lib}/fastlane/actions/rocket.rb +0 -0
  172. data/{lib → fastlane/lib}/fastlane/actions/rsync.rb +0 -0
  173. data/{lib → fastlane/lib}/fastlane/actions/s3.rb +2 -1
  174. data/{lib → fastlane/lib}/fastlane/actions/say.rb +0 -0
  175. data/{lib → fastlane/lib}/fastlane/actions/scan.rb +0 -4
  176. data/{lib → fastlane/lib}/fastlane/actions/scp.rb +1 -0
  177. data/{lib → fastlane/lib}/fastlane/actions/screengrab.rb +7 -13
  178. data/{lib → fastlane/lib}/fastlane/actions/set_build_number_repository.rb +0 -0
  179. data/{lib → fastlane/lib}/fastlane/actions/set_changelog.rb +0 -0
  180. data/{lib → fastlane/lib}/fastlane/actions/set_github_release.rb +1 -0
  181. data/{lib → fastlane/lib}/fastlane/actions/set_info_plist_value.rb +0 -0
  182. data/{lib → fastlane/lib}/fastlane/actions/set_pod_key.rb +0 -0
  183. data/{lib → fastlane/lib}/fastlane/actions/setup_jenkins.rb +0 -0
  184. data/{lib → fastlane/lib}/fastlane/actions/sigh.rb +9 -15
  185. data/{lib → fastlane/lib}/fastlane/actions/skip_docs.rb +0 -0
  186. data/{lib → fastlane/lib}/fastlane/actions/slack.rb +1 -0
  187. data/{lib → fastlane/lib}/fastlane/actions/slather.rb +0 -0
  188. data/{lib → fastlane/lib}/fastlane/actions/snapshot.rb +5 -11
  189. data/{lib → fastlane/lib}/fastlane/actions/sonar.rb +0 -0
  190. data/{lib → fastlane/lib}/fastlane/actions/splunkmint.rb +3 -0
  191. data/{lib → fastlane/lib}/fastlane/actions/ssh.rb +1 -0
  192. data/{lib → fastlane/lib}/fastlane/actions/supply.rb +9 -13
  193. data/{lib → fastlane/lib}/fastlane/actions/swiftlint.rb +0 -0
  194. data/{lib → fastlane/lib}/fastlane/actions/team_id.rb +0 -0
  195. data/{lib → fastlane/lib}/fastlane/actions/team_name.rb +0 -0
  196. data/{lib → fastlane/lib}/fastlane/actions/testfairy.rb +28 -9
  197. data/{lib → fastlane/lib}/fastlane/actions/testflight.rb +0 -0
  198. data/{lib → fastlane/lib}/fastlane/actions/tryouts.rb +1 -0
  199. data/{lib → fastlane/lib}/fastlane/actions/twitter.rb +4 -0
  200. data/{lib → fastlane/lib}/fastlane/actions/typetalk.rb +0 -0
  201. data/{lib → fastlane/lib}/fastlane/actions/unlock_keychain.rb +1 -0
  202. data/{lib → fastlane/lib}/fastlane/actions/update_app_group_identifiers.rb +0 -0
  203. data/{lib → fastlane/lib}/fastlane/actions/update_app_identifier.rb +0 -0
  204. data/{lib → fastlane/lib}/fastlane/actions/update_fastlane.rb +1 -20
  205. data/{lib → fastlane/lib}/fastlane/actions/update_icloud_container_identifiers.rb +0 -0
  206. data/{lib → fastlane/lib}/fastlane/actions/update_info_plist.rb +0 -0
  207. data/{lib → fastlane/lib}/fastlane/actions/update_project_code_signing.rb +0 -0
  208. data/{lib → fastlane/lib}/fastlane/actions/update_project_provisioning.rb +0 -0
  209. data/{lib → fastlane/lib}/fastlane/actions/update_project_team.rb +0 -0
  210. data/{lib → fastlane/lib}/fastlane/actions/update_urban_airship_configuration.rb +4 -0
  211. data/{lib → fastlane/lib}/fastlane/actions/update_url_schemes.rb +0 -0
  212. data/{lib → fastlane/lib}/fastlane/actions/upload_symbols_to_crashlytics.rb +1 -0
  213. data/{lib → fastlane/lib}/fastlane/actions/upload_symbols_to_sentry.rb +2 -0
  214. data/{lib → fastlane/lib}/fastlane/actions/verify_build.rb +0 -0
  215. data/{lib → fastlane/lib}/fastlane/actions/verify_pod_keys.rb +0 -0
  216. data/{lib → fastlane/lib}/fastlane/actions/verify_xcode.rb +0 -0
  217. data/{lib → fastlane/lib}/fastlane/actions/version_bump_podspec.rb +0 -0
  218. data/{lib → fastlane/lib}/fastlane/actions/version_get_podspec.rb +0 -0
  219. data/{lib → fastlane/lib}/fastlane/actions/xcode_install.rb +0 -0
  220. data/{lib → fastlane/lib}/fastlane/actions/xcode_select.rb +0 -0
  221. data/{lib → fastlane/lib}/fastlane/actions/xcode_server_get_assets.rb +1 -0
  222. data/{lib → fastlane/lib}/fastlane/actions/xcodebuild.rb +0 -0
  223. data/{lib → fastlane/lib}/fastlane/actions/xcov.rb +0 -0
  224. data/{lib → fastlane/lib}/fastlane/actions/xctool.rb +1 -1
  225. data/{lib → fastlane/lib}/fastlane/actions/xcversion.rb +0 -0
  226. data/{lib → fastlane/lib}/fastlane/actions/zip.rb +0 -0
  227. data/{lib → fastlane/lib}/fastlane/auto_complete.rb +0 -0
  228. data/fastlane/lib/fastlane/cli_tools_distributor.rb +125 -0
  229. data/{lib → fastlane/lib}/fastlane/command_line_handler.rb +0 -0
  230. data/{lib → fastlane/lib}/fastlane/commands_generator.rb +5 -4
  231. data/{lib → fastlane/lib}/fastlane/configuration_helper.rb +0 -1
  232. data/{lib → fastlane/lib}/fastlane/core_ext/bundler_monkey_patch.rb +0 -0
  233. data/{lib → fastlane/lib}/fastlane/documentation/actions_list.rb +1 -1
  234. data/{lib → fastlane/lib}/fastlane/documentation/docs_generator.rb +1 -1
  235. data/{lib → fastlane/lib}/fastlane/documentation/markdown_docs_generator.rb +0 -0
  236. data/{lib → fastlane/lib}/fastlane/environment_printer.rb +1 -1
  237. data/{lib → fastlane/lib}/fastlane/erb_template_helper.rb +0 -0
  238. data/{lib → fastlane/lib}/fastlane/fast_file.rb +1 -1
  239. data/{lib → fastlane/lib}/fastlane/fastlane_require.rb +27 -3
  240. data/{lib → fastlane/lib}/fastlane/features.rb +0 -0
  241. data/{lib → fastlane/lib}/fastlane/helper/README.md +0 -0
  242. data/{lib → fastlane/lib}/fastlane/helper/adb_helper.rb +0 -0
  243. data/{lib → fastlane/lib}/fastlane/helper/cocoapod_helper.rb +0 -0
  244. data/{lib → fastlane/lib}/fastlane/helper/crashlytics_helper.rb +0 -0
  245. data/{lib → fastlane/lib}/fastlane/helper/gem_helper.rb +0 -0
  246. data/{lib → fastlane/lib}/fastlane/helper/git_helper.rb +0 -0
  247. data/{lib → fastlane/lib}/fastlane/helper/gradle_helper.rb +0 -0
  248. data/{lib → fastlane/lib}/fastlane/helper/podspec_helper.rb +0 -0
  249. data/{lib → fastlane/lib}/fastlane/helper/sh_helper.rb +0 -0
  250. data/{lib → fastlane/lib}/fastlane/helper/xcversion_helper.rb +0 -0
  251. data/{lib → fastlane/lib}/fastlane/junit_generator.rb +1 -1
  252. data/{lib → fastlane/lib}/fastlane/lane.rb +0 -0
  253. data/{lib → fastlane/lib}/fastlane/lane_list.rb +0 -0
  254. data/{lib → fastlane/lib}/fastlane/lane_manager.rb +25 -6
  255. data/{lib → fastlane/lib}/fastlane/markdown_table_formatter.rb +0 -0
  256. data/{lib → fastlane/lib}/fastlane/new_action.rb +1 -1
  257. data/{lib → fastlane/lib}/fastlane/one_off.rb +0 -0
  258. data/{lib → fastlane/lib}/fastlane/other_action.rb +0 -0
  259. data/{lib → fastlane/lib}/fastlane/plugins/plugin_fetcher.rb +0 -0
  260. data/{lib → fastlane/lib}/fastlane/plugins/plugin_generator.rb +0 -0
  261. data/{lib → fastlane/lib}/fastlane/plugins/plugin_generator_ui.rb +0 -0
  262. data/{lib → fastlane/lib}/fastlane/plugins/plugin_info.rb +0 -0
  263. data/{lib → fastlane/lib}/fastlane/plugins/plugin_info_collector.rb +0 -0
  264. data/{lib → fastlane/lib}/fastlane/plugins/plugin_manager.rb +4 -4
  265. data/{lib → fastlane/lib}/fastlane/plugins/plugin_search.rb +0 -0
  266. data/{lib → fastlane/lib}/fastlane/plugins/plugin_update_manager.rb +0 -0
  267. data/{lib → fastlane/lib}/fastlane/plugins/plugins.rb +0 -0
  268. data/{lib → fastlane/lib}/fastlane/plugins/template/%gem_name%.gemspec.erb +3 -0
  269. data/{lib → fastlane/lib}/fastlane/plugins/template/.gitignore +0 -0
  270. data/{lib → fastlane/lib}/fastlane/plugins/template/.rspec +0 -0
  271. data/{lib → fastlane/lib}/fastlane/plugins/template/.rubocop.yml +0 -0
  272. data/{lib → fastlane/lib}/fastlane/plugins/template/.travis.yml +0 -0
  273. data/{lib → fastlane/lib}/fastlane/plugins/template/Gemfile +0 -0
  274. data/{lib → fastlane/lib}/fastlane/plugins/template/LICENSE.erb +0 -0
  275. data/{lib → fastlane/lib}/fastlane/plugins/template/README.md.erb +2 -2
  276. data/{lib → fastlane/lib}/fastlane/plugins/template/Rakefile +0 -0
  277. data/{lib → fastlane/lib}/fastlane/plugins/template/circle.yml +0 -0
  278. data/{lib → fastlane/lib}/fastlane/plugins/template/fastlane/Fastfile.erb +0 -0
  279. data/{lib → fastlane/lib}/fastlane/plugins/template/fastlane/Pluginfile.erb +0 -0
  280. data/{lib → fastlane/lib}/fastlane/plugins/template/lib/fastlane/plugin/%plugin_name%.rb.erb +0 -0
  281. data/{lib → fastlane/lib}/fastlane/plugins/template/lib/fastlane/plugin/%plugin_name%/actions/%plugin_name%_action.rb.erb +0 -0
  282. data/{lib → fastlane/lib}/fastlane/plugins/template/lib/fastlane/plugin/%plugin_name%/helper/%plugin_name%_helper.rb.erb +0 -0
  283. data/{lib → fastlane/lib}/fastlane/plugins/template/lib/fastlane/plugin/%plugin_name%/version.rb.erb +0 -0
  284. data/{lib → fastlane/lib}/fastlane/plugins/template/spec/%plugin_name%_action_spec.rb.erb +0 -0
  285. data/{lib → fastlane/lib}/fastlane/plugins/template/spec/spec_helper.rb.erb +0 -0
  286. data/{lib → fastlane/lib}/fastlane/runner.rb +25 -2
  287. data/{lib → fastlane/lib}/fastlane/setup/crashlytics_beta.rb +1 -1
  288. data/{lib → fastlane/lib}/fastlane/setup/crashlytics_beta_command_line_handler.rb +0 -0
  289. data/{lib → fastlane/lib}/fastlane/setup/crashlytics_beta_info.rb +0 -0
  290. data/{lib → fastlane/lib}/fastlane/setup/crashlytics_beta_info_collector.rb +0 -0
  291. data/{lib → fastlane/lib}/fastlane/setup/crashlytics_beta_ui.rb +0 -0
  292. data/{lib → fastlane/lib}/fastlane/setup/crashlytics_beta_user_email_fetcher.rb +0 -0
  293. data/{lib → fastlane/lib}/fastlane/setup/crashlytics_project_parser.rb +0 -0
  294. data/{lib → fastlane/lib}/fastlane/setup/setup.rb +2 -2
  295. data/{lib → fastlane/lib}/fastlane/setup/setup_android.rb +2 -2
  296. data/{lib → fastlane/lib}/fastlane/setup/setup_ios.rb +3 -3
  297. data/{lib → fastlane/lib}/fastlane/supported_platforms.rb +0 -0
  298. data/{lib → fastlane/lib}/fastlane/tools.rb +0 -0
  299. data/{lib → fastlane/lib}/fastlane/version.rb +2 -2
  300. data/fastlane_core/README.md +54 -0
  301. data/fastlane_core/lib/assets/XMLTemplate.xml.erb +12 -0
  302. data/fastlane_core/lib/fastlane_core.rb +48 -0
  303. data/fastlane_core/lib/fastlane_core/cert_checker.rb +94 -0
  304. data/fastlane_core/lib/fastlane_core/command_executor.rb +98 -0
  305. data/fastlane_core/lib/fastlane_core/configuration/commander_generator.rb +82 -0
  306. data/fastlane_core/lib/fastlane_core/configuration/config_item.rb +133 -0
  307. data/fastlane_core/lib/fastlane_core/configuration/configuration.rb +266 -0
  308. data/fastlane_core/lib/fastlane_core/configuration/configuration_file.rb +82 -0
  309. data/fastlane_core/lib/fastlane_core/core_ext/string.rb +17 -0
  310. data/fastlane_core/lib/fastlane_core/device_manager.rb +231 -0
  311. data/fastlane_core/lib/fastlane_core/env.rb +9 -0
  312. data/{lib/fastlane → fastlane_core/lib/fastlane_core}/fastlane_folder.rb +1 -11
  313. data/fastlane_core/lib/fastlane_core/feature/feature.rb +49 -0
  314. data/fastlane_core/lib/fastlane_core/features.rb +2 -0
  315. data/fastlane_core/lib/fastlane_core/helper.rb +240 -0
  316. data/fastlane_core/lib/fastlane_core/ipa_file_analyser.rb +55 -0
  317. data/fastlane_core/lib/fastlane_core/ipa_upload_package_builder.rb +44 -0
  318. data/fastlane_core/lib/fastlane_core/itunes_search_api.rb +48 -0
  319. data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +409 -0
  320. data/fastlane_core/lib/fastlane_core/keychain_importer.rb +27 -0
  321. data/fastlane_core/lib/fastlane_core/languages.rb +11 -0
  322. data/fastlane_core/lib/fastlane_core/pkg_file_analyser.rb +42 -0
  323. data/fastlane_core/lib/fastlane_core/pkg_upload_package_builder.rb +44 -0
  324. data/fastlane_core/lib/fastlane_core/print_table.rb +63 -0
  325. data/fastlane_core/lib/fastlane_core/project.rb +450 -0
  326. data/fastlane_core/lib/fastlane_core/provisioning_profile.rb +69 -0
  327. data/fastlane_core/lib/fastlane_core/string_filters.rb +34 -0
  328. data/fastlane_core/lib/fastlane_core/tool_collector.rb +179 -0
  329. data/fastlane_core/lib/fastlane_core/ui/disable_colors.rb +17 -0
  330. data/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb +190 -0
  331. data/fastlane_core/lib/fastlane_core/ui/github_issue_inspector_reporter.rb +50 -0
  332. data/fastlane_core/lib/fastlane_core/ui/implementations/shell.rb +122 -0
  333. data/fastlane_core/lib/fastlane_core/ui/interface.rb +159 -0
  334. data/fastlane_core/lib/fastlane_core/ui/ui.rb +26 -0
  335. data/fastlane_core/lib/fastlane_core/update_checker/changelog.rb +37 -0
  336. data/fastlane_core/lib/fastlane_core/update_checker/update_checker.rb +198 -0
  337. data/fastlane_core/lib/fastlane_core/xcodebuild_list_output_parser.rb +28 -0
  338. data/frameit/README.md +284 -0
  339. data/frameit/lib/assets/empty.png +0 -0
  340. data/frameit/lib/frameit.rb +52 -0
  341. data/frameit/lib/frameit/commands_generator.rb +99 -0
  342. data/frameit/lib/frameit/config_parser.rb +98 -0
  343. data/frameit/lib/frameit/dependency_checker.rb +20 -0
  344. data/frameit/lib/frameit/device_types.rb +13 -0
  345. data/frameit/lib/frameit/editor.rb +351 -0
  346. data/frameit/lib/frameit/frame_downloader.rb +71 -0
  347. data/frameit/lib/frameit/mac_editor.rb +32 -0
  348. data/frameit/lib/frameit/offsets.rb +19 -0
  349. data/frameit/lib/frameit/options.rb +46 -0
  350. data/frameit/lib/frameit/runner.rb +45 -0
  351. data/frameit/lib/frameit/screenshot.rb +89 -0
  352. data/frameit/lib/frameit/strings_parser.rb +35 -0
  353. data/frameit/lib/frameit/template_finder.rb +36 -0
  354. data/gym/README.md +288 -0
  355. data/gym/lib/assets/GymfileTemplate +13 -0
  356. data/gym/lib/assets/package_application_patches/0001_codesign_args_patch.diff +38 -0
  357. data/gym/lib/assets/package_application_patches/0002_no_strict_parameter_patch.diff +42 -0
  358. data/gym/lib/assets/package_application_patches/PackageApplication_MD5 +2 -0
  359. data/gym/lib/assets/wrap_xcodebuild/xcbuild-safe.sh +58 -0
  360. data/gym/lib/gym.rb +49 -0
  361. data/gym/lib/gym/commands_generator.rb +62 -0
  362. data/gym/lib/gym/detect_values.rb +105 -0
  363. data/gym/lib/gym/error_handler.rb +186 -0
  364. data/gym/lib/gym/generators/README.md +1 -0
  365. data/gym/lib/gym/generators/build_command_generator.rb +136 -0
  366. data/gym/lib/gym/generators/package_command_generator.rb +58 -0
  367. data/gym/lib/gym/generators/package_command_generator_legacy.rb +102 -0
  368. data/gym/lib/gym/generators/package_command_generator_xcode7.rb +191 -0
  369. data/gym/lib/gym/manager.rb +17 -0
  370. data/gym/lib/gym/options.rb +254 -0
  371. data/gym/lib/gym/runner.rb +256 -0
  372. data/gym/lib/gym/xcode.rb +21 -0
  373. data/gym/lib/gym/xcodebuild_fixes/README.md +9 -0
  374. data/gym/lib/gym/xcodebuild_fixes/generic_archive_fix.rb +32 -0
  375. data/gym/lib/gym/xcodebuild_fixes/package_application_fix.rb +53 -0
  376. data/gym/lib/gym/xcodebuild_fixes/swift_fix.rb +99 -0
  377. data/gym/lib/gym/xcodebuild_fixes/watchkit2_fix.rb +35 -0
  378. data/gym/lib/gym/xcodebuild_fixes/watchkit_fix.rb +40 -0
  379. data/match/README.md +414 -0
  380. data/match/lib/assets/MatchfileTemplate +9 -0
  381. data/match/lib/assets/READMETemplate.md +49 -0
  382. data/match/lib/match.rb +57 -0
  383. data/match/lib/match/change_password.rb +30 -0
  384. data/match/lib/match/commands_generator.rb +120 -0
  385. data/match/lib/match/encrypt.rb +93 -0
  386. data/match/lib/match/generator.rb +74 -0
  387. data/match/lib/match/git_helper.rb +139 -0
  388. data/match/lib/match/nuke.rb +190 -0
  389. data/match/lib/match/options.rb +124 -0
  390. data/match/lib/match/runner.rb +172 -0
  391. data/match/lib/match/setup.rb +20 -0
  392. data/match/lib/match/spaceship_ensure.rb +78 -0
  393. data/match/lib/match/table_printer.rb +43 -0
  394. data/match/lib/match/utils.rb +59 -0
  395. data/pem/README.md +175 -0
  396. data/pem/lib/pem.rb +21 -0
  397. data/pem/lib/pem/commands_generator.rb +41 -0
  398. data/pem/lib/pem/manager.rb +93 -0
  399. data/pem/lib/pem/options.rb +79 -0
  400. data/pilot/README.md +285 -0
  401. data/pilot/lib/pilot.rb +22 -0
  402. data/pilot/lib/pilot/build_manager.rb +209 -0
  403. data/pilot/lib/pilot/commands_generator.rb +136 -0
  404. data/pilot/lib/pilot/features.rb +0 -0
  405. data/pilot/lib/pilot/manager.rb +71 -0
  406. data/pilot/lib/pilot/options.rb +161 -0
  407. data/pilot/lib/pilot/tester_exporter.rb +37 -0
  408. data/pilot/lib/pilot/tester_importer.rb +51 -0
  409. data/pilot/lib/pilot/tester_manager.rb +212 -0
  410. data/pilot/lib/pilot/tester_util.rb +23 -0
  411. data/produce/README.md +232 -0
  412. data/produce/lib/produce.rb +21 -0
  413. data/produce/lib/produce/available_default_languages.rb +36 -0
  414. data/produce/lib/produce/commands_generator.rb +134 -0
  415. data/produce/lib/produce/developer_center.rb +58 -0
  416. data/produce/lib/produce/group.rb +89 -0
  417. data/produce/lib/produce/itunes_connect.rb +87 -0
  418. data/produce/lib/produce/manager.rb +11 -0
  419. data/produce/lib/produce/options.rb +114 -0
  420. data/produce/lib/produce/service.rb +227 -0
  421. data/scan/README.md +219 -0
  422. data/scan/lib/assets/ScanfileTemplate +13 -0
  423. data/scan/lib/scan.rb +40 -0
  424. data/scan/lib/scan/commands_generator.rb +61 -0
  425. data/scan/lib/scan/detect_values.rb +184 -0
  426. data/scan/lib/scan/error_handler.rb +43 -0
  427. data/scan/lib/scan/manager.rb +17 -0
  428. data/scan/lib/scan/options.rb +189 -0
  429. data/scan/lib/scan/report_collector.rb +70 -0
  430. data/scan/lib/scan/runner.rb +103 -0
  431. data/scan/lib/scan/slack_poster.rb +59 -0
  432. data/scan/lib/scan/test_command_generator.rb +130 -0
  433. data/scan/lib/scan/test_result_parser.rb +21 -0
  434. data/screengrab/README.md +190 -0
  435. data/screengrab/lib/assets/ScreengrabfileTemplate +15 -0
  436. data/screengrab/lib/screengrab.rb +32 -0
  437. data/screengrab/lib/screengrab/android_environment.rb +88 -0
  438. data/screengrab/lib/screengrab/commands_generator.rb +60 -0
  439. data/screengrab/lib/screengrab/dependency_checker.rb +56 -0
  440. data/screengrab/lib/screengrab/detect_values.rb +16 -0
  441. data/screengrab/lib/screengrab/options.rb +109 -0
  442. data/screengrab/lib/screengrab/page.html.erb +206 -0
  443. data/screengrab/lib/screengrab/runner.rb +336 -0
  444. data/screengrab/lib/screengrab/setup.rb +16 -0
  445. data/sigh/README.md +256 -0
  446. data/sigh/lib/assets/resign.sh +774 -0
  447. data/sigh/lib/sigh.rb +19 -0
  448. data/sigh/lib/sigh/commands_generator.rb +133 -0
  449. data/sigh/lib/sigh/download_all.rb +36 -0
  450. data/sigh/lib/sigh/local_manage.rb +140 -0
  451. data/sigh/lib/sigh/manager.rb +44 -0
  452. data/sigh/lib/sigh/options.rb +117 -0
  453. data/sigh/lib/sigh/repair.rb +30 -0
  454. data/sigh/lib/sigh/resign.rb +201 -0
  455. data/sigh/lib/sigh/runner.rb +235 -0
  456. data/snapshot/README.md +400 -0
  457. data/snapshot/lib/assets/SnapfileTemplate +36 -0
  458. data/snapshot/lib/assets/SnapshotHelper.swift +138 -0
  459. data/snapshot/lib/assets/SnapshotHelper2-3.swift +140 -0
  460. data/snapshot/lib/snapshot.rb +59 -0
  461. data/snapshot/lib/snapshot/collector.rb +92 -0
  462. data/snapshot/lib/snapshot/commands_generator.rb +108 -0
  463. data/snapshot/lib/snapshot/dependency_checker.rb +50 -0
  464. data/snapshot/lib/snapshot/detect_values.rb +53 -0
  465. data/snapshot/lib/snapshot/error_handler.rb +22 -0
  466. data/snapshot/lib/snapshot/fixes/README.md +5 -0
  467. data/snapshot/lib/snapshot/fixes/hardware_keyboard_fix.rb +14 -0
  468. data/snapshot/lib/snapshot/fixes/simulator_zoom_fix.rb +25 -0
  469. data/snapshot/lib/snapshot/latest_os_version.rb +31 -0
  470. data/snapshot/lib/snapshot/options.rb +161 -0
  471. data/snapshot/lib/snapshot/page.html.erb +206 -0
  472. data/snapshot/lib/snapshot/reports_generator.rb +64 -0
  473. data/snapshot/lib/snapshot/reset_simulators.rb +88 -0
  474. data/snapshot/lib/snapshot/runner.rb +294 -0
  475. data/snapshot/lib/snapshot/screenshot_flatten.rb +18 -0
  476. data/snapshot/lib/snapshot/screenshot_rotate.rb +38 -0
  477. data/snapshot/lib/snapshot/setup.rb +35 -0
  478. data/snapshot/lib/snapshot/test_command_generator.rb +118 -0
  479. data/snapshot/lib/snapshot/update.rb +29 -0
  480. data/spaceship/README.md +191 -0
  481. data/spaceship/lib/assets/languageMapping.json +240 -0
  482. data/spaceship/lib/assets/languageMappingReadable.json +30 -0
  483. data/spaceship/lib/spaceship.rb +31 -0
  484. data/spaceship/lib/spaceship/babosa_fix.rb +30 -0
  485. data/spaceship/lib/spaceship/base.rb +236 -0
  486. data/spaceship/lib/spaceship/client.rb +487 -0
  487. data/spaceship/lib/spaceship/commands_generator.rb +48 -0
  488. data/spaceship/lib/spaceship/du/du_client.rb +122 -0
  489. data/spaceship/lib/spaceship/du/upload_file.rb +56 -0
  490. data/spaceship/lib/spaceship/du/utilities.rb +81 -0
  491. data/spaceship/lib/spaceship/helper/net_http_generic_request.rb +14 -0
  492. data/spaceship/lib/spaceship/helper/plist_middleware.rb +15 -0
  493. data/spaceship/lib/spaceship/launcher.rb +94 -0
  494. data/spaceship/lib/spaceship/playground.rb +72 -0
  495. data/spaceship/lib/spaceship/portal/app.rb +148 -0
  496. data/spaceship/lib/spaceship/portal/app_group.rb +77 -0
  497. data/spaceship/lib/spaceship/portal/app_service.rb +278 -0
  498. data/spaceship/lib/spaceship/portal/certificate.rb +333 -0
  499. data/spaceship/lib/spaceship/portal/device.rb +192 -0
  500. data/spaceship/lib/spaceship/portal/portal.rb +8 -0
  501. data/spaceship/lib/spaceship/portal/portal_base.rb +13 -0
  502. data/spaceship/lib/spaceship/portal/portal_client.rb +491 -0
  503. data/spaceship/lib/spaceship/portal/provisioning_profile.rb +467 -0
  504. data/spaceship/lib/spaceship/portal/spaceship.rb +112 -0
  505. data/spaceship/lib/spaceship/portal/ui/select_team.rb +83 -0
  506. data/spaceship/lib/spaceship/spaceauth_runner.rb +50 -0
  507. data/spaceship/lib/spaceship/tunes/app_details.rb +139 -0
  508. data/spaceship/lib/spaceship/tunes/app_image.rb +55 -0
  509. data/spaceship/lib/spaceship/tunes/app_ratings.rb +107 -0
  510. data/spaceship/lib/spaceship/tunes/app_screenshot.rb +17 -0
  511. data/spaceship/lib/spaceship/tunes/app_status.rb +60 -0
  512. data/spaceship/lib/spaceship/tunes/app_submission.rb +136 -0
  513. data/spaceship/lib/spaceship/tunes/app_trailer.rb +68 -0
  514. data/spaceship/lib/spaceship/tunes/app_version.rb +766 -0
  515. data/spaceship/lib/spaceship/tunes/app_version_common.rb +33 -0
  516. data/spaceship/lib/spaceship/tunes/app_version_generated_promocodes.rb +35 -0
  517. data/spaceship/lib/spaceship/tunes/app_version_history.rb +59 -0
  518. data/spaceship/lib/spaceship/tunes/app_version_promocodes.rb +34 -0
  519. data/spaceship/lib/spaceship/tunes/app_version_ref.rb +19 -0
  520. data/spaceship/lib/spaceship/tunes/app_version_states_history.rb +34 -0
  521. data/spaceship/lib/spaceship/tunes/application.rb +437 -0
  522. data/spaceship/lib/spaceship/tunes/build.rb +269 -0
  523. data/spaceship/lib/spaceship/tunes/build_details.rb +48 -0
  524. data/spaceship/lib/spaceship/tunes/build_train.rb +182 -0
  525. data/spaceship/lib/spaceship/tunes/device_type.rb +14 -0
  526. data/spaceship/lib/spaceship/tunes/language_converter.rb +63 -0
  527. data/spaceship/lib/spaceship/tunes/language_item.rb +56 -0
  528. data/spaceship/lib/spaceship/tunes/pricing_tier.rb +81 -0
  529. data/spaceship/lib/spaceship/tunes/recovery_device.rb +69 -0
  530. data/spaceship/lib/spaceship/tunes/spaceship.rb +34 -0
  531. data/spaceship/lib/spaceship/tunes/tester.rb +283 -0
  532. data/spaceship/lib/spaceship/tunes/transit_app_file.rb +27 -0
  533. data/spaceship/lib/spaceship/tunes/tunes.rb +35 -0
  534. data/spaceship/lib/spaceship/tunes/tunes_base.rb +15 -0
  535. data/spaceship/lib/spaceship/tunes/tunes_client.rb +1068 -0
  536. data/spaceship/lib/spaceship/tunes/user_detail.rb +19 -0
  537. data/spaceship/lib/spaceship/tunes/version_set.rb +35 -0
  538. data/spaceship/lib/spaceship/two_step_client.rb +195 -0
  539. data/spaceship/lib/spaceship/ui.rb +27 -0
  540. data/supply/README.md +214 -0
  541. data/supply/lib/supply.rb +29 -0
  542. data/supply/lib/supply/apk_listing.rb +14 -0
  543. data/supply/lib/supply/client.rb +345 -0
  544. data/supply/lib/supply/commands_generator.rb +62 -0
  545. data/supply/lib/supply/listing.rb +32 -0
  546. data/supply/lib/supply/options.rb +135 -0
  547. data/supply/lib/supply/setup.rb +102 -0
  548. data/supply/lib/supply/uploader.rb +221 -0
  549. metadata +699 -428
  550. data/bin//360/237/232/200 +0 -5
  551. data/lib/.DS_Store +0 -0
  552. data/lib/assets/.DS_Store +0 -0
  553. data/lib/assets/completions/.DS_Store +0 -0
  554. data/lib/fastlane/.DS_Store +0 -0
  555. data/lib/fastlane/actions/gym.rb +0 -90
  556. data/lib/fastlane/actions/reset_simulators.rb +0 -44
  557. data/lib/fastlane/cli_tools_distributor.rb +0 -100
  558. data/lib/fastlane/setup/.DS_Store +0 -0
@@ -0,0 +1,17 @@
1
+ module Spaceship
2
+ module Tunes
3
+ # Represents a screenshot hosted on iTunes Connect
4
+ class AppScreenshot < Spaceship::Tunes::AppImage
5
+ attr_accessor :device_type
6
+
7
+ attr_accessor :language
8
+
9
+ class << self
10
+ # Create a new object based on a hash.
11
+ def factory(attrs)
12
+ self.new(attrs)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,60 @@
1
+ module Spaceship
2
+ module Tunes
3
+ # Defines the different states of the app
4
+ #
5
+ # As specified by Apple: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/ChangingAppStatus.html
6
+ module AppStatus
7
+ # You can edit this version, upload new binaries and more
8
+ PREPARE_FOR_SUBMISSION = "Prepare for Submission"
9
+
10
+ # App is currently live in the App Store
11
+ READY_FOR_SALE = "Ready for Sale"
12
+
13
+ # Waiting for Apple's Review
14
+ WAITING_FOR_REVIEW = "Waiting For Review"
15
+
16
+ # Currently in Review
17
+ IN_REVIEW = "In Review"
18
+
19
+ # App rejected for whatever reason
20
+ REJECTED = "Rejected"
21
+
22
+ # The developer took the app from the App Store
23
+ DEVELOPER_REMOVED_FROM_SALE = "Developer Removed From Sale"
24
+
25
+ # Developer rejected this version/binary
26
+ DEVELOPER_REJECTED = "Developer Rejected"
27
+
28
+ # You have to renew your Apple account to keep using iTunes Connect
29
+ PENDING_CONTRACT = "Pending Contract"
30
+
31
+ UPLOAD_RECEIVED = "Upload Received"
32
+ PENDING_DEVELOPER_RELEASE = "Pending Developer Release"
33
+ PROCESSING_FOR_APP_STORE = "Processing for App Store"
34
+ # WAITING_FOR_EXPORT_COMPLIANCE = "Waiting For Export Compliance"
35
+ # METADATA_REJECTED = "Metadata Rejected"
36
+ # REMOVED_FROM_SALE = "Removed From Sale"
37
+ # INVALID_BINARY = "Invalid Binary"
38
+
39
+ # Get the app status matching based on a string (given by iTunes Connect)
40
+ def self.get_from_string(text)
41
+ mapping = {
42
+ 'readyForSale' => READY_FOR_SALE,
43
+ 'prepareForUpload' => PREPARE_FOR_SUBMISSION,
44
+ 'devRejected' => DEVELOPER_REJECTED,
45
+ 'pendingContract' => PENDING_CONTRACT,
46
+ 'developerRemovedFromSale' => DEVELOPER_REMOVED_FROM_SALE,
47
+ 'waitingForReview' => WAITING_FOR_REVIEW,
48
+ 'inReview' => IN_REVIEW,
49
+ 'pendingDeveloperRelease' => PENDING_DEVELOPER_RELEASE
50
+ }
51
+
52
+ mapping.each do |k, v|
53
+ return v if k == text
54
+ end
55
+
56
+ return nil
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,136 @@
1
+
2
+ module Spaceship
3
+ module Tunes
4
+ # Represents a submission for review of an iTunes Connect Application
5
+ # This class handles the submission of all review information and documents
6
+ class AppSubmission < TunesBase
7
+ # @return (Spaceship::Tunes::Application) A reference to the application
8
+ # this submission is for
9
+ attr_accessor :application
10
+
11
+ # @return (AppVersion) The version to use for this submission
12
+ attr_accessor :version
13
+
14
+ # @return (Boolean) Submitted for Review
15
+ attr_accessor :submitted_for_review
16
+
17
+ # To pass from the user
18
+
19
+ # @return (Boolean) Ad ID Info - Limits ads tracking
20
+ attr_accessor :add_id_info_limits_tracking
21
+
22
+ # @return (Boolean) Ad ID Info - Serves ads
23
+ attr_accessor :add_id_info_serves_ads
24
+
25
+ # @return (Boolean) Ad ID Info - Tracks actions
26
+ attr_accessor :add_id_info_tracks_action
27
+
28
+ # @return (Boolean) Ad ID Info - Tracks installs
29
+ attr_accessor :add_id_info_tracks_install
30
+
31
+ # @return (Boolean) Ad ID Info - Uses idfa
32
+ attr_accessor :add_id_info_uses_idfa
33
+
34
+ # @return (Boolean) Content Rights - Contains third party content
35
+ attr_accessor :content_rights_contains_third_party_content
36
+
37
+ # @return (Boolean) Content Rights - Has rights of content
38
+ attr_accessor :content_rights_has_rights
39
+
40
+ # @return (Boolean) Export Compliance - Available on French Store
41
+ attr_accessor :export_compliance_available_on_french_store
42
+
43
+ # @return (Not Yet Implemented) Export Compliance - CCAT File
44
+ attr_accessor :export_compliance_ccat_file
45
+
46
+ # @return (Boolean) Export Compliance - Contains proprietary cryptography
47
+ attr_accessor :export_compliance_contains_proprietary_cryptography
48
+
49
+ # @return (Boolean) Export Compliance - Contains third-party cryptography
50
+ attr_accessor :export_compliance_contains_third_party_cryptography
51
+
52
+ # @return (Boolean) Export Compliance - Is exempt
53
+ attr_accessor :export_compliance_is_exempt
54
+
55
+ # @return (Boolean) Export Compliance - Uses encryption
56
+ attr_accessor :export_compliance_uses_encryption
57
+
58
+ # @return (String) Export Compliance - App type
59
+ attr_accessor :export_compliance_app_type
60
+
61
+ # @return (Boolean) Export Compliance - Encryption Updated
62
+ attr_accessor :export_compliance_encryption_updated
63
+
64
+ # @return (Boolean) Export Compliance - Compliance Required
65
+ attr_accessor :export_compliance_compliance_required
66
+
67
+ # @return (String) Export Compliance - Platform
68
+ attr_accessor :export_compliance_platform
69
+
70
+ attr_mapping({
71
+ # Ad ID Info Section
72
+ 'adIdInfo.limitsTracking.value' => :add_id_info_limits_tracking,
73
+ 'adIdInfo.servesAds.value' => :add_id_info_serves_ads,
74
+ 'adIdInfo.tracksAction.value' => :add_id_info_tracks_action,
75
+ 'adIdInfo.tracksInstall.value' => :add_id_info_tracks_install,
76
+ 'adIdInfo.usesIdfa.value' => :add_id_info_uses_idfa,
77
+
78
+ # Content Rights Section
79
+ 'contentRights.containsThirdPartyContent.value' => :content_rights_contains_third_party_content,
80
+ 'contentRights.hasRights.value' => :content_rights_has_rights,
81
+
82
+ # Export Compliance Section
83
+ 'exportCompliance.availableOnFrenchStore.value' => :export_compliance_available_on_french_store,
84
+ 'exportCompliance.ccatFile.value' => :export_compliance_ccat_file,
85
+ 'exportCompliance.containsProprietaryCryptography.value' => :export_compliance_contains_proprietary_cryptography,
86
+ 'exportCompliance.containsThirdPartyCryptography.value' => :export_compliance_contains_third_party_cryptography,
87
+ 'exportCompliance.isExempt.value' => :export_compliance_is_exempt,
88
+ 'exportCompliance.usesEncryption.value' => :export_compliance_uses_encryption,
89
+ 'exportCompliance.appType' => :export_compliance_app_type,
90
+ 'exportCompliance.encryptionUpdated.value' => :export_compliance_encryption_updated,
91
+ 'exportCompliance.exportComplianceRequired' => :export_compliance_compliance_required,
92
+ 'exportCompliance.platform' => :export_compliance_platform
93
+ })
94
+
95
+ class << self
96
+ # Create a new object based on a hash.
97
+ # This is used to create a new object based on the server response.
98
+ def factory(attrs)
99
+ # fill content rights section if iTC returns nil
100
+ if attrs["contentRights"].nil?
101
+ attrs["contentRights"] = {
102
+ "containsThirdPartyContent" => {
103
+ "value" => nil
104
+ },
105
+ "hasRights" => {
106
+ "value" => nil
107
+ }
108
+ }
109
+ end
110
+
111
+ obj = self.new(attrs)
112
+ return obj
113
+ end
114
+
115
+ # @param application (Spaceship::Tunes::Application) The app this submission is for
116
+ def create(application, version)
117
+ attrs = client.prepare_app_submissions(application.apple_id, application.edit_version.version_id)
118
+ attrs[:application] = application
119
+ attrs[:version] = version
120
+
121
+ return self.factory(attrs)
122
+ end
123
+ end
124
+
125
+ # Save and complete the app submission
126
+ def complete!
127
+ client.send_app_submission(application.apple_id, raw_data)
128
+ @submitted_for_review = true
129
+ end
130
+
131
+ def setup
132
+ @submitted_for_review = false
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,68 @@
1
+ module Spaceship
2
+ module Tunes
3
+ # Represents a preview video hosted on iTunes Connect. Used for icons, screenshots, etc
4
+ class AppTrailer < TunesBase
5
+ attr_accessor :video_asset_token
6
+
7
+ attr_accessor :picture_asset_token
8
+
9
+ attr_accessor :descriptionXML
10
+
11
+ attr_accessor :preview_frame_time_code
12
+
13
+ attr_accessor :video_url
14
+
15
+ attr_accessor :preview_image_url
16
+
17
+ attr_accessor :full_sized_preview_image_url
18
+
19
+ attr_accessor :device_type
20
+
21
+ attr_accessor :language
22
+
23
+ attr_mapping(
24
+ 'videoAssetToken' => :video_asset_token,
25
+ 'pictureAssetToken' => :picture_asset_token,
26
+ 'descriptionXML' => :descriptionXML,
27
+ 'previewFrameTimeCode' => :preview_frame_time_code,
28
+ 'isPortrait' => :is_portrait,
29
+ 'videoUrl' => :video_url,
30
+ 'previewImageUrl' => :preview_image_url,
31
+ 'fullSizedPreviewImageUrl' => :full_sized_preview_image_url,
32
+ 'contentType' => :content_type,
33
+ 'videoStatus' => :video_status
34
+ )
35
+
36
+ class << self
37
+ def factory(attrs)
38
+ self.new(attrs)
39
+ end
40
+ end
41
+
42
+ def reset!(attrs = {})
43
+ update_raw_data!({
44
+ video_asset_token: nil,
45
+ picture_asset_token: nil,
46
+ descriptionXML: nil,
47
+ preview_frame_time_code: nil,
48
+ is_portrait: nil,
49
+ video_url: nil,
50
+ preview_image_url: nil,
51
+ full_sized_preview_image_url: nil,
52
+ content_type: nil,
53
+ video_status: nil,
54
+ device_type: nil,
55
+ language: nil
56
+ }.merge(attrs))
57
+ end
58
+
59
+ private
60
+
61
+ def update_raw_data!(hash)
62
+ hash.each do |k, v|
63
+ self.send("#{k}=", v)
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,766 @@
1
+ module Spaceship
2
+ module Tunes
3
+ # Represents an editable version of an iTunes Connect Application
4
+ # This can either be the live or the edit version retrieved via the app
5
+ # rubocop:disable Metrics/ClassLength
6
+ class AppVersion < TunesBase
7
+ # @return (Spaceship::Tunes::Application) A reference to the application
8
+ # this version is for
9
+ attr_accessor :application
10
+
11
+ # @return (String) The platform value of this version.
12
+ attr_accessor :platform
13
+
14
+ # @return (String) The version number of this version
15
+ attr_accessor :version
16
+
17
+ # @return (String) The copyright information of this app
18
+ attr_accessor :copyright
19
+
20
+ # @return (String) The appType number of this version
21
+ attr_accessor :app_type
22
+
23
+ # @return (Spaceship::Tunes::AppStatus) What's the current status of this app
24
+ # e.g. Waiting for Review, Ready for Sale, ...
25
+ attr_reader :app_status
26
+
27
+ # @return (Bool) Is that the version that's currently available in the App Store?
28
+ attr_accessor :is_live
29
+
30
+ # @return (String) App Status (e.g. 'readyForSale'). You should use `app_status` instead
31
+ attr_accessor :raw_status
32
+
33
+ # @return (String) Build Version
34
+ attr_accessor :build_version
35
+
36
+ # @return (Bool)
37
+ attr_accessor :can_reject_version
38
+
39
+ # @return (Bool)
40
+ attr_accessor :can_prepare_for_upload
41
+
42
+ # @return (Bool)
43
+ attr_accessor :can_send_version_live
44
+
45
+ # @return (Bool) Should the app automatically be released once it's approved?
46
+ attr_accessor :release_on_approval
47
+
48
+ # @return (Bool)
49
+ attr_accessor :can_beta_test
50
+
51
+ # @return (Bool) Does the binary contain a watch binary?
52
+ attr_accessor :supports_apple_watch
53
+
54
+ # @return (Spaceship::Tunes::AppImage) the structure containing information about the large app icon (1024x1024)
55
+ attr_accessor :large_app_icon
56
+
57
+ # @return (Spaceship::Tunes::AppImage) the structure containing information about the large watch icon (1024x1024)
58
+ attr_accessor :watch_app_icon
59
+
60
+ # @return (Integer) a unqiue ID for this version generated by iTunes Connect
61
+ attr_accessor :version_id
62
+
63
+ ####
64
+ # GeoJson
65
+ ####
66
+ # @return (Spaceship::Tunes::TransitAppFile) the structure containing information about the geo json. Can be nil
67
+ attr_accessor :transit_app_file
68
+
69
+ ####
70
+ # App Review Information
71
+ ####
72
+ # @return (String) App Review Information First Name
73
+ attr_accessor :review_first_name
74
+
75
+ # @return (String) App Review Information Last Name
76
+ attr_accessor :review_last_name
77
+
78
+ # @return (String) App Review Information Phone Number
79
+ attr_accessor :review_phone_number
80
+
81
+ # @return (String) App Review Information Email Address
82
+ attr_accessor :review_email
83
+
84
+ # @return (Boolean) The checkbox that indiciates if a demo account
85
+ # is needed. Is set automatically depending on if a user and pass
86
+ # are set
87
+ attr_reader :review_user_needed
88
+
89
+ # @return (String) App Review Information Demo Account User Name
90
+ attr_accessor :review_demo_user
91
+
92
+ # @return (String) App Review Information Demo Account Password
93
+ attr_accessor :review_demo_password
94
+
95
+ # @return (String) App Review Information Notes
96
+ attr_accessor :review_notes
97
+
98
+ ####
99
+ # Localized values
100
+ ####
101
+
102
+ # @return (Array) Raw access the all available languages. You shouldn't use it probably
103
+ attr_accessor :languages
104
+
105
+ # @return (Hash) A hash representing the keywords in all languages
106
+ attr_reader :keywords
107
+
108
+ # @return (Hash) A hash representing the description in all languages
109
+ attr_reader :description
110
+
111
+ # @return (Hash) The changelog
112
+ attr_reader :release_notes
113
+
114
+ # @return (Hash) A hash representing the support url in all languages
115
+ attr_reader :support_url
116
+
117
+ # @return (Hash) A hash representing the marketing url in all languages
118
+ attr_reader :marketing_url
119
+
120
+ # @return (Hash) Represents the screenshots of this app version (read-only)
121
+ attr_reader :screenshots
122
+
123
+ # @return (Hash) Represents the trailers of this app version (read-only)
124
+ attr_reader :trailers
125
+
126
+ attr_mapping({
127
+ 'appType' => :app_type,
128
+ 'platform' => :platform,
129
+ 'canBetaTest' => :can_beta_test,
130
+ 'canPrepareForUpload' => :can_prepare_for_upload,
131
+ 'canRejectVersion' => :can_reject_version,
132
+ 'canSendVersionLive' => :can_send_version_live,
133
+ 'copyright.value' => :copyright,
134
+ 'details.value' => :languages,
135
+ 'largeAppIcon.value.originalFileName' => :app_icon_original_name,
136
+ 'largeAppIcon.value.url' => :app_icon_url,
137
+ 'releaseOnApproval.value' => :release_on_approval,
138
+ 'status' => :raw_status,
139
+ 'preReleaseBuild.buildVersion' => :build_version,
140
+ 'supportsAppleWatch' => :supports_apple_watch,
141
+ 'versionId' => :version_id,
142
+ 'version.value' => :version,
143
+
144
+ # GeoJson
145
+ # 'transitAppFile.value' => :transit_app_file
146
+
147
+ # App Review Information
148
+ 'appReviewInfo.firstName.value' => :review_first_name,
149
+ 'appReviewInfo.lastName.value' => :review_last_name,
150
+ 'appReviewInfo.phoneNumber.value' => :review_phone_number,
151
+ 'appReviewInfo.emailAddress.value' => :review_email,
152
+ 'appReviewInfo.reviewNotes.value' => :review_notes,
153
+ 'appReviewInfo.accountRequired.value' => :review_user_needed,
154
+ 'appReviewInfo.userName.value' => :review_demo_user,
155
+ 'appReviewInfo.password.value' => :review_demo_password
156
+ })
157
+
158
+ class << self
159
+ # Create a new object based on a hash.
160
+ # This is used to create a new object based on the server response.
161
+ def factory(attrs)
162
+ obj = self.new(attrs)
163
+ obj.unfold_languages
164
+
165
+ return obj
166
+ end
167
+
168
+ # @param application (Spaceship::Tunes::Application) The app this version is for
169
+ # @param app_id (String) The unique Apple ID of this app
170
+ # @param is_live (Boolean)
171
+ def find(application, app_id, is_live, platform: nil)
172
+ # we only support applications
173
+ raise "We do not support BUNDLE types right now" if application.type == 'BUNDLE'
174
+
175
+ # too bad the "id" field is empty, it forces us to make more requests to the server
176
+ # these could also be cached
177
+ attrs = client.app_version(app_id, is_live, platform: platform)
178
+ return nil unless attrs
179
+
180
+ attrs[:application] = application
181
+ attrs[:is_live] = is_live
182
+
183
+ return self.factory(attrs)
184
+ end
185
+ end
186
+
187
+ # @return (Bool) Is that version currently available in the App Store?
188
+ def is_live?
189
+ is_live
190
+ end
191
+
192
+ def review_user_needed
193
+ (self.review_demo_user.to_s + self.review_demo_password.to_s).length > 0
194
+ end
195
+
196
+ # Call this method to make sure the given languages are available for this app
197
+ # You should call this method before accessing the name, description and other localized values
198
+ # This will create the new language if it's not available yet and do nothing if everything's there
199
+ # Important: Due to a bug you have to fetch the `edit_version` again, as it doesn't get refreshed immediately
200
+ def create_languages(languages)
201
+ languages = [languages] if languages.kind_of?(String)
202
+ raise "Please pass an array" unless languages.kind_of? Array
203
+
204
+ copy_from = self.languages.find { |a| a['language'] == 'en-US' } || self.languages.first
205
+
206
+ languages.each do |language|
207
+ # First, see if it's already available
208
+ found = self.languages.find do |local|
209
+ local['language'] == language
210
+ end
211
+ next if found
212
+
213
+ new_language = copy_from.clone
214
+ new_language['language'] = language
215
+
216
+ self.languages << new_language
217
+ end
218
+ nil
219
+ end
220
+
221
+ def current_build_number
222
+ if self.is_live?
223
+ build_version
224
+ else
225
+ if candidate_builds.length > 0
226
+ candidate_builds.first.build_version
227
+ end
228
+ end
229
+ end
230
+
231
+ # Returns an array of all builds that can be sent to review
232
+ def candidate_builds
233
+ res = client.candidate_builds(self.application.apple_id, self.version_id)
234
+ builds = []
235
+ res.each do |attrs|
236
+ next unless attrs["type"] == "BUILD" # I don't know if it can be something else.
237
+ attrs[:apple_id] = self.application.apple_id
238
+ builds << Tunes::Build.factory(attrs)
239
+ end
240
+ return builds
241
+ end
242
+
243
+ # Select a build to be submitted for Review.
244
+ # You have to pass a build you got from - candidate_builds
245
+ # Don't forget to call save! after calling this method
246
+ def select_build(build)
247
+ raw_data.set(['preReleaseBuildVersionString', 'value'], build.build_version)
248
+ raw_data.set(['preReleaseBuildTrainVersionString'], build.train_version)
249
+ raw_data.set(['preReleaseBuildUploadDate'], build.upload_date)
250
+ true
251
+ end
252
+
253
+ # Set the age restriction rating
254
+ # Call it like this:
255
+ # v.update_rating({
256
+ # 'CARTOON_FANTASY_VIOLENCE' => 0,
257
+ # 'MATURE_SUGGESTIVE' => 2,
258
+ # 'UNRESTRICTED_WEB_ACCESS' => 0,
259
+ # 'GAMBLING_CONTESTS' => 0
260
+ # })
261
+ #
262
+ # Available Values
263
+ # https://github.com/fastlane/fastlane/blob/master/deliver/Reference.md
264
+ def update_rating(hash)
265
+ raise "Must be a hash" unless hash.kind_of?(Hash)
266
+
267
+ hash.each do |key, value|
268
+ to_edit = self.raw_data['ratings']['nonBooleanDescriptors'].find do |current|
269
+ current['name'].include?(key)
270
+ end
271
+
272
+ if to_edit
273
+ to_set = "NONE" if value == 0
274
+ to_set = "INFREQUENT_MILD" if value == 1
275
+ to_set = "FREQUENT_INTENSE" if value == 2
276
+ raise "Invalid value '#{value}' for '#{key}', must be 0-2" unless to_set
277
+ to_edit['level'] = "ITC.apps.ratings.level.#{to_set}"
278
+ else
279
+ # Maybe it's a boolean descriptor?
280
+ to_edit = self.raw_data['ratings']['booleanDescriptors'].find do |current|
281
+ current['name'].include?(key)
282
+ end
283
+
284
+ if to_edit
285
+ to_set = "NO"
286
+ to_set = "YES" if value.to_i > 0
287
+ to_edit['level'] = "ITC.apps.ratings.level.#{to_set}"
288
+ else
289
+ raise "Could not find option '#{key}' in the list of available options"
290
+ end
291
+ end
292
+ end
293
+ true
294
+ end
295
+
296
+ # Push all changes that were made back to iTunes Connect
297
+ def save!
298
+ client.update_app_version!(application.apple_id, self.version_id, raw_data)
299
+ end
300
+
301
+ # @return (String) An URL to this specific resource. You can enter this URL into your browser
302
+ def url
303
+ url = "https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa/ra/ng/app/#{application.apple_id}/ios/versioninfo/"
304
+ url += "deliverable" if self.is_live?
305
+ return url
306
+ end
307
+
308
+ # Private methods
309
+ def setup
310
+ # Properly parse the AppStatus
311
+ status = raw_data['status']
312
+ @app_status = Tunes::AppStatus.get_from_string(status)
313
+ setup_large_app_icon
314
+ setup_watch_app_icon
315
+ setup_transit_app_file if supports_app_transit?
316
+ setup_screenshots
317
+ setup_trailers
318
+ end
319
+
320
+ # This method will generate the required keys/values
321
+ # for iTunes Connect to validate the uploaded image
322
+ def generate_image_metadata(image_data, original_file_name)
323
+ {
324
+ assetToken: image_data["token"],
325
+ originalFileName: original_file_name,
326
+ size: image_data["length"],
327
+ height: image_data["height"],
328
+ width: image_data["width"],
329
+ checksum: image_data["md5"]
330
+ }
331
+ end
332
+
333
+ # Uploads or removes the large icon
334
+ # @param icon_path (String): The path to the icon. Use nil to remove it
335
+ def upload_large_icon!(icon_path)
336
+ unless icon_path
337
+ @large_app_icon.reset!
338
+ return
339
+ end
340
+ upload_image = UploadFile.from_path icon_path
341
+ image_data = client.upload_large_icon(self, upload_image)
342
+
343
+ raw_data["largeAppIcon"]["value"] = generate_image_metadata(image_data, upload_image.file_name)
344
+ end
345
+
346
+ # Uploads or removes the watch icon
347
+ # @param icon_path (String): The path to the icon. Use nil to remove it
348
+ def upload_watch_icon!(icon_path)
349
+ unless icon_path
350
+ @watch_app_icon.reset!
351
+ return
352
+ end
353
+ upload_image = UploadFile.from_path icon_path
354
+ image_data = client.upload_watch_icon(self, upload_image)
355
+
356
+ raw_data["watchAppIcon"]["value"] = generate_image_metadata(image_data, upload_image.file_name)
357
+ end
358
+
359
+ # Uploads or removes the transit app file
360
+ # @param icon_path (String): The path to the geojson file. Use nil to remove it
361
+ def upload_geojson!(geojson_path)
362
+ unless geojson_path
363
+ raw_data["transitAppFile"]["value"] = nil
364
+ @transit_app_file = nil
365
+ return
366
+ end
367
+ upload_file = UploadFile.from_path geojson_path
368
+ geojson_data = client.upload_geojson(self, upload_file)
369
+
370
+ @transit_app_file = Tunes::TransitAppFile.factory({}) if @transit_app_file.nil?
371
+ @transit_app_file .url = nil # response.headers['Location']
372
+ @transit_app_file.asset_token = geojson_data["token"]
373
+ @transit_app_file.name = upload_file.file_name
374
+ @transit_app_file.time_stamp = Time.now.to_i * 1000 # works without but...
375
+ end
376
+
377
+ # Uploads or removes a screenshot
378
+ # @param icon_path (String): The path to the screenshot. Use nil to remove it
379
+ # @param sort_order (Fixnum): The sort_order, from 1 to 5
380
+ # @param language (String): The language for this screenshot
381
+ # @param device (string): The device for this screenshot
382
+ # @param is_messages (Bool): True if the screenshot is for iMessage
383
+ def upload_screenshot!(screenshot_path, sort_order, language, device, is_messages)
384
+ raise "sort_order must be higher than 0" unless sort_order > 0
385
+ raise "sort_order must not be > 5" if sort_order > 5
386
+ # this will also check both language and device parameters
387
+ device_lang_screenshots = screenshots_data_for_language_and_device(language, device, is_messages)["value"]
388
+
389
+ existing_sort_orders = device_lang_screenshots.map { |s| s["value"]["sortOrder"] }
390
+ if screenshot_path # adding / replacing
391
+ upload_file = UploadFile.from_path screenshot_path
392
+ screenshot_data = client.upload_screenshot(self, upload_file, device, is_messages)
393
+
394
+ # Since October 2016 we also need to pass the size, height, width and checksum
395
+ # otherwise iTunes Connect validation will fail at a later point
396
+ new_screenshot = {
397
+ "value" => {
398
+ "assetToken" => screenshot_data["token"],
399
+ "sortOrder" => sort_order,
400
+ "originalFileName" => upload_file.file_name,
401
+ "size" => screenshot_data["length"],
402
+ "height" => screenshot_data["height"],
403
+ "width" => screenshot_data["width"],
404
+ "checksum" => screenshot_data["md5"]
405
+ }
406
+ }
407
+
408
+ # We disable "scaling" for this device type / language combination
409
+ # We only set this, if we actually successfully uploaded a new screenshot
410
+ # for this device / language combination
411
+ # if this value is not set, iTC will fallback to another device type for screenshots
412
+ language_details = raw_data_details.find { |d| d["language"] == language }["displayFamilies"]["value"]
413
+ device_language_details = language_details.find { |display_family| display_family['name'] == device }
414
+ scaled_key = is_messages ? "messagesScaled" : "scaled"
415
+ device_language_details[scaled_key]["value"] = false
416
+
417
+ if existing_sort_orders.include?(sort_order) # replace
418
+ device_lang_screenshots[existing_sort_orders.index(sort_order)] = new_screenshot
419
+ else # add
420
+ device_lang_screenshots << new_screenshot
421
+ end
422
+ else # removing
423
+ raise "cannot remove screenshot with non existing sort_order" unless existing_sort_orders.include?(sort_order)
424
+ device_lang_screenshots.delete_at(existing_sort_orders.index(sort_order))
425
+ end
426
+ setup_screenshots
427
+ end
428
+
429
+ # Uploads, removes a trailer video or change its preview image
430
+ #
431
+ # A preview image for the video is required by ITC and is usually automatically extracted by your browser.
432
+ # This method will either automatically extract it from the video (using `ffmpeg) or allow you
433
+ # to specify it using +preview_image_path+.
434
+ # If the preview image is specified, ffmpeg` will ot be used. The image resolution will be checked against
435
+ # expectations (which might be different from the trailer resolution.
436
+ #
437
+ # It is recommended to extract the preview image using the spaceship related tools in order to ensure
438
+ # the appropriate format and resolution are used.
439
+ #
440
+ # Note: if the video is already set, the +trailer_path+ is only used to grab the preview screenshot.
441
+ # Note: to extract its resolution and a screenshot preview, the `ffmpeg` tool will be used
442
+ #
443
+ # @param icon_path (String): The path to the screenshot. Use nil to remove it
444
+ # @param sort_order (Fixnum): The sort_order, from 1 to 5
445
+ # @param language (String): The language for this screenshot
446
+ # @param device (String): The device for this screenshot
447
+ # @param timestamp (String): The optional timestamp of the screenshot to grab
448
+ def upload_trailer!(trailer_path, language, device, timestamp = "05.00", preview_image_path = nil)
449
+ raise "No app trailer supported for iphone35" if device == 'iphone35'
450
+
451
+ device_lang_trailer = trailer_data_for_language_and_device(language, device, is_messages)
452
+ if trailer_path # adding / replacing trailer / replacing preview
453
+ raise "Invalid timestamp #{timestamp}" if (timestamp =~ /^[0-9][0-9].[0-9][0-9]$/).nil?
454
+
455
+ if preview_image_path
456
+ check_preview_screenshot_resolution(preview_image_path, device)
457
+ video_preview_path = preview_image_path
458
+ else
459
+ # IDEA: optimization, we could avoid fetching the screenshot if the timestamp hasn't changed
460
+ video_preview_resolution = video_preview_resolution_for(device, trailer_path)
461
+ video_preview_path = Utilities.grab_video_preview(trailer_path, timestamp, video_preview_resolution)
462
+ end
463
+ video_preview_file = UploadFile.from_path video_preview_path
464
+ video_preview_data = client.upload_trailer_preview(self, video_preview_file)
465
+
466
+ trailer = device_lang_trailer["value"]
467
+ if trailer.nil? # add trailer
468
+ upload_file = UploadFile.from_path trailer_path
469
+ trailer_data = client.upload_trailer(self, upload_file)
470
+ trailer_data = trailer_data['responses'][0]
471
+ trailer = {
472
+ "videoAssetToken" => trailer_data["token"],
473
+ "descriptionXML" => trailer_data["descriptionDoc"],
474
+ "contentType" => upload_file.content_type
475
+ }
476
+ device_lang_trailer["value"] = trailer
477
+ end
478
+ # add / update preview
479
+ # different format required
480
+ ts = "00:00:#{timestamp}"
481
+ ts[8] = ':'
482
+
483
+ trailer.merge!({
484
+ "pictureAssetToken" => video_preview_data["token"],
485
+ "previewFrameTimeCode" => ts.to_s,
486
+ "isPortrait" => Utilities.portrait?(video_preview_path)
487
+ })
488
+ else # removing trailer
489
+ raise "cannot remove non existing trailer" if device_lang_trailer["value"].nil?
490
+ device_lang_trailer["value"] = nil
491
+ end
492
+ setup_trailers
493
+ end
494
+
495
+ # Prefill name, keywords, etc...
496
+ def unfold_languages
497
+ {
498
+ keywords: :keywords,
499
+ description: :description,
500
+ supportURL: :support_url,
501
+ marketingURL: :marketing_url,
502
+ releaseNotes: :release_notes
503
+ }.each do |json, attribute|
504
+ instance_variable_set("@#{attribute}".to_sym, LanguageItem.new(json, languages))
505
+ end
506
+ end
507
+
508
+ def release!
509
+ client.release!(self.application.apple_id, self.version_id)
510
+ end
511
+
512
+ #####################################################
513
+ # @!group Promo codes
514
+ #####################################################
515
+ def generate_promocodes!(quantity)
516
+ data = client.generate_app_version_promocodes!(
517
+ app_id: self.application.apple_id,
518
+ version_id: self.version_id,
519
+ quantity: quantity
520
+ )
521
+ Tunes::AppVersionGeneratedPromocodes.factory(data)
522
+ end
523
+
524
+ # These methods takes care of properly parsing values that
525
+ # are not returned in the right format, e.g. boolean as string
526
+ def release_on_approval
527
+ super == 'true'
528
+ end
529
+
530
+ def supports_apple_watch
531
+ !super.nil?
532
+ end
533
+
534
+ def reject!
535
+ raise 'Version not rejectable' unless can_reject_version
536
+ client.reject!(self.application.apple_id, self.version_id)
537
+ end
538
+
539
+ private
540
+
541
+ def setup_large_app_icon
542
+ large_app_icon = raw_data["largeAppIcon"]["value"]
543
+ @large_app_icon = nil
544
+ @large_app_icon = Tunes::AppImage.factory(large_app_icon) if large_app_icon
545
+ end
546
+
547
+ def setup_watch_app_icon
548
+ watch_app_icon = raw_data["watchAppIcon"]["value"]
549
+ @watch_app_icon = nil
550
+ @watch_app_icon = Tunes::AppImage.factory(watch_app_icon) if watch_app_icon
551
+ end
552
+
553
+ def supports_app_transit?
554
+ raw_data["transitAppFile"] != nil
555
+ end
556
+
557
+ def setup_transit_app_file
558
+ transit_app_file = raw_data["transitAppFile"]["value"]
559
+ @transit_app_file = nil
560
+ @transit_app_file = Tunes::TransitAppFile.factory(transit_app_file) if transit_app_file
561
+ end
562
+
563
+ def screenshots_data_for_language_and_device(language, device, is_messages)
564
+ data_field = is_messages ? "messagesScreenshots" : "screenshots"
565
+ container_data_for_language_and_device(data_field, language, device)
566
+ end
567
+
568
+ def trailer_data_for_language_and_device(language, device)
569
+ container_data_for_language_and_device("appTrailers", language, device)
570
+ end
571
+
572
+ def container_data_for_language_and_device(data_field, language, device)
573
+ raise "#{device} isn't a valid device name" unless DeviceType.exists?(device)
574
+
575
+ languages = raw_data_details.select { |d| d["language"] == language }
576
+ # IDEA: better error for non existing language
577
+ raise "#{language} isn't an activated language" unless languages.count > 0
578
+ lang_details = languages[0]
579
+ display_families = lang_details["displayFamilies"]["value"]
580
+ device_details = display_families.find { |display_family| display_family['name'] == device }
581
+ raise "Unexpected state: missing device details for #{device}" unless device_details.key?(data_field)
582
+ return device_details[data_field]
583
+ rescue => ex
584
+ raise "iTunes Connect error: #{ex}"
585
+ end
586
+
587
+ def setup_screenshots
588
+ @screenshots = {}
589
+
590
+ raw_data_details.each do |row|
591
+ # Now that's one language right here
592
+ @screenshots[row['language']] = setup_screenshots_for(row) + setup_messages_screenshots_for(row)
593
+ end
594
+ end
595
+
596
+ # generates the nested data structure to represent screenshots
597
+ def setup_screenshots_for(row)
598
+ return [] if row.nil? || row["displayFamilies"].nil?
599
+
600
+ display_families = row.fetch("displayFamilies", {}).fetch("value", nil)
601
+ return [] unless display_families
602
+
603
+ result = []
604
+
605
+ display_families.each do |display_family|
606
+ # {
607
+ # "name": "iphone6Plus",
608
+ # "scaled": {
609
+ # "value": false,
610
+ # "isEditable": false,
611
+ # "isRequired": false,
612
+ # "errorKeys": null
613
+ # },
614
+ # "screenshots": {
615
+ # "value": [{
616
+ # "value": {
617
+ # "assetToken": "Purple62/v4/08/0a/04/080a0430-c2cc-2577-f491-9e0a09c58ffe/mzl.pbcpzqyg.jpg",
618
+ # "sortOrder": 1,
619
+ # "type": null,
620
+ # "originalFileName": "ios-414-1.jpg"
621
+ # },
622
+ # "isEditable": true,
623
+ # "isRequired": false,
624
+ # "errorKeys": null
625
+ # }, {
626
+ # "value": {
627
+ # "assetToken": "Purple71/v4/de/81/aa/de81aa10-64f6-332e-c974-9ee46adab675/mzl.cshkjvwl.jpg",
628
+ # "sortOrder": 2,
629
+ # "type": null,
630
+ # "originalFileName": "ios-414-2.jpg"
631
+ # },
632
+ # "isEditable": true,
633
+ # "isRequired": false,
634
+ # "errorKeys": null
635
+ # }],
636
+ # "messagesScaled": {
637
+ # "value": false,
638
+ # "isEditable": false,
639
+ # "isRequired": false,
640
+ # "errorKeys": null
641
+ # },
642
+ # "messagesScreenshots": {
643
+ # "value": [{
644
+ # "value": {
645
+ # "assetToken": "Purple62/v4/08/0a/04/080a0430-c2cc-2577-f491-9e0a09c58ffe/mzl.pbcpzqyg.jpg",
646
+ # "sortOrder": 1,
647
+ # "type": null,
648
+ # "originalFileName": "ios-414-1.jpg"
649
+ # },
650
+ # "isEditable": true,
651
+ # "isRequired": false,
652
+ # "errorKeys": null
653
+ # }, {
654
+ # "value": {
655
+ # "assetToken": "Purple71/v4/de/81/aa/de81aa10-64f6-332e-c974-9ee46adab675/mzl.cshkjvwl.jpg",
656
+ # "sortOrder": 2,
657
+ # "type": null,
658
+ # "originalFileName": "ios-414-2.jpg"
659
+ # },
660
+ # "isEditable": true,
661
+ # "isRequired": false,
662
+ # "errorKeys": null
663
+ # }],
664
+ # "isEditable": true,
665
+ # "isRequired": false,
666
+ # "errorKeys": null
667
+ # },
668
+ # "trailer": {
669
+ # "value": null,
670
+ # "isEditable": true,
671
+ # "isRequired": false,
672
+ # "errorKeys": null
673
+ # }
674
+ # }
675
+
676
+ display_family.fetch("screenshots", {}).fetch("value", []).each do |screenshot|
677
+ screenshot_data = screenshot["value"]
678
+ data = {
679
+ device_type: display_family['name'],
680
+ language: row["language"]
681
+ }.merge(screenshot_data)
682
+ result << Tunes::AppScreenshot.factory(data)
683
+ end
684
+ end
685
+
686
+ return result
687
+ end
688
+
689
+ # generates the nested data structure to represent screenshots
690
+ def setup_messages_screenshots_for(row)
691
+ return [] if row.nil? || row["displayFamilies"].nil?
692
+
693
+ display_families = row.fetch("displayFamilies", {}).fetch("value", nil)
694
+ return [] unless display_families
695
+
696
+ result = []
697
+
698
+ display_families.each do |display_family|
699
+ display_family_screenshots = display_family.fetch("messagesScreenshots", {})
700
+ next unless display_family_screenshots
701
+ display_family_screenshots.fetch("value", []).each do |screenshot|
702
+ screenshot_data = screenshot["value"]
703
+ data = {
704
+ device_type: display_family['name'],
705
+ language: row["language"],
706
+ is_imessage: true # to identify imessage screenshots later on (e.g: during download)
707
+ }.merge(screenshot_data)
708
+ result << Tunes::AppScreenshot.factory(data)
709
+ end
710
+ end
711
+
712
+ return result
713
+ end
714
+
715
+ def setup_trailers
716
+ @trailers = {}
717
+ raw_data_details.each do |row|
718
+ # Now that's one language right here
719
+ @trailers[row["language"]] = setup_trailers_for(row)
720
+ end
721
+ end
722
+
723
+ # generates the nested data structure to represent trailers
724
+ def setup_trailers_for(row)
725
+ return [] if row.nil? || row["displayFamilies"].nil?
726
+
727
+ display_families = row.fetch("displayFamilies", {}).fetch("value", nil)
728
+ return [] unless display_families
729
+
730
+ result = []
731
+
732
+ display_families.each do |display_family|
733
+ trailer_data = display_family.fetch("trailer", {}).fetch("value")
734
+ next if trailer_data.nil?
735
+ data = {
736
+ device_type: display_family['name'],
737
+ language: row["language"]
738
+ }.merge(trailer_data)
739
+ result << Tunes::AppTrailer.factory(data)
740
+ end
741
+
742
+ return result
743
+ end
744
+
745
+ # identify the required resolution for this particular video screenshot
746
+ def video_preview_resolution_for(device, video_path)
747
+ is_portrait = Utilities.portrait?(video_path)
748
+ TunesClient.video_preview_resolution_for(device, is_portrait)
749
+ end
750
+
751
+ # ensure the specified preview screenshot has the expected resolution the specified target +device+
752
+ def check_preview_screenshot_resolution(preview_screenshot_path, device)
753
+ is_portrait = Utilities.portrait?(preview_screenshot_path)
754
+ expected_resolution = TunesClient.video_preview_resolution_for(device, is_portrait)
755
+ actual_resolution = Utilities.resolution(preview_screenshot_path)
756
+ orientation = is_portrait ? "portrait" : "landscape"
757
+ raise "Invalid #{orientation} screenshot resolution for device #{device}. Should be #{expected_resolution}" unless actual_resolution == expected_resolution
758
+ end
759
+
760
+ def raw_data_details
761
+ raw_data["details"]["value"]
762
+ end
763
+ end
764
+ # rubocop:enable Metrics/ClassLength
765
+ end
766
+ end