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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b8843e85a32a30167805e1aa3cef04d1626b05f7f1d1c130b1558d9e3bfaa809
4
- data.tar.gz: 4ef87037d3779a327d32bb87fb73fc3501d94d4406bb9529fc1049775a23f93e
3
+ metadata.gz: 21276029f4a059802fcc59cdf37a843caa2b38cc11d6af22f76fa2969bf24975
4
+ data.tar.gz: 02eedbe630b35226f7a00c531d0b8075b11ab6f4c705434e2f4e4f3445251c8d
5
5
  SHA512:
6
- metadata.gz: 19fe84e13c4007da01357055deb1350eb0108fe31dd45466827208d7d59f9a858dedc8450e1f0cc2f7863db567263638371ce97536d66b5db054c021c5caa612
7
- data.tar.gz: 065fbe7cd8cc1af06ca4e739ca1e901694cf711039c345cd2bd9086090b80af503b616ce2babeedf0120bb692c8d425472e8ad8b2d645efb4569f42771cd63bc
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.print_filtered_list(PProf::ProvisioningProfile::DEFAULT_DIR, filters, list_options)
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
- o.print_info(p, options)
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 = %i[name uuid app_id_name app_id_prefix creation_date expiration_date ttl team_ids
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
- # Prints the filtered list of Provisioning Profiles
100
+ # Returns a Provisioning Profile hash ready to be printed as a JSON output
97
101
  #
98
- # Convenience method. Calls self.print_list with a filter block build from a filter hash
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
- # @param [String] dir
101
- # The directory to search for the provisioning profiles. Defaults to the standard directory on Mac
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
- # @param [Hash<Symbol,Any>] list_options
107
- # The way to print the output.
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 = PProf::ProvisioningProfile::DEFAULT_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 `:uuid`, the file path otherwise
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 = PProf::ProvisioningProfile::DEFAULT_DIR, options) # rubocop:disable Style/OptionalArguments
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] == :uuid ? p.uuid.chomp : file.chomp
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
@@ -146,7 +146,7 @@ module PProf
146
146
  #
147
147
  # @return [Hash]
148
148
  def to_hash
149
- @dict
149
+ @plist
150
150
  end
151
151
 
152
152
  # The human-readable string representation of this Provisioning Profile
data/lib/pprof/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  module PProf
4
4
  # Module version
5
- VERSION = '0.4.0'
5
+ VERSION = '0.5.1'
6
6
  end
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.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-02-28 00:00:00.000000000 Z
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.7.0
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.2.19
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: []