pprof 0.4.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/pprof +20 -4
- data/lib/pprof/output_formatter.rb +82 -28
- data/lib/pprof/provisioning_profile.rb +1 -1
- data/lib/pprof/version.rb +1 -1
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 21276029f4a059802fcc59cdf37a843caa2b38cc11d6af22f76fa2969bf24975
|
4
|
+
data.tar.gz: 02eedbe630b35226f7a00c531d0b8075b11ab6f4c705434e2f4e4f3445251c8d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 48eb1f57db15c832e6a9acf454d9c6a5ce3be07dc7db4d5877cccb7c32c96f6cfddcf7b3be78a8af8c2c9374148961273a0a1e22a5f51e13b0d8df7359b20ed7
|
7
|
+
data.tar.gz: fdb8efa34984352bc61242ae6452c3e5f6a6e3c11708735c0061d202dae12d8c232458ad88f02d572579221e7d1b8e7e30b1c457048ad626097d80d9825e5aba
|
data/bin/pprof
CHANGED
@@ -40,6 +40,8 @@ parser = OptionParser.new do |opts|
|
|
40
40
|
|Tips:
|
41
41
|
| - If you want to search for _exact_ match, you can use and anchored RegEx like `/^InHouse$/i`
|
42
42
|
| - To remove all expired certificates, you can use `#{opts.program_name} -e0 | xargs -0 rm`
|
43
|
+
| - You can combine the `--json` output with `jq` to generate and filter using some powerful custom outputs.
|
44
|
+
| e.g.: `#{opts.program_name} --name 'My App' --json --devices | jq '.[] | {uuid:.UUID, name:.AppIDName, nb_profiles: .ProvisionedDevices|length}'`
|
43
45
|
BANNER
|
44
46
|
|
45
47
|
opts.separator ''
|
@@ -64,6 +66,9 @@ parser = OptionParser.new do |opts|
|
|
64
66
|
opts.on('-p', '--path', 'Print only the paths, one per line (instead of an ASCII table)') do
|
65
67
|
list_options[:mode] = :path
|
66
68
|
end
|
69
|
+
opts.on('-j', '--json', 'Print the output information as a JSON') do
|
70
|
+
list_options[:mode] = :json
|
71
|
+
end
|
67
72
|
opts.on('-0', '--print0', 'Separate each found entry by \\0, to be used by `xargs -0`') do
|
68
73
|
list_options[:zero] = true
|
69
74
|
end
|
@@ -139,7 +144,7 @@ unless filters.empty? || ARGV.empty?
|
|
139
144
|
exit
|
140
145
|
end
|
141
146
|
|
142
|
-
unless options.empty? || !ARGV.empty?
|
147
|
+
unless list_options[:mode] == :json || options.empty? || !ARGV.empty?
|
143
148
|
puts 'You should use option flags only when providing an specific path.'
|
144
149
|
puts parser # Usage
|
145
150
|
exit
|
@@ -151,14 +156,25 @@ o = PProf::OutputFormatter.new
|
|
151
156
|
if ARGV.empty?
|
152
157
|
# Print list of matching profiles
|
153
158
|
list_options[:mode] = :path if list_options[:zero] && list_options[:mode] == :table
|
154
|
-
o.
|
159
|
+
filter_func = o.filter_proc(filters)
|
160
|
+
case list_options[:mode]
|
161
|
+
when :table
|
162
|
+
o.print_table(&filter_func)
|
163
|
+
when :json
|
164
|
+
o.print_json_list(options: options, &filter_func)
|
165
|
+
else
|
166
|
+
o.print_list(options: list_options, &filter_func)
|
167
|
+
end
|
155
168
|
else
|
156
169
|
begin
|
157
170
|
# Print info about given profile path/UUID
|
158
171
|
p = PProf::ProvisioningProfile.new(ARGV[0])
|
159
|
-
|
160
172
|
options = { info: true } if options.empty?
|
161
|
-
|
173
|
+
if list_options[:mode] == :json
|
174
|
+
o.print_json(p, options)
|
175
|
+
else
|
176
|
+
o.print_info(p, options)
|
177
|
+
end
|
162
178
|
rescue StandardError => e
|
163
179
|
o.print_error(e, ARGV[0])
|
164
180
|
end
|
@@ -1,9 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'json'
|
4
|
+
|
3
5
|
# Module for the pprof tool to manipulate Provisioning Profiles
|
4
6
|
module PProf
|
5
7
|
# A helper tool to pretty-print Provisioning Profile informations
|
6
8
|
class OutputFormatter
|
9
|
+
# List of properties of a `PProf::ProvisioningProfile` to print when using the `-i` flag
|
10
|
+
MAIN_PROFILE_KEYS = %i[name uuid app_id_name app_id_prefix creation_date expiration_date ttl team_ids team_name]
|
11
|
+
|
7
12
|
# Initialize a new OutputFormatter
|
8
13
|
#
|
9
14
|
# @param [IO] output
|
@@ -63,8 +68,7 @@ module PProf
|
|
63
68
|
def print_info(profile, options = nil)
|
64
69
|
options ||= { info: true }
|
65
70
|
if options[:info]
|
66
|
-
keys =
|
67
|
-
team_name]
|
71
|
+
keys = MAIN_PROFILE_KEYS
|
68
72
|
keys.each do |key|
|
69
73
|
@output.puts "- #{key}: #{profile.send(key.to_sym)}"
|
70
74
|
end
|
@@ -93,27 +97,57 @@ module PProf
|
|
93
97
|
# rubocop:enable Style/GuardClause
|
94
98
|
end
|
95
99
|
|
96
|
-
#
|
100
|
+
# Returns a Provisioning Profile hash ready to be printed as a JSON output
|
97
101
|
#
|
98
|
-
#
|
102
|
+
# @param [Array<PProf::ProvisioningProfile>] profile
|
103
|
+
# List of provisioning profiles to include in the JSON output
|
104
|
+
# @param [Hash] options
|
105
|
+
# Options to indicate what to include in the generated JSON.
|
106
|
+
# `:certs`: if set to `true`, output will also include the info about `DeveloperCertificates` in each profile
|
107
|
+
# `:devices`: if set to `true`, output will also include the list of `ProvisionedDevices` for each profile
|
99
108
|
#
|
100
|
-
# @
|
101
|
-
#
|
109
|
+
# @return [Hash] The hash ready to be `JSON.pretty_generate`'d
|
110
|
+
#
|
111
|
+
def as_json(profile, options = {})
|
112
|
+
hash = profile.to_hash.dup
|
113
|
+
hash.delete 'DER-Encoded-Profile'
|
114
|
+
hash.delete 'ProvisionedDevices' unless options[:devices]
|
115
|
+
if options[:certs]
|
116
|
+
hash['DeveloperCertificates'] = profile.developer_certificates.map do |cert|
|
117
|
+
{
|
118
|
+
subject: cert.subject,
|
119
|
+
issuer: cert.issuer,
|
120
|
+
serial: cert.serial,
|
121
|
+
expires: cert.not_after
|
122
|
+
}
|
123
|
+
end
|
124
|
+
else
|
125
|
+
hash.delete 'DeveloperCertificates'
|
126
|
+
end
|
127
|
+
hash
|
128
|
+
end
|
129
|
+
|
130
|
+
# Prints a Provisioning Profile as JSON
|
131
|
+
#
|
132
|
+
# @param [Array<PProf::ProvisioningProfile>] profile
|
133
|
+
# List of provisioning profiles to include in the JSON output
|
134
|
+
# @param [Hash] options
|
135
|
+
# Options to indicate what to include in the generated JSON.
|
136
|
+
# `:certs`: if set to `true`, output will also include the info about `DeveloperCertificates` in each profile
|
137
|
+
# `:devices`: if set to `true`, output will also include the list of `ProvisionedDevices` for each profile
|
138
|
+
#
|
139
|
+
def print_json(profile, options = {})
|
140
|
+
@output.puts JSON.pretty_generate(as_json(profile, options))
|
141
|
+
end
|
142
|
+
|
143
|
+
# Generates a lambda which takes a `PProf::ProvisioningProfile` and returns if it should be kept in our listing or not
|
102
144
|
#
|
103
145
|
# @param [Hash<Symbol,Any>] filters
|
104
146
|
# The hash describing the applied filters
|
147
|
+
# @return [Lambda] A lambda which takes a `PProf::ProvisioningProfile` and returns `true` if it matches the provided `filters`
|
105
148
|
#
|
106
|
-
|
107
|
-
|
108
|
-
# * Valid values for key `:mode` are:
|
109
|
-
# - `:table` (for ASCII table output)
|
110
|
-
# - `:list` (for plain list of only the UUIDs, suitable for piping to `xargs`)
|
111
|
-
# - `:path` (for plain list of only the paths, suitable for piping to `xargs`)
|
112
|
-
# * Valid values for key `:zero` are `true` or `false` to decide if we print `\0` at the end of each output.
|
113
|
-
# Only used by `:list` and `:path` modes
|
114
|
-
#
|
115
|
-
def print_filtered_list(dir = PProf::ProvisioningProfile::DEFAULT_DIR, filters = {}, list_options = { mode: :table })
|
116
|
-
filter_func = lambda do |p|
|
149
|
+
def filter_proc(filters = {})
|
150
|
+
lambda do |p|
|
117
151
|
(filters[:name].nil? || p.name =~ filters[:name]) &&
|
118
152
|
(filters[:appid_name].nil? || p.app_id_name =~ filters[:appid_name]) &&
|
119
153
|
(filters[:appid].nil? || p.entitlements.app_id =~ filters[:appid]) &&
|
@@ -125,13 +159,6 @@ module PProf
|
|
125
159
|
(filters[:aps_env].nil? || match_aps_env(p.entitlements.aps_environment, filters[:aps_env])) &&
|
126
160
|
true
|
127
161
|
end
|
128
|
-
|
129
|
-
case list_options[:mode]
|
130
|
-
when :table
|
131
|
-
print_table(dir, &filter_func)
|
132
|
-
else
|
133
|
-
print_list(dir, list_options, &filter_func)
|
134
|
-
end
|
135
162
|
end
|
136
163
|
|
137
164
|
# Prints the filtered list as a table
|
@@ -144,7 +171,7 @@ module PProf
|
|
144
171
|
# The block is given ProvisioningProfile object and should
|
145
172
|
# return true to display the row, false to filter it out
|
146
173
|
#
|
147
|
-
def print_table(dir
|
174
|
+
def print_table(dir: PProf::ProvisioningProfile::DEFAULT_DIR)
|
148
175
|
count = 0
|
149
176
|
errors = []
|
150
177
|
|
@@ -181,21 +208,21 @@ module PProf
|
|
181
208
|
# Defaults to '~/Library/MobileDevice/Provisioning Profiles'
|
182
209
|
# @param [Hash] options
|
183
210
|
# The options hash typically filled while parsing the command line arguments.
|
184
|
-
# - :mode: will print the UUIDs if set to `:
|
211
|
+
# - :mode: will print the UUIDs if set to `:list`, the file path otherwise
|
185
212
|
# - :zero: will concatenate the entries with `\0` instead of `\n` if set
|
186
213
|
#
|
187
214
|
# @yield each provisioning profile for filtering/validation
|
188
215
|
# The block is given ProvisioningProfile object and should
|
189
216
|
# return true to display the row, false to filter it out
|
190
217
|
#
|
191
|
-
def print_list(dir
|
218
|
+
def print_list(dir: PProf::ProvisioningProfile::DEFAULT_DIR, options:) # rubocop:disable Style/OptionalArguments
|
192
219
|
errors = []
|
193
220
|
Dir['*.mobileprovision', base: dir].each do |file_name|
|
194
221
|
file = File.join(dir, file_name)
|
195
222
|
p = PProf::ProvisioningProfile.new(file)
|
196
223
|
next if block_given? && !yield(p)
|
197
224
|
|
198
|
-
@output.print options[:mode] == :
|
225
|
+
@output.print options[:mode] == :list ? p.uuid.chomp : file.chomp
|
199
226
|
@output.print options[:zero] ? "\0" : "\n"
|
200
227
|
rescue StandardError => e
|
201
228
|
errors << { message: e, file: file }
|
@@ -203,6 +230,33 @@ module PProf
|
|
203
230
|
errors.each { |e| print_error(e[:message], e[:file]) } unless errors.empty?
|
204
231
|
end
|
205
232
|
|
233
|
+
# Prints the filtered list of profiles as a JSON array
|
234
|
+
#
|
235
|
+
# @param [String] dir
|
236
|
+
# The directory containing the mobileprovision files to list.
|
237
|
+
# Defaults to '~/Library/MobileDevice/Provisioning Profiles'
|
238
|
+
# @param [Hash] options
|
239
|
+
# The options hash typically filled while parsing the command line arguments.
|
240
|
+
# - :certs: will print the UUIDs if set to `:list`, the file path otherwise
|
241
|
+
# - :devices: will concatenate the entries with `\0` instead of `\n` if set
|
242
|
+
#
|
243
|
+
# @yield each provisioning profile for filtering/validation
|
244
|
+
# The block is given ProvisioningProfile object and should
|
245
|
+
# return true to display the row, false to filter it out
|
246
|
+
#
|
247
|
+
def print_json_list(dir: PProf::ProvisioningProfile::DEFAULT_DIR, options:) # rubocop:disable Style/OptionalArguments
|
248
|
+
errors = []
|
249
|
+
profiles = Dir['*.mobileprovision', base: dir].map do |file_name|
|
250
|
+
file = File.join(dir, file_name)
|
251
|
+
p = PProf::ProvisioningProfile.new(file)
|
252
|
+
as_json(p, options) unless block_given? && !yield(p)
|
253
|
+
rescue StandardError => e
|
254
|
+
errors << { message: e, file: file }
|
255
|
+
end.compact
|
256
|
+
errors.each { |e| print_error(e[:message], e[:file]) } unless errors.empty?
|
257
|
+
@output.puts JSON.pretty_generate(profiles)
|
258
|
+
end
|
259
|
+
|
206
260
|
def self.match_aps_env(actual, expected)
|
207
261
|
return false if actual.nil? # false if no Push entitlements
|
208
262
|
return true if expected == true # true if Push present but we don't filter on specific env
|
data/lib/pprof/version.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.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Olivier Halligon
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-05-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: plist
|
@@ -44,7 +44,7 @@ licenses:
|
|
44
44
|
- MIT
|
45
45
|
metadata:
|
46
46
|
rubygems_mfa_required: 'true'
|
47
|
-
post_install_message:
|
47
|
+
post_install_message:
|
48
48
|
rdoc_options: []
|
49
49
|
require_paths:
|
50
50
|
- lib
|
@@ -52,15 +52,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
52
52
|
requirements:
|
53
53
|
- - ">="
|
54
54
|
- !ruby/object:Gem::Version
|
55
|
-
version: 2.
|
55
|
+
version: 2.6.4
|
56
56
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
58
|
- - ">="
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: '0'
|
61
61
|
requirements: []
|
62
|
-
rubygems_version: 3.
|
63
|
-
signing_key:
|
62
|
+
rubygems_version: 3.0.3
|
63
|
+
signing_key:
|
64
64
|
specification_version: 4
|
65
65
|
summary: A Provisioning Profiles library
|
66
66
|
test_files: []
|