pprof 0.3.9 → 0.4.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 +5 -5
- data/bin/pprof +41 -40
- data/lib/pprof/entitlements.rb +6 -3
- data/lib/pprof/output_formatter.rb +61 -47
- data/lib/pprof/provisioning_profile.rb +21 -19
- data/lib/pprof/version.rb +3 -1
- data/lib/pprof.rb +2 -0
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b8843e85a32a30167805e1aa3cef04d1626b05f7f1d1c130b1558d9e3bfaa809
|
4
|
+
data.tar.gz: 4ef87037d3779a327d32bb87fb73fc3501d94d4406bb9529fc1049775a23f93e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 19fe84e13c4007da01357055deb1350eb0108fe31dd45466827208d7d59f9a858dedc8450e1f0cc2f7863db567263638371ce97536d66b5db054c021c5caa612
|
7
|
+
data.tar.gz: 065fbe7cd8cc1af06ca4e739ca1e901694cf711039c345cd2bd9086090b80af503b616ce2babeedf0120bb692c8d425472e8ad8b2d645efb4569f42771cd63bc
|
data/bin/pprof
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require 'pprof'
|
4
5
|
require 'optparse'
|
@@ -7,7 +8,7 @@ require 'optparse'
|
|
7
8
|
# Or a standard match if the string is bare.
|
8
9
|
#
|
9
10
|
def matcher(string)
|
10
|
-
m = string.match(%r
|
11
|
+
m = string.match(%r{^/(.*)/(.*)$})
|
11
12
|
if m.nil?
|
12
13
|
Regexp.new(Regexp.escape(string))
|
13
14
|
else
|
@@ -19,10 +20,11 @@ end
|
|
19
20
|
|
20
21
|
filters = {}
|
21
22
|
options = {}
|
22
|
-
list_options = { :
|
23
|
+
list_options = { mode: :table }
|
23
24
|
|
25
|
+
# rubocop:disable Metrics/BlockLength
|
24
26
|
parser = OptionParser.new do |opts|
|
25
|
-
opts.banner = <<-BANNER.gsub(/^ *\|/,'')
|
27
|
+
opts.banner = <<-BANNER.gsub(/^ *\|/, '')
|
26
28
|
|Usage:
|
27
29
|
| pprof [print_options] (PATH|UUID)
|
28
30
|
| pprof [list_options] [filters]
|
@@ -40,125 +42,124 @@ parser = OptionParser.new do |opts|
|
|
40
42
|
| - To remove all expired certificates, you can use `#{opts.program_name} -e0 | xargs -0 rm`
|
41
43
|
BANNER
|
42
44
|
|
43
|
-
opts.separator
|
44
|
-
opts.separator
|
45
|
+
opts.separator ''
|
46
|
+
opts.separator 'Print options (when file given)'
|
45
47
|
|
46
|
-
opts.on(
|
48
|
+
opts.on('-i', '--info', 'Print general info (default)') do
|
47
49
|
options[:info] = true
|
48
50
|
end
|
49
|
-
opts.on(
|
51
|
+
opts.on('-c', '--certs', 'Print certificates') do
|
50
52
|
options[:certs] = true
|
51
53
|
end
|
52
|
-
opts.on(
|
54
|
+
opts.on('-d', '--devices', 'Print provisioned devices') do
|
53
55
|
options[:devices] = true
|
54
56
|
end
|
55
57
|
|
56
|
-
opts.separator
|
57
|
-
opts.separator
|
58
|
+
opts.separator ''
|
59
|
+
opts.separator 'List options (when no file given)'
|
58
60
|
|
59
|
-
opts.on(
|
61
|
+
opts.on('-l', '--list', 'Print only the UUIDs, one per line (instead of an ASCII table)') do
|
60
62
|
list_options[:mode] = :list
|
61
63
|
end
|
62
|
-
opts.on(
|
64
|
+
opts.on('-p', '--path', 'Print only the paths, one per line (instead of an ASCII table)') do
|
63
65
|
list_options[:mode] = :path
|
64
66
|
end
|
65
|
-
opts.on(
|
67
|
+
opts.on('-0', '--print0', 'Separate each found entry by \\0, to be used by `xargs -0`') do
|
66
68
|
list_options[:zero] = true
|
67
69
|
end
|
68
70
|
|
69
|
-
opts.separator
|
70
|
-
opts.separator
|
71
|
+
opts.separator ''
|
72
|
+
opts.separator 'Filters (when no file given)'
|
71
73
|
|
72
|
-
opts.on(
|
74
|
+
opts.on('--name NAME', 'Filter by name') do |name|
|
73
75
|
filters[:name] = matcher(name)
|
74
76
|
end
|
75
77
|
|
76
|
-
opts.on(
|
78
|
+
opts.on('--appid-name APPID', 'Filter by App ID Name') do |appid_name|
|
77
79
|
filters[:appid_name] = matcher(appid_name)
|
78
80
|
end
|
79
81
|
|
80
|
-
opts.on(
|
82
|
+
opts.on('--appid APPID', 'Filter by App ID') do |appid|
|
81
83
|
filters[:appid] = matcher(appid)
|
82
84
|
end
|
83
85
|
|
84
|
-
opts.on(
|
86
|
+
opts.on('--uuid UUID', 'Filter by UUID') do |uuid|
|
85
87
|
filters[:uuid] = matcher(uuid)
|
86
88
|
end
|
87
89
|
|
88
|
-
opts.on(
|
90
|
+
opts.on('--team TEAM', 'Filter by team name or ID') do |team|
|
89
91
|
filters[:team] = matcher(team)
|
90
92
|
end
|
91
93
|
|
92
|
-
opts.on(
|
94
|
+
opts.on('--[no-]exp', 'Only profiles (not) expired') do |flag|
|
93
95
|
filters[:exp] = flag
|
94
96
|
end
|
95
97
|
|
96
|
-
opts.on(
|
98
|
+
opts.on('--[no-]has-devices', 'Filter by profiles having (no) provisioned devices') do |d|
|
97
99
|
filters[:has_devices] = d
|
98
100
|
end
|
99
101
|
|
100
|
-
opts.on(
|
102
|
+
opts.on('--[no-]all-devices', 'Filter by profiles (not) provisioning all devices') do |d|
|
101
103
|
filters[:all_devices] = d
|
102
104
|
end
|
103
105
|
|
104
|
-
opts.on(
|
106
|
+
opts.on('--aps [ENV]', 'Only profiles having Push entitlements (or a specific aps env)') do |env|
|
105
107
|
filters[:aps_env] = env.nil? ? true : matcher(env)
|
106
108
|
end
|
107
109
|
|
110
|
+
opts.separator ''
|
111
|
+
opts.separator 'Misc'
|
108
112
|
|
109
|
-
opts.
|
110
|
-
opts.separator "Misc"
|
111
|
-
|
112
|
-
opts.on_tail("-h", "--help", "Show this message") do
|
113
|
+
opts.on_tail('-h', '--help', 'Show this message') do
|
113
114
|
puts opts
|
114
115
|
exit
|
115
116
|
end
|
116
117
|
|
117
|
-
opts.on_tail(
|
118
|
+
opts.on_tail('-v', '--version', 'Show version') do
|
118
119
|
puts PProf::VERSION
|
119
120
|
exit
|
120
121
|
end
|
121
122
|
end
|
123
|
+
# rubocop:enable Metrics/BlockLength
|
122
124
|
|
123
125
|
# Parse the options, catching parse errors nicely
|
124
126
|
begin
|
125
127
|
parser.parse!
|
126
|
-
rescue OptionParser::InvalidOption =>
|
127
|
-
puts
|
128
|
-
puts parser.help
|
128
|
+
rescue OptionParser::InvalidOption => e
|
129
|
+
puts e
|
130
|
+
puts parser.help
|
129
131
|
exit 1
|
130
132
|
end
|
131
133
|
|
132
134
|
# Don't mix filters and options together, that doesn't make sense
|
133
135
|
|
134
136
|
unless filters.empty? || ARGV.empty?
|
135
|
-
puts
|
137
|
+
puts 'You should use either filter flags to filter the whole list, or an specific path, not both.'
|
136
138
|
puts parser # Usage
|
137
139
|
exit
|
138
140
|
end
|
139
141
|
|
140
142
|
unless options.empty? || !ARGV.empty?
|
141
|
-
puts
|
143
|
+
puts 'You should use option flags only when providing an specific path.'
|
142
144
|
puts parser # Usage
|
143
145
|
exit
|
144
146
|
end
|
145
147
|
|
146
148
|
# Call the appropriate action
|
147
149
|
|
150
|
+
o = PProf::OutputFormatter.new
|
148
151
|
if ARGV.empty?
|
149
152
|
# Print list of matching profiles
|
150
|
-
o = PProf::OutputFormatter.new
|
151
153
|
list_options[:mode] = :path if list_options[:zero] && list_options[:mode] == :table
|
152
154
|
o.print_filtered_list(PProf::ProvisioningProfile::DEFAULT_DIR, filters, list_options)
|
153
155
|
else
|
154
|
-
# Print info about given profile path/UUID
|
155
|
-
o = PProf::OutputFormatter.new
|
156
156
|
begin
|
157
|
+
# Print info about given profile path/UUID
|
157
158
|
p = PProf::ProvisioningProfile.new(ARGV[0])
|
158
|
-
|
159
|
-
options = { :
|
159
|
+
|
160
|
+
options = { info: true } if options.empty?
|
160
161
|
o.print_info(p, options)
|
161
|
-
rescue
|
162
|
+
rescue StandardError => e
|
162
163
|
o.print_error(e, ARGV[0])
|
163
164
|
end
|
164
165
|
end
|
data/lib/pprof/entitlements.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Module for the pprof tool to manipulate Provisioning Profiles
|
2
4
|
module PProf
|
3
5
|
# Represents the list of entitlements in a Provisioning Profile
|
@@ -23,7 +25,7 @@ module PProf
|
|
23
25
|
# True if we can attach a debugger to the executable, false if not.
|
24
26
|
#
|
25
27
|
# @return [Bool]
|
26
|
-
def get_task_allow
|
28
|
+
def get_task_allow # rubocop:disable Naming/AccessorMethodName
|
27
29
|
@dict['get-task-allow']
|
28
30
|
end
|
29
31
|
|
@@ -98,9 +100,10 @@ module PProf
|
|
98
100
|
# @param [#to_s] key
|
99
101
|
# The key to check
|
100
102
|
#
|
101
|
-
def
|
102
|
-
@dict.
|
103
|
+
def key?(key)
|
104
|
+
@dict.key?(key.to_s)
|
103
105
|
end
|
106
|
+
alias has_key? key?
|
104
107
|
|
105
108
|
# The list of all entitlement keys, as String
|
106
109
|
#
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Module for the pprof tool to manipulate Provisioning Profiles
|
2
4
|
module PProf
|
3
5
|
# A helper tool to pretty-print Provisioning Profile informations
|
@@ -27,14 +29,16 @@ module PProf
|
|
27
29
|
# @param [String...] cols
|
28
30
|
# The content of each column of the row to add
|
29
31
|
def row(*cols)
|
30
|
-
|
32
|
+
justified_cols = cols.zip(@widths).map do |c, w|
|
31
33
|
(c || '<nil>').to_s.ljust(w)[0...w]
|
32
|
-
end
|
34
|
+
end
|
35
|
+
"| #{justified_cols.join(' | ')} |"
|
33
36
|
end
|
34
37
|
|
35
38
|
# Add a separator line to the ASCII table
|
36
39
|
def separator
|
37
|
-
|
40
|
+
columns_dashes = @widths.map { |w| '-' * (w + 2) }
|
41
|
+
"+#{columns_dashes.join('+')}+"
|
38
42
|
end
|
39
43
|
end
|
40
44
|
|
@@ -57,25 +61,36 @@ module PProf
|
|
57
61
|
# Decide what to print. Valid keys are :info, :certs and :devices
|
58
62
|
#
|
59
63
|
def print_info(profile, options = nil)
|
60
|
-
options ||= { :
|
64
|
+
options ||= { info: true }
|
61
65
|
if options[:info]
|
62
|
-
keys = [
|
66
|
+
keys = %i[name uuid app_id_name app_id_prefix creation_date expiration_date ttl team_ids
|
67
|
+
team_name]
|
63
68
|
keys.each do |key|
|
64
|
-
@output.puts "- #{key
|
69
|
+
@output.puts "- #{key}: #{profile.send(key.to_sym)}"
|
65
70
|
end
|
66
|
-
@output.puts
|
67
|
-
@output.puts
|
71
|
+
@output.puts '- Entitlements:'
|
72
|
+
@output.puts(profile.entitlements.to_s.split("\n").map { |line| " #{line}" })
|
68
73
|
end
|
69
74
|
|
70
|
-
|
75
|
+
# rubocop:disable Style/GuardClause
|
76
|
+
if options[:info] || options[:certs]
|
71
77
|
@output.puts "- #{profile.developer_certificates.count} Developer Certificates"
|
72
|
-
|
78
|
+
if options[:certs]
|
79
|
+
profile.developer_certificates.each do |cert|
|
80
|
+
@output.puts " - #{cert.subject}"
|
81
|
+
@output.puts " issuer: #{cert.issuer}"
|
82
|
+
@output.puts " serial: #{cert.serial}"
|
83
|
+
@output.puts " expires: #{cert.not_after}"
|
84
|
+
end
|
85
|
+
end
|
73
86
|
end
|
87
|
+
|
74
88
|
if options[:info] || options[:devices]
|
75
89
|
@output.puts "- #{(profile.provisioned_devices || []).count} Provisioned Devices"
|
76
90
|
profile.provisioned_devices.each { |udid| @output.puts " - #{udid}" } if options[:devices]
|
77
91
|
@output.puts "- Provision all devices: #{profile.provisions_all_devices.inspect}"
|
78
92
|
end
|
93
|
+
# rubocop:enable Style/GuardClause
|
79
94
|
end
|
80
95
|
|
81
96
|
# Prints the filtered list of Provisioning Profiles
|
@@ -97,18 +112,18 @@ module PProf
|
|
97
112
|
# * Valid values for key `:zero` are `true` or `false` to decide if we print `\0` at the end of each output.
|
98
113
|
# Only used by `:list` and `:path` modes
|
99
114
|
#
|
100
|
-
def print_filtered_list(dir = PProf::ProvisioningProfile::DEFAULT_DIR, filters = {}, list_options = { :
|
115
|
+
def print_filtered_list(dir = PProf::ProvisioningProfile::DEFAULT_DIR, filters = {}, list_options = { mode: :table })
|
101
116
|
filter_func = lambda do |p|
|
102
117
|
(filters[:name].nil? || p.name =~ filters[:name]) &&
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
118
|
+
(filters[:appid_name].nil? || p.app_id_name =~ filters[:appid_name]) &&
|
119
|
+
(filters[:appid].nil? || p.entitlements.app_id =~ filters[:appid]) &&
|
120
|
+
(filters[:uuid].nil? || p.uuid =~ filters[:uuid]) &&
|
121
|
+
(filters[:team].nil? || p.team_name =~ filters[:team] || p.team_ids.any? { |id| id =~ filters[:team] }) &&
|
122
|
+
(filters[:exp].nil? || (p.expiration_date < DateTime.now) == filters[:exp]) &&
|
123
|
+
(filters[:has_devices].nil? || !(p.provisioned_devices || []).empty? == filters[:has_devices]) &&
|
124
|
+
(filters[:all_devices].nil? || p.provisions_all_devices == filters[:all_devices]) &&
|
125
|
+
(filters[:aps_env].nil? || match_aps_env(p.entitlements.aps_environment, filters[:aps_env])) &&
|
126
|
+
true
|
112
127
|
end
|
113
128
|
|
114
129
|
case list_options[:mode]
|
@@ -138,16 +153,17 @@ module PProf
|
|
138
153
|
@output.puts table.row('UUID', 'Name', 'AppID', 'Expiration Date', ' ', 'Team Name')
|
139
154
|
@output.puts table.separator
|
140
155
|
|
141
|
-
Dir[
|
156
|
+
Dir['*.mobileprovision', base: dir].each do |file_name|
|
157
|
+
file = File.join(dir, file_name)
|
142
158
|
begin
|
143
159
|
p = PProf::ProvisioningProfile.new(file)
|
144
|
-
|
160
|
+
|
145
161
|
next if block_given? && !yield(p)
|
146
162
|
|
147
163
|
state = DateTime.now < p.expiration_date ? "\u{2705}" : "\u{274c}" # 2705=checkmark, 274C=red X
|
148
164
|
@output.puts table.row(p.uuid, p.name, p.entitlements.app_id, p.expiration_date.to_time, state, p.team_name)
|
149
|
-
rescue
|
150
|
-
errors << { :
|
165
|
+
rescue StandardError => e
|
166
|
+
errors << { message: e, file: file }
|
151
167
|
end
|
152
168
|
count += 1
|
153
169
|
end
|
@@ -155,9 +171,7 @@ module PProf
|
|
155
171
|
@output.puts table.separator
|
156
172
|
@output.puts "#{count} Provisioning Profiles found."
|
157
173
|
|
158
|
-
unless errors.empty?
|
159
|
-
errors.each { |e| print_error(e[:message], e[:file]) }
|
160
|
-
end
|
174
|
+
errors.each { |e| print_error(e[:message], e[:file]) } unless errors.empty?
|
161
175
|
end
|
162
176
|
|
163
177
|
# Prints the filtered list of UUIDs or Paths only
|
@@ -165,35 +179,35 @@ module PProf
|
|
165
179
|
# @param [String] dir
|
166
180
|
# The directory containing the mobileprovision files to list.
|
167
181
|
# Defaults to '~/Library/MobileDevice/Provisioning Profiles'
|
182
|
+
# @param [Hash] options
|
183
|
+
# The options hash typically filled while parsing the command line arguments.
|
184
|
+
# - :mode: will print the UUIDs if set to `:uuid`, the file path otherwise
|
185
|
+
# - :zero: will concatenate the entries with `\0` instead of `\n` if set
|
168
186
|
#
|
169
|
-
# @yield each provisioning
|
187
|
+
# @yield each provisioning profile for filtering/validation
|
170
188
|
# The block is given ProvisioningProfile object and should
|
171
189
|
# return true to display the row, false to filter it out
|
172
190
|
#
|
173
|
-
def print_list(dir = PProf::ProvisioningProfile::DEFAULT_DIR, options)
|
191
|
+
def print_list(dir = PProf::ProvisioningProfile::DEFAULT_DIR, options) # rubocop:disable Style/OptionalArguments
|
174
192
|
errors = []
|
175
|
-
Dir[
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
end
|
185
|
-
end
|
186
|
-
unless errors.empty?
|
187
|
-
errors.each { |e| print_error(e[:message], e[:file]) }
|
193
|
+
Dir['*.mobileprovision', base: dir].each do |file_name|
|
194
|
+
file = File.join(dir, file_name)
|
195
|
+
p = PProf::ProvisioningProfile.new(file)
|
196
|
+
next if block_given? && !yield(p)
|
197
|
+
|
198
|
+
@output.print options[:mode] == :uuid ? p.uuid.chomp : file.chomp
|
199
|
+
@output.print options[:zero] ? "\0" : "\n"
|
200
|
+
rescue StandardError => e
|
201
|
+
errors << { message: e, file: file }
|
188
202
|
end
|
203
|
+
errors.each { |e| print_error(e[:message], e[:file]) } unless errors.empty?
|
189
204
|
end
|
190
205
|
|
191
|
-
|
192
|
-
private
|
193
206
|
def self.match_aps_env(actual, expected)
|
194
|
-
return false if actual.nil?
|
195
|
-
return true if expected
|
196
|
-
|
207
|
+
return false if actual.nil? # false if no Push entitlements
|
208
|
+
return true if expected == true # true if Push present but we don't filter on specific env
|
209
|
+
|
210
|
+
actual =~ expected # true if Push present and we filter on specific env
|
197
211
|
end
|
198
212
|
end
|
199
213
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'openssl'
|
2
4
|
require 'plist'
|
3
5
|
require 'time'
|
@@ -7,7 +9,7 @@ module PProf
|
|
7
9
|
# Represents the content of a Provisioning Profile file
|
8
10
|
class ProvisioningProfile
|
9
11
|
# The default location where all the Provisioning Profiles are stored on a Mac
|
10
|
-
DEFAULT_DIR="#{ENV['HOME']}/Library/MobileDevice/Provisioning Profiles"
|
12
|
+
DEFAULT_DIR = "#{ENV['HOME']}/Library/MobileDevice/Provisioning Profiles"
|
11
13
|
|
12
14
|
# Create a new ProvisioningProfile object from a file path or UUID
|
13
15
|
#
|
@@ -19,26 +21,26 @@ module PProf
|
|
19
21
|
# File path or UUID of the ProvisioningProfile
|
20
22
|
#
|
21
23
|
def initialize(file)
|
22
|
-
if file =~
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
path = if file =~ /^[0-9A-F-]*$/i
|
25
|
+
"#{PProf::ProvisioningProfile::DEFAULT_DIR}/#{file}.mobileprovision"
|
26
|
+
else
|
27
|
+
file
|
28
|
+
end
|
27
29
|
xml = nil
|
28
30
|
begin
|
29
31
|
pkcs7 = OpenSSL::PKCS7.new(File.read(path))
|
30
32
|
pkcs7.verify([], OpenSSL::X509::Store.new)
|
31
33
|
xml = pkcs7.data
|
32
|
-
raise
|
33
|
-
rescue
|
34
|
+
raise 'Empty PKCS7 payload' if xml.nil? || xml.empty?
|
35
|
+
rescue StandardError
|
34
36
|
# Seems like sometimes OpenSSL fails to parse the PKCS7 payload
|
35
37
|
# Besides, OpenSSL is deprecated on macOS so might not be up-to-date on all machines
|
36
38
|
# So as a fallback, we run the `security` command line.
|
37
|
-
# (We could use `security` everytime, but invoking a command line is generally less
|
39
|
+
# (We could use `security` everytime, but invoking a command line is generally less
|
38
40
|
# efficient than calling the OpenSSL gem if available, so for now it's just used as fallback)
|
39
41
|
xml = `security cms -D -i "#{path}" 2> /dev/null`
|
40
42
|
end
|
41
|
-
@plist = Plist
|
43
|
+
@plist = Plist.parse_xml(xml)
|
42
44
|
raise "Unable to parse file #{file}." if @plist.nil?
|
43
45
|
end
|
44
46
|
|
@@ -101,7 +103,7 @@ module PProf
|
|
101
103
|
def team_ids
|
102
104
|
@plist['TeamIdentifier']
|
103
105
|
end
|
104
|
-
|
106
|
+
|
105
107
|
# The name of the Team associated with this Provisioning Profile
|
106
108
|
#
|
107
109
|
# @return [String]
|
@@ -109,7 +111,7 @@ module PProf
|
|
109
111
|
@plist['TeamName']
|
110
112
|
end
|
111
113
|
|
112
|
-
# The list of X509 Developer
|
114
|
+
# The list of X509 Developer Certificates associated with this profile
|
113
115
|
#
|
114
116
|
# @return [Array<OpenSSL::X509::Certificate>]
|
115
117
|
def developer_certificates
|
@@ -152,14 +154,14 @@ module PProf
|
|
152
154
|
#
|
153
155
|
# @return [String]
|
154
156
|
def to_s
|
155
|
-
lines = [
|
156
|
-
"- #{key
|
157
|
+
lines = %i[name uuid app_id_name app_id_prefix creation_date expiration_date ttl team_ids team_name].map do |key|
|
158
|
+
"- #{key}: #{send(key.to_sym)}"
|
157
159
|
end +
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
160
|
+
[
|
161
|
+
"- #{developer_certificates.count} Developer Certificates",
|
162
|
+
"- #{provisioned_devices.count} Provisioned Devices",
|
163
|
+
'- Entitlements:'
|
164
|
+
] + entitlements.to_hash.map { |key, value| " - #{key}: #{value}" }
|
163
165
|
lines.join("\n")
|
164
166
|
end
|
165
167
|
end
|
data/lib/pprof/version.rb
CHANGED
data/lib/pprof.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pprof
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Olivier Halligon
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: plist
|
@@ -42,7 +42,8 @@ files:
|
|
42
42
|
homepage: https://github.com/AliSoftware/pprof
|
43
43
|
licenses:
|
44
44
|
- MIT
|
45
|
-
metadata:
|
45
|
+
metadata:
|
46
|
+
rubygems_mfa_required: 'true'
|
46
47
|
post_install_message:
|
47
48
|
rdoc_options: []
|
48
49
|
require_paths:
|
@@ -51,15 +52,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
51
52
|
requirements:
|
52
53
|
- - ">="
|
53
54
|
- !ruby/object:Gem::Version
|
54
|
-
version: 2.
|
55
|
+
version: 2.7.0
|
55
56
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
57
|
requirements:
|
57
58
|
- - ">="
|
58
59
|
- !ruby/object:Gem::Version
|
59
60
|
version: '0'
|
60
61
|
requirements: []
|
61
|
-
|
62
|
-
rubygems_version: 2.5.2
|
62
|
+
rubygems_version: 3.2.19
|
63
63
|
signing_key:
|
64
64
|
specification_version: 4
|
65
65
|
summary: A Provisioning Profiles library
|