fastlane_core 0.9.2 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/fastlane_core.rb +2 -0
- data/lib/fastlane_core/ipa_file_analyser.rb +46 -0
- data/lib/fastlane_core/itunes_transporter.rb +208 -0
- data/lib/fastlane_core/update_checker.rb +35 -28
- data/lib/fastlane_core/version.rb +1 -1
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f8b0ac651f60fbd9ab9eda7a9842a524de056726
|
4
|
+
data.tar.gz: 25b61598ef0442e59fb1f3356f1ef9935dd8a780
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 12022fab57b9c45321648fbe1493e59ed605829af2bd75eb3067f32ad5b37e834cd3f74baef12c95164f9f8cccf39ffe58c83df9f955ce33c9a524f30e8ec6b4
|
7
|
+
data.tar.gz: a53ebc857fead387a86b07385772121d705f77ce929513bcfc74a2c9df9bec5ceee30b052f622507520c144b8ed37b6b3cdb79493c2def2f7ed0bac8ff778e17
|
data/lib/fastlane_core.rb
CHANGED
@@ -6,6 +6,8 @@ require 'fastlane_core/update_checker'
|
|
6
6
|
require 'fastlane_core/languages'
|
7
7
|
require 'fastlane_core/itunes_search_api'
|
8
8
|
require 'fastlane_core/cert_checker'
|
9
|
+
require 'fastlane_core/ipa_file_analyser'
|
10
|
+
require 'fastlane_core/itunes_transporter'
|
9
11
|
|
10
12
|
# Third Party code
|
11
13
|
require 'colored'
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'zip'
|
2
|
+
|
3
|
+
module FastlaneCore
|
4
|
+
class IpaFileAnalyser
|
5
|
+
|
6
|
+
# Fetches the app identifier (e.g. com.facebook.Facebook) from the given ipa file.
|
7
|
+
def self.fetch_app_identifier(path)
|
8
|
+
plist = IpaFileAnalyser.fetch_info_plist_file(path)
|
9
|
+
return plist['CFBundleIdentifier'] if plist
|
10
|
+
return nil
|
11
|
+
end
|
12
|
+
|
13
|
+
# Fetches the app version from the given ipa file.
|
14
|
+
def self.fetch_app_version(path)
|
15
|
+
plist = IpaFileAnalyser.fetch_info_plist_file(path)
|
16
|
+
return plist['CFBundleShortVersionString'] if plist
|
17
|
+
return nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.fetch_info_plist_file(path)
|
21
|
+
Zip::File.open(path) do |zipfile|
|
22
|
+
zipfile.each do |file|
|
23
|
+
if file.name.include?'.plist' and not ['.bundle', '.framework'].any? { |a| file.name.include?a }
|
24
|
+
# We can not be completely sure, that's the correct plist file, so we have to try
|
25
|
+
begin
|
26
|
+
# The XML file has to be properly unpacked first
|
27
|
+
tmp_path = "/tmp/deploytmp.plist"
|
28
|
+
File.write(tmp_path, zipfile.read(file))
|
29
|
+
system("plutil -convert xml1 #{tmp_path}")
|
30
|
+
result = Plist::parse_xml(tmp_path)
|
31
|
+
File.delete(tmp_path)
|
32
|
+
|
33
|
+
if result['CFBundleIdentifier'] or result['CFBundleVersion']
|
34
|
+
return result
|
35
|
+
end
|
36
|
+
rescue
|
37
|
+
# We don't really care, look for another XML file
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
require 'pty'
|
2
|
+
require 'shellwords'
|
3
|
+
require 'credentials_manager/password_manager'
|
4
|
+
|
5
|
+
|
6
|
+
module FastlaneCore
|
7
|
+
# The TransporterInputError occurs when you passed wrong inputs to the {Deliver::ItunesTransporter}
|
8
|
+
class TransporterInputError < StandardError
|
9
|
+
end
|
10
|
+
# The TransporterTransferError occurs when some error happens
|
11
|
+
# while uploading or downloading something from/to iTC
|
12
|
+
class TransporterTransferError < StandardError
|
13
|
+
end
|
14
|
+
|
15
|
+
class ItunesTransporter
|
16
|
+
ERROR_REGEX = />\s*ERROR:\s+(.+)/
|
17
|
+
WARNING_REGEX = />\s*WARN:\s+(.+)/
|
18
|
+
OUTPUT_REGEX = />\s+(.+)/
|
19
|
+
RETURN_VALUE_REGEX = />\sDBG-X:\sReturning\s+(\d+)/
|
20
|
+
|
21
|
+
SKIP_ERRORS = [ "ERROR: An exception has occurred: Scheduling automatic restart in 1 minute" ]
|
22
|
+
|
23
|
+
private_constant :ERROR_REGEX, :WARNING_REGEX, :OUTPUT_REGEX, :RETURN_VALUE_REGEX, :SKIP_ERRORS
|
24
|
+
|
25
|
+
# This will be called from the Deliverfile, and disables the logging of the transporter output
|
26
|
+
def self.hide_transporter_output
|
27
|
+
@@hide_transporter_output = true
|
28
|
+
|
29
|
+
@@hide_transporter_output = false if $verbose
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns a new instance of the iTunesTransporter.
|
33
|
+
# If no username or password given, it will be taken from
|
34
|
+
# the #{CredentialsManager::PasswordManager}
|
35
|
+
def initialize(user = nil, password = nil)
|
36
|
+
@user = (user || CredentialsManager::PasswordManager.shared_manager.username)
|
37
|
+
@password = (password || CredentialsManager::PasswordManager.shared_manager.password)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Downloads the latest version of the app metadata package from iTC.
|
41
|
+
# @param app_id [Integer] The unique App ID
|
42
|
+
# @param dir [String] the path in which the package file should be stored
|
43
|
+
# @return (Bool) True if everything worked fine
|
44
|
+
# @raise [Deliver::TransporterTransferError] when something went wrong
|
45
|
+
# when transfering
|
46
|
+
def download(app_id, dir = nil)
|
47
|
+
dir ||= "/tmp"
|
48
|
+
|
49
|
+
Helper.log.info "Going to download app metadata from iTunesConnect"
|
50
|
+
command = build_download_command(@user, @password, app_id, dir)
|
51
|
+
Helper.log.debug build_download_command(@user, 'YourPassword', app_id, dir) if $verbose
|
52
|
+
|
53
|
+
result = execute_transporter(command)
|
54
|
+
|
55
|
+
itmsp_path = File.join(dir, "#{app_id}.itmsp")
|
56
|
+
if result and File.directory?itmsp_path
|
57
|
+
Helper.log.info "Successfully downloaded the latest package from iTunesConnect.".green
|
58
|
+
else
|
59
|
+
unless /^[0-9a-zA-Z\.\$\_]*$/ === @password
|
60
|
+
Helper.log.error "Password contains special characters, which may not be handled properly by iTMSTransporter. If you experience problems uploading to iTunes Connect, please consider changing your password to something with only alphanumeric characters."
|
61
|
+
end
|
62
|
+
Helper.log.fatal "Could not download metadata from iTunes Connect! It's probably related to your password or your internet connection."
|
63
|
+
end
|
64
|
+
|
65
|
+
result
|
66
|
+
end
|
67
|
+
|
68
|
+
# Uploads the modified package back to iTunesConnect
|
69
|
+
# @param app_id [Integer] The unique App ID
|
70
|
+
# @param dir [String] the path in which the package file is located
|
71
|
+
# @return (Bool) True if everything worked fine
|
72
|
+
# @raise [Deliver::TransporterTransferError] when something went wrong
|
73
|
+
# when transfering
|
74
|
+
def upload(app_id, dir)
|
75
|
+
dir = File.join(dir, "#{app_id}.itmsp")
|
76
|
+
|
77
|
+
Helper.log.info "Going to upload updated app to iTunesConnect"
|
78
|
+
Helper.log.info "This might take a few minutes, please don't interrupt the script".green
|
79
|
+
|
80
|
+
command = build_upload_command(@user, @password, dir)
|
81
|
+
Helper.log.debug build_upload_command(@user, 'YourPassword', dir) if $verbose
|
82
|
+
|
83
|
+
result = execute_transporter(command)
|
84
|
+
|
85
|
+
if result
|
86
|
+
Helper.log.info(("-" * 102).green)
|
87
|
+
Helper.log.info("Successfully uploaded package to iTunesConnect. It might take a few minutes until it's visible online.".green)
|
88
|
+
Helper.log.info(("-" * 102).green)
|
89
|
+
|
90
|
+
FileUtils.rm_rf(dir) unless Helper.is_test? # we don't need the package any more, since the upload was successful
|
91
|
+
end
|
92
|
+
|
93
|
+
result
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
def execute_transporter(command)
|
98
|
+
@errors = []
|
99
|
+
@warnings = []
|
100
|
+
|
101
|
+
if defined?@@hide_transporter_output
|
102
|
+
# Show a one time message instead
|
103
|
+
Helper.log.info "Waiting for iTunes Connect transporter to be finished.".green
|
104
|
+
Helper.log.info "iTunes Transporter progress... this might take a few minutes...".green
|
105
|
+
end
|
106
|
+
|
107
|
+
begin
|
108
|
+
PTY.spawn(command) do |stdin, stdout, pid|
|
109
|
+
stdin.each do |line|
|
110
|
+
parse_line(line) # this is where the parsing happens
|
111
|
+
end
|
112
|
+
end
|
113
|
+
rescue => ex
|
114
|
+
Helper.log.fatal(ex.to_s)
|
115
|
+
@errors << ex.to_s
|
116
|
+
end
|
117
|
+
|
118
|
+
if @warnings.count > 0
|
119
|
+
Helper.log.warn(@warnings.join("\n"))
|
120
|
+
end
|
121
|
+
|
122
|
+
if @errors.count > 0
|
123
|
+
Helper.log.error(@errors.join("\n"))
|
124
|
+
return false
|
125
|
+
end
|
126
|
+
|
127
|
+
true
|
128
|
+
end
|
129
|
+
|
130
|
+
def parse_line(line)
|
131
|
+
# Taken from https://github.com/sshaw/itunes_store_transporter/blob/master/lib/itunes/store/transporter/output_parser.rb
|
132
|
+
|
133
|
+
output_done = false
|
134
|
+
|
135
|
+
re = Regexp.union(SKIP_ERRORS)
|
136
|
+
if line.match(re)
|
137
|
+
# Those lines will not be handle like errors or warnings
|
138
|
+
|
139
|
+
elsif line =~ ERROR_REGEX
|
140
|
+
@errors << $1
|
141
|
+
Helper.log.error "[Transporter Error Output]: #{$1}".red
|
142
|
+
|
143
|
+
# Check if it's a login error
|
144
|
+
if $1.include?"Your Apple ID or password was entered incorrectly" or
|
145
|
+
$1.include?"This Apple ID has been locked for security reasons"
|
146
|
+
|
147
|
+
CredentialsManager::PasswordManager.shared_manager.password_seems_wrong unless Helper.is_test?
|
148
|
+
elsif $1.include?"Redundant Binary Upload. There already exists a binary upload with build"
|
149
|
+
Helper.log.fatal $1
|
150
|
+
Helper.log.fatal "You have to change the build number of your app to upload your ipa file"
|
151
|
+
end
|
152
|
+
|
153
|
+
output_done = true
|
154
|
+
elsif line =~ WARNING_REGEX
|
155
|
+
@warnings << $1
|
156
|
+
Helper.log.warn "[Transporter Warning Output]: #{$1}".yellow
|
157
|
+
output_done = true
|
158
|
+
end
|
159
|
+
|
160
|
+
if line =~ RETURN_VALUE_REGEX
|
161
|
+
if $1.to_i != 0
|
162
|
+
Helper.log.fatal "Transporter transfer failed.".red
|
163
|
+
Helper.log.warn(@warnings.join("\n").yellow)
|
164
|
+
Helper.log.error(@errors.join("\n").red)
|
165
|
+
raise "Return status of iTunes Transporter was #{$1}: #{@errors.join('\n')}".red
|
166
|
+
else
|
167
|
+
Helper.log.info "iTunes Transporter successfully finished its job".green
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
if not defined?@@hide_transporter_output and line =~ OUTPUT_REGEX
|
172
|
+
# General logging for debug purposes
|
173
|
+
unless output_done
|
174
|
+
Helper.log.debug "[Transporter]: #{$1}"
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def build_download_command(username, password, apple_id, destination = "/tmp")
|
180
|
+
[
|
181
|
+
'"' + Helper.transporter_path + '"',
|
182
|
+
"-m lookupMetadata",
|
183
|
+
"-u \"#{username}\"",
|
184
|
+
"-p '#{escaped_password(password)}'",
|
185
|
+
"-apple_id #{apple_id}",
|
186
|
+
"-destination '#{destination}'"
|
187
|
+
].join(' ')
|
188
|
+
end
|
189
|
+
|
190
|
+
def build_upload_command(username, password, source = "/tmp")
|
191
|
+
[
|
192
|
+
'"' + Helper.transporter_path + '"',
|
193
|
+
"-m upload",
|
194
|
+
"-u \"#{username}\"",
|
195
|
+
"-p '#{escaped_password(password)}'",
|
196
|
+
"-f '#{source}'",
|
197
|
+
ENV["DELIVER_ITMSTRANSPORTER_ADDITIONAL_UPLOAD_PARAMETERS"], # that's here, because the user might overwrite the -t option
|
198
|
+
"-t 'Signiant'",
|
199
|
+
"-k 100000"
|
200
|
+
].join(' ')
|
201
|
+
end
|
202
|
+
|
203
|
+
def escaped_password(password)
|
204
|
+
Shellwords.escape(password)
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|
208
|
+
end
|
@@ -1,15 +1,16 @@
|
|
1
|
-
require '
|
1
|
+
require 'excon'
|
2
2
|
|
3
3
|
module FastlaneCore
|
4
4
|
# Verifies, the user runs the latest version of this gem
|
5
5
|
class UpdateChecker
|
6
|
-
|
7
6
|
# This web service is fully open source: https://github.com/fastlane/refresher
|
8
7
|
UPDATE_URL = "https://fastlane-refresher.herokuapp.com/"
|
9
8
|
|
10
9
|
def self.start_looking_for_update(gem_name)
|
11
10
|
return if Helper.is_test?
|
12
11
|
return if ENV["FASTLANE_SKIP_UPDATE_CHECK"]
|
12
|
+
|
13
|
+
@start_time = Time.now
|
13
14
|
|
14
15
|
Thread.new do
|
15
16
|
begin
|
@@ -19,15 +20,32 @@ module FastlaneCore
|
|
19
20
|
end
|
20
21
|
end
|
21
22
|
|
22
|
-
def self.
|
23
|
+
def self.server_results
|
24
|
+
@@results ||= {}
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.update_available?(gem_name, current_version)
|
23
28
|
latest = server_results[gem_name]
|
24
|
-
|
25
|
-
|
29
|
+
return (latest and Gem::Version.new(latest) > Gem::Version.new(current_version))
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.show_update_status(gem_name, current_version)
|
33
|
+
t = Thread.new do
|
34
|
+
begin
|
35
|
+
finished_running(gem_name)
|
36
|
+
rescue
|
37
|
+
end
|
26
38
|
end
|
39
|
+
|
40
|
+
if update_available?(gem_name, current_version)
|
41
|
+
show_update_message(gem_name, current_version)
|
42
|
+
end
|
43
|
+
|
44
|
+
t.join(3)
|
27
45
|
end
|
28
46
|
|
29
|
-
def self.show_update_message(gem_name,
|
30
|
-
|
47
|
+
def self.show_update_message(gem_name, current_version)
|
48
|
+
available = server_results[gem_name]
|
31
49
|
puts ""
|
32
50
|
puts '#######################################################################'.green
|
33
51
|
puts "# #{gem_name} #{available} is available. You are on #{current_version}.".green
|
@@ -37,30 +55,19 @@ module FastlaneCore
|
|
37
55
|
puts '#######################################################################'.green
|
38
56
|
end
|
39
57
|
|
40
|
-
def self.server_results
|
41
|
-
@@results ||= {}
|
42
|
-
end
|
43
|
-
|
44
|
-
# Legacy Code:
|
45
|
-
#
|
46
|
-
# Is a new official release available (this does not include pre-releases)
|
47
|
-
def self.update_available?(gem_name, current_version)
|
48
|
-
begin
|
49
|
-
latest = fetch_latest(gem_name)
|
50
|
-
if latest and Gem::Version.new(latest) > Gem::Version.new(current_version)
|
51
|
-
return true
|
52
|
-
end
|
53
|
-
rescue => ex
|
54
|
-
Helper.log.error("Could not check if '#{gem_name}' is up to date.")
|
55
|
-
end
|
56
|
-
return false
|
57
|
-
end
|
58
|
-
|
59
|
-
# Relevant code
|
60
58
|
def self.fetch_latest(gem_name)
|
61
59
|
url = UPDATE_URL + gem_name
|
62
60
|
url += "?ci=1" if Helper.is_ci?
|
63
|
-
JSON.parse(
|
61
|
+
JSON.parse(Excon.post(url).body).fetch("version", nil)
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.finished_running(gem_name)
|
65
|
+
time = (Time.now - @start_time).to_i
|
66
|
+
|
67
|
+
url = UPDATE_URL + "time/#{gem_name}"
|
68
|
+
url += "?time=#{time}"
|
69
|
+
url += "&ci=1" if Helper.is_ci?
|
70
|
+
output = Excon.post(url)
|
64
71
|
end
|
65
72
|
end
|
66
73
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fastlane_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Felix Krause
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-07-
|
11
|
+
date: 2015-07-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -108,6 +108,20 @@ dependencies:
|
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: 0.45.0
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rubyzip
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 1.1.6
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 1.1.6
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
126
|
name: credentials_manager
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -280,11 +294,13 @@ files:
|
|
280
294
|
- lib/fastlane_core/developer_center/developer_center_helper.rb
|
281
295
|
- lib/fastlane_core/developer_center/developer_center_login.rb
|
282
296
|
- lib/fastlane_core/helper.rb
|
297
|
+
- lib/fastlane_core/ipa_file_analyser.rb
|
283
298
|
- lib/fastlane_core/itunes_connect/itunes_connect.rb
|
284
299
|
- lib/fastlane_core/itunes_connect/itunes_connect_apple_id.rb
|
285
300
|
- lib/fastlane_core/itunes_connect/itunes_connect_helper.rb
|
286
301
|
- lib/fastlane_core/itunes_connect/itunes_connect_login.rb
|
287
302
|
- lib/fastlane_core/itunes_search_api.rb
|
303
|
+
- lib/fastlane_core/itunes_transporter.rb
|
288
304
|
- lib/fastlane_core/languages.rb
|
289
305
|
- lib/fastlane_core/update_checker.rb
|
290
306
|
- lib/fastlane_core/version.rb
|