fastlane-plugin-ipa_info 0.7.0 → 0.8.0
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.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0d02632c59b5d057a6227def1bc12cc69deb3f0c5a05b9448cd034675d12ce9a
|
|
4
|
+
data.tar.gz: aa464bb64612797248568cfc0ba704150dc59d9fc9872781c92e1ac6147545c6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9c23edd1aef4d7ee8364747f40ae35f12ce7ba6002e0b35855991a55535af4d69f8c5a6d9925ab7843e8895ec0c8b331de5198505865ac5ba17e54a5621b29a4
|
|
7
|
+
data.tar.gz: bb96ff38f13fe7b0767292e8d944a9191909667a4636634b6cafa58c21a2b711980a9ee74633e5b07f30b0db6c5fad6ac343701b2758733f08b0375546544ce2
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
require 'tempfile'
|
|
2
2
|
require 'tmpdir'
|
|
3
|
-
require 'zip'
|
|
4
|
-
require 'zip/filesystem'
|
|
5
3
|
require 'fileutils'
|
|
6
4
|
require 'plist'
|
|
7
5
|
require 'open3'
|
|
@@ -11,34 +9,29 @@ module Fastlane
|
|
|
11
9
|
module Helper
|
|
12
10
|
class IpaAnalyzeHelper
|
|
13
11
|
def self.analyze(ipa_path)
|
|
14
|
-
ipa_zipfile = Zip::File.open(ipa_path)
|
|
15
12
|
app_folder_path = find_app_folder_path_in_ipa(ipa_path)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
# file path
|
|
19
|
-
mobileprovision_entry = ipa_zipfile.find_entry("#{app_folder_path}/embedded.mobileprovision")
|
|
20
|
-
UI.user_error!("mobileprovision not found in #{ipa_path}") unless mobileprovision_entry
|
|
21
|
-
info_plist_entry = ipa_zipfile.find_entry("#{app_folder_path}/Info.plist")
|
|
22
|
-
UI.user_error!("Info.plist not found in #{ipa_path}") unless info_plist_entry
|
|
13
|
+
plist_data = self.fetch_file_with_unzip(ipa_path, "#{app_folder_path}/Info.plist")
|
|
14
|
+
mobileprovisioning_data = self.fetch_file_with_unzip(ipa_path, "#{app_folder_path}/embedded.mobileprovision")
|
|
23
15
|
|
|
24
16
|
return {
|
|
25
|
-
provisiong_info: self.analyze_mobileprovisioning(
|
|
26
|
-
plist_info: self.analyze_info_plist(
|
|
27
|
-
certificate_info: self.codesigned(
|
|
17
|
+
provisiong_info: self.analyze_mobileprovisioning(mobileprovisioning_data),
|
|
18
|
+
plist_info: self.analyze_info_plist(plist_data),
|
|
19
|
+
certificate_info: self.codesigned(ipa_path, app_folder_path)
|
|
28
20
|
}
|
|
29
21
|
end
|
|
30
22
|
|
|
31
23
|
# Info plist
|
|
32
|
-
def self.analyze_info_plist(
|
|
24
|
+
def self.analyze_info_plist(data)
|
|
25
|
+
tempfile = Tempfile.new(::File.basename("info_plist"))
|
|
33
26
|
result = {}
|
|
34
27
|
|
|
35
|
-
tempfile = Tempfile.new(::File.basename(info_plist_entry.name))
|
|
36
28
|
begin
|
|
37
|
-
|
|
29
|
+
File.open(tempfile.path, 'w') do |output|
|
|
30
|
+
output.puts(data)
|
|
31
|
+
end
|
|
38
32
|
UI.user_error!("Failed to convert binary Plist to XML") unless system("plutil -convert xml1 '#{tempfile.path}'")
|
|
39
33
|
|
|
40
34
|
plist = Plist.parse_xml(tempfile.path)
|
|
41
|
-
|
|
42
35
|
plist.each do |key, value|
|
|
43
36
|
parse_value = value.class == Hash || value.class == Array ? value : value.to_s
|
|
44
37
|
|
|
@@ -49,18 +42,20 @@ module Fastlane
|
|
|
49
42
|
ensure
|
|
50
43
|
tempfile.close && tempfile.unlink
|
|
51
44
|
end
|
|
52
|
-
|
|
45
|
+
|
|
46
|
+
result
|
|
53
47
|
end
|
|
54
48
|
|
|
55
49
|
# mobileprovisioning
|
|
56
|
-
def self.analyze_mobileprovisioning(
|
|
50
|
+
def self.analyze_mobileprovisioning(data)
|
|
51
|
+
tempfile = Tempfile.new(::File.basename("mobile_provisioning"))
|
|
57
52
|
result = {}
|
|
58
53
|
|
|
59
|
-
tempfile = Tempfile.new(::File.basename(mobileprovision_entry.name))
|
|
60
54
|
begin
|
|
61
|
-
|
|
55
|
+
File.open(tempfile.path, 'w') do |output|
|
|
56
|
+
output.puts(data)
|
|
57
|
+
end
|
|
62
58
|
mobileprovisioning = Plist.parse_xml(`security cms -D -i #{tempfile.path}`)
|
|
63
|
-
|
|
64
59
|
mobileprovisioning.each do |key, value|
|
|
65
60
|
next if key == 'DeveloperCertificates'
|
|
66
61
|
|
|
@@ -73,33 +68,49 @@ module Fastlane
|
|
|
73
68
|
ensure
|
|
74
69
|
tempfile.close && tempfile.unlink
|
|
75
70
|
end
|
|
76
|
-
|
|
71
|
+
|
|
72
|
+
result
|
|
77
73
|
end
|
|
78
74
|
|
|
79
75
|
# certificate
|
|
80
|
-
def self.codesigned(
|
|
81
|
-
result = {}
|
|
76
|
+
def self.codesigned(ipa_path, app_folder_path)
|
|
82
77
|
tempdir = Dir.pwd + "/tmp"
|
|
78
|
+
result = {}
|
|
83
79
|
|
|
84
80
|
begin
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
end
|
|
81
|
+
_, error, = Open3.capture3("unzip -d #{tempdir} #{ipa_path}")
|
|
82
|
+
UI.user_error!(error) unless error.empty?
|
|
88
83
|
|
|
89
|
-
|
|
90
|
-
cmd = "codesign -dv #{app_path}"
|
|
84
|
+
cmd = "codesign -dv #{tempdir}/#{app_folder_path}"
|
|
91
85
|
_stdout, stderr, _status = Open3.capture3(cmd)
|
|
92
86
|
codesigned_flag = stderr.include?("Signed Time")
|
|
93
|
-
|
|
94
87
|
result["CodeSigned"] = codesigned_flag
|
|
95
88
|
rescue StandardError => e
|
|
96
89
|
UI.user_error!(e.message)
|
|
97
90
|
ensure
|
|
98
91
|
FileUtils.rm_r(tempdir)
|
|
99
92
|
end
|
|
93
|
+
|
|
100
94
|
return result
|
|
101
95
|
end
|
|
102
96
|
|
|
97
|
+
# extract file
|
|
98
|
+
def self.fetch_file_with_unzip(path, target_file)
|
|
99
|
+
list, error, = Open3.capture3("unzip", "-Z", "-1", path)
|
|
100
|
+
UI.user_error!(error) unless error.empty?
|
|
101
|
+
|
|
102
|
+
return nil if list.empty?
|
|
103
|
+
entry = list.chomp.split("\n").find do |e|
|
|
104
|
+
File.fnmatch(target_file, e, File::FNM_PATHNAME)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
data, error, = Open3.capture3("unzip", "-p", path, entry)
|
|
108
|
+
UI.user_error!(error) unless error.empty?
|
|
109
|
+
UI.user_error!("not exits data for #{target_file}") if data.empty?
|
|
110
|
+
|
|
111
|
+
data
|
|
112
|
+
end
|
|
113
|
+
|
|
103
114
|
# return app folder path
|
|
104
115
|
def self.find_app_folder_path_in_ipa(ipa_path)
|
|
105
116
|
return "Payload/#{File.basename(ipa_path, File.extname(ipa_path))}.app"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fastlane-plugin-ipa_info
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- tarappo
|
|
@@ -30,26 +30,6 @@ dependencies:
|
|
|
30
30
|
- - "~>"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
32
|
version: '3.1'
|
|
33
|
-
- !ruby/object:Gem::Dependency
|
|
34
|
-
name: rubyzip
|
|
35
|
-
requirement: !ruby/object:Gem::Requirement
|
|
36
|
-
requirements:
|
|
37
|
-
- - "~>"
|
|
38
|
-
- !ruby/object:Gem::Version
|
|
39
|
-
version: '1.1'
|
|
40
|
-
- - ">="
|
|
41
|
-
- !ruby/object:Gem::Version
|
|
42
|
-
version: 1.1.7
|
|
43
|
-
type: :runtime
|
|
44
|
-
prerelease: false
|
|
45
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
46
|
-
requirements:
|
|
47
|
-
- - "~>"
|
|
48
|
-
- !ruby/object:Gem::Version
|
|
49
|
-
version: '1.1'
|
|
50
|
-
- - ">="
|
|
51
|
-
- !ruby/object:Gem::Version
|
|
52
|
-
version: 1.1.7
|
|
53
33
|
- !ruby/object:Gem::Dependency
|
|
54
34
|
name: mac_ios_info
|
|
55
35
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -201,7 +181,6 @@ files:
|
|
|
201
181
|
- lib/fastlane/plugin/ipa_info.rb
|
|
202
182
|
- lib/fastlane/plugin/ipa_info/actions/ipa_info_action.rb
|
|
203
183
|
- lib/fastlane/plugin/ipa_info/helper/ipa_analyze_helper.rb
|
|
204
|
-
- lib/fastlane/plugin/ipa_info/helper/ipa_analyze_helper2.rb
|
|
205
184
|
- lib/fastlane/plugin/ipa_info/helper/ipa_info_helper.rb
|
|
206
185
|
- lib/fastlane/plugin/ipa_info/version.rb
|
|
207
186
|
homepage: https://github.com/tarappo/fastlane-plugin-ipa_info
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
require 'tempfile'
|
|
2
|
-
require 'tmpdir'
|
|
3
|
-
require 'zip'
|
|
4
|
-
require 'zip/filesystem'
|
|
5
|
-
require 'fileutils'
|
|
6
|
-
require 'plist'
|
|
7
|
-
require 'open3'
|
|
8
|
-
require 'fastlane_core/ui/ui'
|
|
9
|
-
|
|
10
|
-
module Fastlane
|
|
11
|
-
module Helper
|
|
12
|
-
class IpaAnalyzeHelper2
|
|
13
|
-
def self.analyze(ipa_path)
|
|
14
|
-
app_folder_path = find_app_folder_path_in_ipa(ipa_path)
|
|
15
|
-
plist_data = self.fetch_file_with_unzip(ipa_path, "#{app_folder_path}/Info.plist")
|
|
16
|
-
mobileprovisioning_data = self.fetch_file_with_unzip(ipa_path, "#{app_folder_path}/embedded.mobileprovision")
|
|
17
|
-
|
|
18
|
-
return {
|
|
19
|
-
provisiong_info: self.analyze_mobileprovisioning(mobileprovisioning_data),
|
|
20
|
-
plist_info: self.analyze_info_plist(plist_data),
|
|
21
|
-
certificate_info: self.codesigned(ipa_path, app_folder_path)
|
|
22
|
-
}
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# Info plist
|
|
26
|
-
def self.analyze_info_plist(data)
|
|
27
|
-
tempfile = Tempfile.new(::File.basename("info_plist"))
|
|
28
|
-
result = {}
|
|
29
|
-
|
|
30
|
-
begin
|
|
31
|
-
File.open(tempfile.path, 'w') do |output|
|
|
32
|
-
output.puts(data)
|
|
33
|
-
end
|
|
34
|
-
UI.user_error!("Failed to convert binary Plist to XML") unless system("plutil -convert xml1 '#{tempfile.path}'")
|
|
35
|
-
|
|
36
|
-
plist = Plist.parse_xml(tempfile.path)
|
|
37
|
-
plist.each do |key, value|
|
|
38
|
-
parse_value = value.class == Hash || value.class == Array ? value : value.to_s
|
|
39
|
-
|
|
40
|
-
result[key] = parse_value
|
|
41
|
-
end
|
|
42
|
-
rescue StandardError => e
|
|
43
|
-
UI.user_error!(e.message)
|
|
44
|
-
ensure
|
|
45
|
-
tempfile.close && tempfile.unlink
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
result
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
# mobileprovisioning
|
|
52
|
-
def self.analyze_mobileprovisioning(data)
|
|
53
|
-
tempfile = Tempfile.new(::File.basename("mobile_provisioning"))
|
|
54
|
-
result = {}
|
|
55
|
-
|
|
56
|
-
begin
|
|
57
|
-
File.open(tempfile.path, 'w') do |output|
|
|
58
|
-
output.puts(data)
|
|
59
|
-
end
|
|
60
|
-
mobileprovisioning = Plist.parse_xml(`security cms -D -i #{tempfile.path}`)
|
|
61
|
-
mobileprovisioning.each do |key, value|
|
|
62
|
-
next if key == 'DeveloperCertificates'
|
|
63
|
-
|
|
64
|
-
parse_value = value.class == Hash || value.class == Array ? value : value.to_s
|
|
65
|
-
|
|
66
|
-
result[key] = parse_value
|
|
67
|
-
end
|
|
68
|
-
rescue StandardError => e
|
|
69
|
-
UI.user_error!(e.message)
|
|
70
|
-
ensure
|
|
71
|
-
tempfile.close && tempfile.unlink
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
result
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
# certificate
|
|
78
|
-
def self.codesigned(ipa_path, app_folder_path)
|
|
79
|
-
tempdir = Dir.pwd + "/tmp"
|
|
80
|
-
result = {}
|
|
81
|
-
|
|
82
|
-
begin
|
|
83
|
-
data, error, = Open3.capture3("unzip -d #{tempdir} #{ipa_path}")
|
|
84
|
-
|
|
85
|
-
cmd = "codesign -dv #{tempdir}/#{app_folder_path}"
|
|
86
|
-
_stdout, stderr, _status = Open3.capture3(cmd)
|
|
87
|
-
codesigned_flag = stderr.include?("Signed Time")
|
|
88
|
-
result["CodeSigned"] = codesigned_flag
|
|
89
|
-
rescue StandardError => e
|
|
90
|
-
UI.user_error!(e.message)
|
|
91
|
-
ensure
|
|
92
|
-
FileUtils.rm_r(tempdir)
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
return result
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
# extract file
|
|
99
|
-
def self.fetch_file_with_unzip(path, target_file)
|
|
100
|
-
list, error, = Open3.capture3("unzip", "-Z", "-1", path)
|
|
101
|
-
UI.user_error!(error) unless error.empty?
|
|
102
|
-
|
|
103
|
-
return nil if list.empty?
|
|
104
|
-
entry = list.chomp.split("\n").find do |e|
|
|
105
|
-
File.fnmatch(target_file, e, File::FNM_PATHNAME)
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
data, error, = Open3.capture3("unzip", "-p", path, entry)
|
|
109
|
-
UI.user_error!(error) unless error.empty?
|
|
110
|
-
UI.user_error!("not exits data for #{target_file}") if data.empty?
|
|
111
|
-
|
|
112
|
-
data
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
private
|
|
116
|
-
|
|
117
|
-
# return app folder path
|
|
118
|
-
def self.find_app_folder_path_in_ipa(ipa_path)
|
|
119
|
-
return "Payload/#{File.basename(ipa_path, File.extname(ipa_path))}.app"
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
end
|