Class: PProf::OutputFormatter

Inherits:
Object
  • Object
show all
Defined in:
lib/pprof/output_formatter.rb

Overview

A helper tool to pretty-print Provisioning Profile informations

Defined Under Namespace

Classes: ASCIITable

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(output = $stdout) ⇒ OutputFormatter

Initialize a new OutputFormatter

Parameters:

  • (defaults to: $stdout)

    The output destination where to print the formatted data. Defaults to $stdout



13
14
15
# File 'lib/pprof/output_formatter.rb', line 13

def initialize(output = $stdout)
  @output = output
end

Class Method Details

.match_aps_env(actual, expected) ⇒ Object



206
207
208
209
210
211
# File 'lib/pprof/output_formatter.rb', line 206

def self.match_aps_env(actual, expected)
  return false if actual.nil? # false if no Push entitlements
  return true if expected == true # true if Push present but we don't filter on specific env

  actual =~ expected        # true if Push present and we filter on specific env
end

Instance Method Details

Prints an error message

Parameters:

  • The error message to print

  • The provisioning profile file for which the error occurred



52
53
54
# File 'lib/pprof/output_formatter.rb', line 52

def print_error(message, file)
  @output.puts "\u{274c}  #{file} - #{message}"
end

Prints the filtered list of Provisioning Profiles

Convenience method. Calls self.print_list with a filter block build from a filter hash

Parameters:

  • (defaults to: PProf::ProvisioningProfile::DEFAULT_DIR)

    The directory to search for the provisioning profiles. Defaults to the standard directory on Mac

  • (defaults to: {})

    The hash describing the applied filters

  • (defaults to: { mode: :table })

    The way to print the output.

    • Valid values for key :mode are:

      • :table (for ASCII table output)

      • :list (for plain list of only the UUIDs, suitable for piping to xargs)

      • :path (for plain list of only the paths, suitable for piping to xargs)

    • Valid values for key :zero are true or false to decide if we print \0 at the end of each output. Only used by :list and :path modes



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/pprof/output_formatter.rb', line 115

def print_filtered_list(dir = PProf::ProvisioningProfile::DEFAULT_DIR, filters = {}, list_options = { mode: :table })
  filter_func = lambda do |p|
    (filters[:name].nil? || p.name =~ filters[:name]) &&
      (filters[:appid_name].nil? || p.app_id_name =~ filters[:appid_name]) &&
      (filters[:appid].nil? || p.entitlements.app_id =~ filters[:appid]) &&
      (filters[:uuid].nil? || p.uuid =~ filters[:uuid]) &&
      (filters[:team].nil? || p.team_name =~ filters[:team] || p.team_ids.any? { |id| id =~ filters[:team] }) &&
      (filters[:exp].nil? || (p.expiration_date < DateTime.now) == filters[:exp]) &&
      (filters[:has_devices].nil? || !(p.provisioned_devices || []).empty? == filters[:has_devices]) &&
      (filters[:all_devices].nil? || p.provisions_all_devices == filters[:all_devices]) &&
      (filters[:aps_env].nil? || match_aps_env(p.entitlements.aps_environment, filters[:aps_env])) &&
      true
  end

  case list_options[:mode]
  when :table
    print_table(dir, &filter_func)
  else
    print_list(dir, list_options, &filter_func)
  end
end

Prints the description of a Provisioning Profile

Parameters:

  • The ProvisioningProfile object to print

  • (defaults to: nil)

    Decide what to print. Valid keys are :info, :certs and :devices



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/pprof/output_formatter.rb', line 63

def print_info(profile, options = nil)
  options ||= { info: true }
  if options[:info]
    keys = i[name uuid app_id_name app_id_prefix creation_date expiration_date ttl team_ids
              team_name]
    keys.each do |key|
      @output.puts "- #{key}: #{profile.send(key.to_sym)}"
    end
    @output.puts '- Entitlements:'
    @output.puts(profile.entitlements.to_s.split("\n").map { |line| "   #{line}" })
  end

  # rubocop:disable Style/GuardClause
  if options[:info] || options[:certs]
    @output.puts "- #{profile.developer_certificates.count} Developer Certificates"
    if options[:certs]
      profile.developer_certificates.each do |cert|
        @output.puts "   - #{cert.subject}"
        @output.puts "     issuer: #{cert.issuer}"
        @output.puts "     serial: #{cert.serial}"
        @output.puts "     expires: #{cert.not_after}"
      end
    end
  end

  if options[:info] || options[:devices]
    @output.puts "- #{(profile.provisioned_devices || []).count} Provisioned Devices"
    profile.provisioned_devices.each { |udid| @output.puts "   - #{udid}" } if options[:devices]
    @output.puts "- Provision all devices: #{profile.provisions_all_devices.inspect}"
  end
  # rubocop:enable Style/GuardClause
end

Prints the filtered list of UUIDs or Paths only

Parameters:

  • (defaults to: PProf::ProvisioningProfile::DEFAULT_DIR)

    The directory containing the mobileprovision files to list. Defaults to ‘~/Library/MobileDevice/Provisioning Profiles’

  • The options hash typically filled while parsing the command line arguments.

    - :mode: will print the UUIDs if set to `:uuid`, the file path otherwise
    - :zero: will concatenate the entries with `\0` instead of `\n` if set
    

Yields:

  • each provisioning profile for filtering/validation The block is given ProvisioningProfile object and should return true to display the row, false to filter it out



191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/pprof/output_formatter.rb', line 191

def print_list(dir = PProf::ProvisioningProfile::DEFAULT_DIR, options) # rubocop:disable Style/OptionalArguments
  errors = []
  Dir['*.mobileprovision', base: dir].each do |file_name|
    file = File.join(dir, file_name)
    p = PProf::ProvisioningProfile.new(file)
    next if block_given? && !yield(p)

    @output.print options[:mode] == :uuid ? p.uuid.chomp : file.chomp
    @output.print options[:zero] ? "\0" : "\n"
  rescue StandardError => e
    errors << { message: e, file: file }
  end
  errors.each { |e| print_error(e[:message], e[:file]) } unless errors.empty?
end

Prints the filtered list as a table

Parameters:

  • (defaults to: PProf::ProvisioningProfile::DEFAULT_DIR)

    The directory containing the mobileprovision files to list. Defaults to ‘~/Library/MobileDevice/Provisioning Profiles’

Yields:

  • each provisioning provile for filtering/validation The block is given ProvisioningProfile object and should return true to display the row, false to filter it out



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/pprof/output_formatter.rb', line 147

def print_table(dir = PProf::ProvisioningProfile::DEFAULT_DIR)
  count = 0
  errors = []

  table = PProf::OutputFormatter::ASCIITable.new(36, 60, 45, 25, 2, 10)
  @output.puts table.separator
  @output.puts table.row('UUID', 'Name', 'AppID', 'Expiration Date', ' ', 'Team Name')
  @output.puts table.separator

  Dir['*.mobileprovision', base: dir].each do |file_name|
    file = File.join(dir, file_name)
    begin
      p = PProf::ProvisioningProfile.new(file)

      next if block_given? && !yield(p)

      state = DateTime.now < p.expiration_date ? "\u{2705}" : "\u{274c}" # 2705=checkmark, 274C=red X
      @output.puts table.row(p.uuid, p.name, p.entitlements.app_id, p.expiration_date.to_time, state, p.team_name)
    rescue StandardError => e
      errors << { message: e, file: file }
    end
    count += 1
  end

  @output.puts table.separator
  @output.puts "#{count} Provisioning Profiles found."

  errors.each { |e| print_error(e[:message], e[:file]) } unless errors.empty?
end