deliver 0.13.5 → 1.0.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -208
  3. data/bin/deliver +1 -1
  4. data/lib/assets/DeliverfileDefault +2 -22
  5. data/lib/assets/summary.html.erb +27 -39
  6. data/lib/deliver.rb +16 -14
  7. data/lib/deliver/app_screenshot.rb +43 -33
  8. data/lib/deliver/commands_generator.rb +30 -108
  9. data/lib/deliver/detect_values.rb +23 -0
  10. data/lib/deliver/download_screenshots.rb +30 -9
  11. data/lib/deliver/html_generator.rb +7 -8
  12. data/lib/deliver/options.rb +126 -0
  13. data/lib/deliver/runner.rb +75 -0
  14. data/lib/deliver/setup.rb +84 -0
  15. data/lib/deliver/submit_for_review.rb +60 -0
  16. data/lib/deliver/upload_assets.rb +22 -0
  17. data/lib/deliver/upload_metadata.rb +100 -0
  18. data/lib/deliver/upload_price_tier.rb +21 -0
  19. data/lib/deliver/upload_screenshots.rb +63 -0
  20. data/lib/deliver/version.rb +2 -1
  21. metadata +37 -62
  22. data/lib/assets/DeliverLanguageMapping.json +0 -187
  23. data/lib/assets/DeliverfileExample +0 -38
  24. data/lib/deliver/app.rb +0 -167
  25. data/lib/deliver/app_metadata.rb +0 -419
  26. data/lib/deliver/app_metadata_screenshots.rb +0 -189
  27. data/lib/deliver/deliver_process.rb +0 -426
  28. data/lib/deliver/deliverer.rb +0 -138
  29. data/lib/deliver/deliverfile/deliverfile.rb +0 -35
  30. data/lib/deliver/deliverfile/deliverfile_creator.rb +0 -135
  31. data/lib/deliver/deliverfile/dsl.rb +0 -142
  32. data/lib/deliver/dependency_checker.rb +0 -19
  33. data/lib/deliver/ipa_file_analyser.rb +0 -44
  34. data/lib/deliver/ipa_uploader.rb +0 -148
  35. data/lib/deliver/itunes_connect/itunes_connect.rb +0 -12
  36. data/lib/deliver/itunes_connect/itunes_connect_additional.rb +0 -105
  37. data/lib/deliver/itunes_connect/itunes_connect_app_icon.rb +0 -41
  38. data/lib/deliver/itunes_connect/itunes_connect_app_rating.rb +0 -90
  39. data/lib/deliver/itunes_connect/itunes_connect_apple_watch_app_icon.rb +0 -42
  40. data/lib/deliver/itunes_connect/itunes_connect_information.rb +0 -34
  41. data/lib/deliver/itunes_connect/itunes_connect_new_version.rb +0 -67
  42. data/lib/deliver/itunes_connect/itunes_connect_reader.rb +0 -46
  43. data/lib/deliver/itunes_connect/itunes_connect_screenshot_fetcher.rb +0 -54
  44. data/lib/deliver/itunes_connect/itunes_connect_submission.rb +0 -282
  45. data/lib/deliver/itunes_transporter.rb +0 -221
  46. data/lib/deliver/metadata_item.rb +0 -94
  47. data/lib/deliver/testflight.rb +0 -27
@@ -1,138 +0,0 @@
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
- DESCRIPTION = :description
22
- TITLE = :title
23
- BETA_IPA = :beta_ipa
24
- IS_BETA_IPA = :is_beta_ipa
25
- SKIP_DEPLOY = :skip_deploy
26
- CHANGELOG = :changelog
27
- SUPPORT_URL = :support_url
28
- PRIVACY_URL = :privacy_url
29
- MARKETING_URL = :marketing_url
30
- KEYWORDS = :keywords
31
- SCREENSHOTS_PATH = :screenshots_path
32
- DEFAULT_LANGUAGE = :default_language
33
- CONFIG_JSON_FOLDER = :config_json_folder # Path to a folder containing a configuration file and including screenshots
34
- SKIP_PDF = :skip_pdf
35
- SUBMIT_FURTHER_INFORMATION = :submit_further_information # export compliance, content rights and advertising identifier
36
- PRICE_TIER = :price_tier
37
- APP_ICON = :app_icon
38
- APPLE_WATCH_APP_ICON = :apple_watch_app_icon
39
-
40
- COPYRIGHT = :copyright
41
- PRIMARY_CATEGORY = :primary_category
42
- SECONDARY_CATEGORY = :secondary_category
43
- PRIMARY_SUBCATEGORIES = :primary_subcategories
44
- SECONDARY_SUBCATEGORIES = :secondary_subcategories
45
-
46
- AUTOMATIC_RELEASE = :automatic_release # should the update go live after approval
47
- RATINGS_CONFIG_PATH = :ratings_config_path # a path to the configuration for the app's ratings
48
-
49
- APP_REVIEW_INFORMATION = :app_review_information
50
- # Supported
51
- # first_name
52
- # last_name
53
- # phone_number
54
- # email_address
55
- # demo_user
56
- # demo_password
57
- # notes
58
- end
59
-
60
- module AllBlocks
61
- UNIT_TESTS = :unit_tests
62
- SUCCESS = :success
63
- ERROR = :error
64
- end
65
-
66
-
67
- # Start a new deployment process based on the given Deliverfile
68
- # @param (String) path The path to the Deliverfile.
69
- # @param (Hash) hash You can pass a hash instead of a path to basically
70
- # give all the information required (see {Deliverer::ValKey} for available options)
71
- # @param (Bool) force Runs a deployment without verifying any information. This can be
72
- # used for build servers. If this is set to false a PDF summary will be generated and opened
73
- def initialize(path = nil, hash: nil, force: false, is_beta_ipa: false, skip_deploy: false)
74
- @deliver_process = DeliverProcess.new
75
- @deliver_process.deploy_information[ValKey::SKIP_PDF] = true if force
76
- @deliver_process.deploy_information[ValKey::IS_BETA_IPA] = is_beta_ipa
77
- @deliver_process.deploy_information[ValKey::SKIP_DEPLOY] = skip_deploy
78
-
79
- if hash
80
- hash.each do |key, value|
81
- # we still call this interface to verify the inputs correctly
82
- set_new_value(key, value)
83
- end
84
-
85
- finished_executing_deliver_file
86
- else
87
- @deliver_file = Deliver::Deliverfile::Deliverfile.new(self, path)
88
- end
89
-
90
- # Do not put code here...
91
- end
92
-
93
- # This method is internally called from the Deliverfile DSL
94
- # to set a value for a given key. This method will also verify if
95
- # the key is valid.
96
- def set_new_value(key, value)
97
- unless self.class.all_available_keys_to_set.include?key
98
- raise "Invalid key '#{key}', must be contained in Deliverer::ValKey.".red
99
- end
100
-
101
- if @deliver_process.deploy_information[key]
102
- Helper.log.warn("You already set a value for key '#{key}'. Overwriting with new value '#{value}'.")
103
- end
104
-
105
- @deliver_process.deploy_information[key] = value
106
- end
107
-
108
- # Sets a new block for a specific key
109
- def set_new_block(key, block)
110
- @deliver_process.deploy_information[:blocks][key] = block
111
- end
112
-
113
- # An array of all available options to be set a deployment_information.
114
- #
115
- # Is used to verify user inputs
116
- # @return (Hash) The array of symbols
117
- def self.all_available_keys_to_set
118
- Deliverer::ValKey.constants.collect { |a| Deliverer::ValKey.const_get(a) }
119
- end
120
-
121
- # An array of all available blocks to be set for a deployment
122
- #
123
- # Is used to verify user inputs
124
- # @return (Hash) The array of symbols
125
- def self.all_available_blocks_to_set
126
- Deliverer::AllBlocks.constants.collect { |a| Deliverer::AllBlocks.const_get(a) }
127
- end
128
-
129
- # This method will take care of the actual deployment process, after we
130
- # received all information from the Deliverfile.
131
- #
132
- # This method will be called from the {Deliver::Deliverfile} after
133
- # it is finished executing the Ruby script.
134
- def finished_executing_deliver_file
135
- deliver_process.run
136
- end
137
- end
138
- end
@@ -1,35 +0,0 @@
1
- require 'deliver/deliverfile/dsl'
2
-
3
- module Deliver
4
- module Deliverfile
5
- # Deliverfile represents a Deliverfile created by a user of this library
6
- class Deliverfile
7
-
8
- FILE_NAME = "Deliverfile"
9
-
10
- include Deliver::Deliverfile::Deliverfile::DSL
11
-
12
- # The path to the used Deliverfile.
13
- attr_accessor :path
14
-
15
- # Loads the Deliverfile from the given path
16
- # @param deliver_data (Deliver::Deliverer) The deliverer which handles the
17
- # results of running this deliverfile
18
- # @param (String) path (optional) to the file itself. This must also include the
19
- # filename itself.
20
- def initialize(deliver_data, path = nil)
21
- path ||= "./#{FILE_NAME}"
22
- raise "#{FILE_NAME} not found at path '#{File.expand_path(path)}'".red unless File.exists?(path.to_s)
23
-
24
- self.path = path
25
- @deliver_data = deliver_data
26
-
27
- content = File.read(path)
28
-
29
- eval(content) # this is okay in this case
30
-
31
- @deliver_data.finished_executing_deliver_file
32
- end
33
- end
34
- end
35
- end
@@ -1,135 +0,0 @@
1
- require 'credentials_manager/password_manager'
2
- require 'credentials_manager/appfile_config'
3
- require 'deliver/itunes_connect/itunes_connect'
4
-
5
- module Deliver
6
- # Helps new user quickly adopt Deliver
7
- class DeliverfileCreator
8
-
9
- # This method will ask the user what he wants to do
10
- # @param deliver_path (String) The path in which the Deliverfile should be created (this automatically takes care if it's in the fastlane folder)
11
- # @param project_name (String) The default name of the project, which is used in the generated Deliverfile
12
- def self.create(deliver_path, project_name = nil)
13
- deliver_file_path = File.join(deliver_path, Deliver::Deliverfile::Deliverfile::FILE_NAME)
14
- raise "Deliverfile already exists at path '#{deliver_file_path}'. Run 'deliver' to use Deliver.".red if File.exists?(deliver_file_path)
15
-
16
- project_name ||= Dir.pwd.split("/").last
17
-
18
- if agree("Do you want Deliver to automatically create the Deliverfile for you based " +
19
- "on your current app? The app has to be in the App Store to use this feature. (y/n)", true)
20
-
21
- puts "\n\nFirst, you need to login with your iTunesConnect credentials. ".yellow +
22
- "\nThis is necessary to fetch the latest metadata from your app and use it to create a Deliverfile for you." +
23
- "\nIf you have previously entered your credentials already, you will not be asked again."
24
-
25
- if CredentialsManager::PasswordManager.shared_manager.username and CredentialsManager::PasswordManager.shared_manager.password
26
- identifier = ((CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier) rescue '') || '')
27
- while identifier.length < 3
28
- identifier = ask("\nApp Identifier of your app (e.g. com.krausefx.app_name): ")
29
- end
30
-
31
- self.create_based_on_identifier(deliver_path, identifier, project_name)
32
- else
33
- self.create_example_deliver_file(deliver_file_path, project_name)
34
- end
35
- else
36
- self.create_example_deliver_file(deliver_file_path, project_name)
37
- end
38
- end
39
-
40
- # This method is used, when the user does not want to automatically create the Deliverfile
41
- # @param path (String) The exact path (including the file name) in which the Deliverfile should be created
42
- # @param project_name (String) The default name of the project, which is used in the generated Deliverfile
43
- def self.create_example_deliver_file(path, project_name)
44
- gem_path = Helper.gem_path('deliver')
45
- example = File.read("#{gem_path}/lib/assets/DeliverfileExample")
46
- example.gsub!("[[APP_NAME]]", project_name)
47
- File.write(path, example)
48
-
49
- puts "Successfully created new Deliverfile at '#{path}'".green
50
- end
51
-
52
- # This will download all the app metadata and store its data into JSON files
53
- # @param deliver_path (String) The directory in which the Deliverfile should be created
54
- # @param identifier (String) The app identifier we want to create Deliverfile based on
55
- # @param project_name (String) The default name of the project, which is used in the generated Deliverfile
56
- def self.create_based_on_identifier(deliver_path, identifier, project_name)
57
- app = Deliver::App.new(app_identifier: identifier)
58
- app.set_metadata_directory("/tmp") # we don't want to pollute the current folder
59
- app.metadata # this will download the latest app metadata
60
-
61
- version_number = app.metadata.fetch_value("//x:version").first["string"] # fetch the latest app version
62
-
63
- file_path = File.join(deliver_path, Deliver::Deliverfile::Deliverfile::FILE_NAME)
64
- json = generate_deliver_file(app, deliver_path, project_name, version_number)
65
- File.write(file_path, json)
66
-
67
- FileUtils.mkdir_p File.join(deliver_path, 'screenshots')
68
- begin
69
- Helper.log.info "Downloading all previously used app screenshots.".green
70
- ItunesConnect.new.download_existing_screenshots(app, deliver_path)
71
- rescue Exception => ex
72
- Helper.log.error ex
73
- Helper.log.error "Couldn't download already existing screenshots from iTunesConnect. You have to add them manually!".red
74
- end
75
-
76
- # Add a README to the screenshots folder
77
- FileUtils.mkdir_p File.join(deliver_path, 'screenshots') # just in case the fetching didn't work
78
- File.write(File.join(deliver_path, 'screenshots', 'README.txt'), File.read("#{Helper.gem_path('deliver')}/lib/assets/ScreenshotsHelp"))
79
-
80
- Helper.log.info "Successfully created new Deliverfile".green
81
- end
82
-
83
- private
84
- # This method takes care of creating a new 'deliver' folder, containg the app metadata
85
- # and screenshots folders
86
- def self.generate_deliver_file(app, path, project_name, version_number)
87
- FileUtils.mkdir_p path rescue nil # never mind if it's already there
88
-
89
- json = create_json_based_on_xml(app, path)
90
-
91
- json.each do |language, value|
92
- folder = File.join(path, "metadata", language)
93
- FileUtils.mkdir_p(folder)
94
- value.each do |key, content|
95
- content = content.join("\n") if key == :keywords
96
- File.write(File.join(folder, "#{key}.txt"), content)
97
- end
98
- Helper.log.info "Successfully downloaded existing metadata for language #{language}"
99
- end
100
-
101
- puts "Successfully created new configuration files.".green
102
-
103
- gem_path = Helper.gem_path('deliver')
104
-
105
- # Generate the final Deliverfile here
106
- deliver = File.read("#{gem_path}/lib/assets/DeliverfileDefault")
107
- deliver.gsub!("[[APP_IDENTIFIER]]", app.app_identifier)
108
- deliver.gsub!("[[APP_NAME]]", project_name)
109
- deliver.gsub!("[[APPLE_ID]]", app.apple_id.to_s)
110
- deliver.gsub!("[[EMAIL]]", CredentialsManager::PasswordManager.shared_manager.username)
111
- deliver.gsub!("[[APP_VERSION]]", version_number)
112
-
113
- return deliver
114
- end
115
-
116
- # Access the app metadata and use them to create a finished Deliverfile
117
- def self.create_json_based_on_xml(app, path)
118
- json = {}
119
- # Access the app metadata and use them to create a finished Deliverfile
120
- app_name = app.metadata.information.each do |locale, current|
121
- current.each do |key, value|
122
- if value and value.kind_of?Hash # that does not apply for screenshots, which is an array
123
- current[key] = value[:value]
124
- else
125
- current.delete(key)
126
- end
127
- end
128
-
129
- json[locale] = current
130
- end
131
-
132
- return json
133
- end
134
- end
135
- end
@@ -1,142 +0,0 @@
1
- # Inspired by https://github.com/CocoaPods/Core/blob/master/lib/cocoapods-core/podfile/dsl.rb
2
- require 'credentials_manager/password_manager'
3
-
4
- module Deliver
5
- module Deliverfile
6
- class Deliverfile
7
- module DSL
8
- MISSING_VALUE_ERROR_MESSAGE = "You have to pass either a value or a block to the given method."
9
- SPECIFY_LANGUAGE_FOR_VALUE = "You have to specify the language of the given value. Either set a default language using 'default_language \"en-US\"' on the top of the file or pass a hash containing the language codes"
10
-
11
- MISSING_APP_IDENTIFIER_MESSAGE = "You have to pass a valid app identifier using the Deliver file. (e.g. 'app_identifier \"net.sunapps.app\"')"
12
- MISSING_VERSION_NUMBER_MESSAGE = "You have to pass a valid version number using the Deliver file. (e.g. 'version \"1.0\"')"
13
- INVALID_IPA_FILE_GIVEN = "The given ipa file seems to be wrong. Make sure it's a valid ipa file."
14
-
15
- class DeliverfileDSLError < StandardError
16
- end
17
-
18
- # Setting all the metadata
19
- def method_missing(method_sym, *arguments, &block)
20
- allowed = Deliver::Deliverer.all_available_keys_to_set
21
- not_translated = [:ipa, :app_identifier, :apple_id, :screenshots_path, :config_json_folder,
22
- :submit_further_information, :copyright, :primary_category, :secondary_category,
23
- :primary_subcategories, :secondary_subcategories,
24
- :automatic_release, :app_review_information, :ratings_config_path, :price_tier,
25
- :app_icon, :apple_watch_app_icon]
26
-
27
- if allowed.include?(method_sym)
28
- value = arguments.first
29
- value = block.call if (value == nil and block != nil)
30
-
31
- if value == nil
32
- Helper.log.error(caller)
33
- Helper.log.fatal("No value or block passed to method '#{method_sym}'")
34
- raise DeliverfileDSLError.new(MISSING_VALUE_ERROR_MESSAGE.red)
35
- end
36
-
37
- if (not value.kind_of?Hash) and (not not_translated.include?method_sym)
38
- # The user should pass a hash for multi-lang values
39
- # Maybe he at least set a default language
40
- if @default_language
41
- value = { @default_language => value }
42
- else
43
- raise DeliverfileDSLError.new(SPECIFY_LANGUAGE_FOR_VALUE.red)
44
- end
45
- end
46
-
47
- @deliver_data.set_new_value(method_sym, value)
48
- else
49
- # Check if it's a block (e.g. run tests)
50
- if Deliver::Deliverer.all_available_blocks_to_set.include?method_sym
51
- if block
52
- @deliver_data.set_new_block(method_sym, block)
53
- else
54
- raise DeliverfileDSLError.new("Value for #{method_sym} must be a Ruby block. Use '#{method_sym}' do ... end.".red)
55
- end
56
- else
57
- # Couldn't find this particular method
58
- Helper.log.error("Could not find method '#{method_sym}'. Available methods: #{allowed.collect { |a| a.to_s }}")
59
- end
60
- end
61
- end
62
-
63
- # This method can be used to set a default language, which is used
64
- # when passing a string to metadata changes, instead of a hash
65
- # containing multiple languages.
66
- #
67
- # This is approach only is recommend for deployments where you are only
68
- # supporting one language.
69
- #
70
- # The language itself must be included in {FastlaneCore::Languages::ALL_LANGUAGES}.
71
- # @example
72
- # default_language 'en-US'
73
- # @example
74
- # default_language 'de-DE'
75
- def default_language(value = nil)
76
- # Verify, default_language is on the top of the file
77
- already_set = @deliver_data.deliver_process.deploy_information
78
- minimum = (already_set[:skip_pdf] ? 4 : 3) # skip_pdf + blocks
79
- if already_set.count > minimum
80
- raise "'default_language' must be on the top of the Deliverfile.".red
81
- end
82
-
83
-
84
- @default_language = value
85
- @default_language ||= yield if block_given?
86
- Helper.log.debug("Set default language to #{@default_language}")
87
- @deliver_data.set_new_value(:default_language, @default_language)
88
- end
89
-
90
- # Pass the path to the ipa file which should be uploaded
91
- # @raise (DeliverfileDSLError) occurs when you pass an invalid path to the
92
- # IPA file.
93
- def ipa(value = nil, &block)
94
- DSL.validate_ipa!(value) if value # to catch errors early
95
-
96
- @deliver_data.set_new_value(Deliverer::ValKey::IPA, (value || block))
97
- end
98
-
99
- # Pass the path to the ipa file (beta version) which should be uploaded
100
- # @raise (DeliverfileDSLError) occurs when you pass an invalid path to the
101
- # IPA file.
102
- def beta_ipa(value = nil, &block)
103
- DSL.validate_ipa!(value) if value # to catch errors early
104
-
105
- @deliver_data.set_new_value(Deliverer::ValKey::BETA_IPA, (value || block))
106
- end
107
-
108
- # This will set the email address of the Apple ID to be used
109
- def email(value)
110
- value ||= yield if block_given?
111
- CredentialsManager::PasswordManager.logout # if it was logged in already (with fastlane)
112
- CredentialsManager::PasswordManager.shared_manager(value)
113
- end
114
-
115
- # This will hide the output of the iTunes Connect transporter while uploading/downloading
116
- def hide_transporter_output
117
- ItunesTransporter.hide_transporter_output
118
- end
119
-
120
- # Set the apps new version number.
121
- #
122
- # If you do not set this, it will automatically being fetched from the
123
- # IPA file.
124
- def version(value = nil)
125
- value ||= yield if block_given?
126
- raise DeliverfileDSLError.new(MISSING_VALUE_ERROR_MESSAGE.red) unless value
127
- raise DeliverfileDSLError.new("The app version should be a string".red) unless value.kind_of?(String)
128
-
129
- @deliver_data.set_new_value(Deliverer::ValKey::APP_VERSION, value)
130
- end
131
-
132
- # Only verifies the file type of the ipa path and if the file can be found. Is also called from deliver_process
133
- # This will raise a DeliverfileDSLError if something goes wrong
134
- def self.validate_ipa!(value)
135
- raise DeliverfileDSLError.new(INVALID_IPA_FILE_GIVEN.red) unless value
136
- raise DeliverfileDSLError.new(INVALID_IPA_FILE_GIVEN.red) unless value.kind_of?String
137
- raise DeliverfileDSLError.new(INVALID_IPA_FILE_GIVEN.red) unless value.include?".ipa"
138
- end
139
- end
140
- end
141
- end
142
- end