Class: FruityBuilder::IOS::Signing
Overview
Namespace for all methods encapsulating idevice calls
Constant Summary
Constants inherited
from Execution
Execution::COMMAND_RETRIES, Execution::COMMAND_TIMEOUT
Class Method Summary
collapse
Methods inherited from Execution
execute, execute_with_timeout_and_retry
Class Method Details
.enable_get_tasks(app_path) ⇒ Object
106
107
108
109
110
111
112
|
# File 'lib/fruity_builder/signing.rb', line 106
def self.enable_get_tasks(app_path)
entitlements = get_entitlements(app_path, raw: true)
return entitlements if entitlements.scan(/<key>get-task-allow<\/key>\\n.*<true\/>/).count > 0
entitlements.gsub('<false/>', '<true/>') if entitlements.scan(/<key>get-task-allow<\/key>\\n.*<false\/>/)
end
|
.get_entitlements(app_path, raw = false) ⇒ Object
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
# File 'lib/fruity_builder/signing.rb', line 89
def self.get_entitlements(app_path, raw = false)
app_path = unpack_ipa(app_path) if is_ipa?(app_path)
result = execute("codesign -d --entitlements - #{app_path}")
if result.exit != 0
raise SigningCommandError.new(result.stderr)
end
xml = result.stdout.to_s.encode('UTF-8', 'UTF-8', invalid: :replace)
xml = xml[xml.index('<')..xml.length]
return xml if raw
entitlements = Plistutil.parse_xml(xml)
return entitlements
end
|
.get_signing_certs ⇒ Object
75
76
77
78
79
80
81
82
83
84
85
86
87
|
# File 'lib/fruity_builder/signing.rb', line 75
def self.get_signing_certs
result = execute('security find-identity -p codesigning -v')
raise SigningCommandError.new(result.stderr) if result.exit != 0
certs = []
result.stdout.split("\n").each do |line|
if /\)\s*(\S*)\s*"(.*)"/.match(line)
certs << { id: Regexp.last_match[1], name: Regexp.last_match[2] }
end
end
certs
end
|
.is_app_signed?(app_path) ⇒ Boolean
28
29
30
31
32
33
34
35
36
37
38
|
# File 'lib/fruity_builder/signing.rb', line 28
def self.is_app_signed?(app_path)
app_path = unpack_ipa(app_path) if is_ipa?(app_path)
result = execute("codesign -d -vvvv '#{app_path}'")
if result.exit != 0
return false if /is not signed/.match(result.stderr)
raise SigningCommandError.new(result.stderr)
end
true
end
|
.is_ipa?(path) ⇒ Boolean
Check to see if the path is an IPA
10
11
12
13
|
# File 'lib/fruity_builder/signing.rb', line 10
def self.is_ipa?(path)
return true if (File.extname path).downcase == '.ipa'
false
end
|
.sign_app(options = {}) ⇒ Object
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
# File 'lib/fruity_builder/signing.rb', line 40
def self.sign_app(options = {})
cert = options[:cert]
entitlements = options[:entitlements]
app = options[:app]
original_app = nil
if is_ipa?(app)
original_app = app
app = unpack_ipa(app)
end
command = "codesign --force --sign '#{cert}'"
unless File.exists?(entitlements)
file = Tempfile.new('entitlements')
file.write(entitlements)
file.close
entitlements = file.path
command = command + " --entitlements #{entitlements}"
end
result = execute(command + " '#{app}'")
raise SigningCommandError.new(result.stderr) if result.exit != 0
zip_app(app, original_app) if original_app
end
|
.unpack_ipa(path) ⇒ Object
15
16
17
18
19
20
21
22
23
24
25
26
|
# File 'lib/fruity_builder/signing.rb', line 15
def self.unpack_ipa(path)
folder = File.dirname(path)
target = (File.basename path, (File.extname path))
return Dir["#{folder}/#{target}/Payload/*.app"].first if File.exists? ("#{folder}/#{target}/Payload/")
result = execute("unzip '#{path}' -d '#{folder}/#{target}'")
raise SigningCommandError.new(result.stderr) if result.exit != 0
Dir["#{folder}/#{target}/Payload/*.app"].first
end
|
.zip_app(payload_path, ipa_path) ⇒ Object
68
69
70
71
72
73
|
# File 'lib/fruity_builder/signing.rb', line 68
def self.zip_app(payload_path, ipa_path)
result = execute("cd #{File.dirname(payload_path)}; zip -r #{ipa_path} ../Payload ")
raise SigningCommandError.new(result.stderr) if result.exit != 0
true
end
|