Class: FruityBuilder::IOS::Plistutil

Inherits:
Execution
  • Object
show all
Defined in:
lib/fruity_builder/plistutil.rb

Constant Summary

Constants inherited from Execution

Execution::COMMAND_RETRIES, Execution::COMMAND_TIMEOUT

Class Method Summary collapse

Methods inherited from Execution

execute, execute_with_timeout_and_retry

Class Method Details

.get_bundle_id(options = {}) ⇒ Object



16
17
18
19
20
21
22
23
# File 'lib/fruity_builder/plistutil.rb', line 16

def self.get_bundle_id(options = {})
  xml = get_xml(options)

  raise PlistutilCommandError.new('No XML was passed') unless xml
  identifiers = xml.scan(/.*CFBundleIdentifier<\/key>\n\t<string>(.*?)<\/string>/)
  identifiers << xml.scan(/.*CFBundleName<\/key>\n\t<string>(.*?)<\/string>/)
  identifiers.flatten.uniq
end

.get_bundle_id_from_app(path) ⇒ Hash

Gets properties from the IPA and returns them in a hash

Parameters:

  • path (String)

    path to the IPA/App

Returns:

  • (Hash)

    list of properties from the app



51
52
53
54
# File 'lib/fruity_builder/plistutil.rb', line 51

def self.get_bundle_id_from_app(path)
  path = Signing.unpack_ipa(path) if Signing.is_ipa?(path)
  get_bundle_id_from_plist("#{path}/Info.plist")
end

.get_bundle_id_from_plist(plist) ⇒ Hash

Gets properties from the IPA and returns them in a hash

Parameters:

  • plist (String)

    path to the plist

Returns:

  • (Hash)

    list of properties from the app

Raises:



59
60
61
62
63
64
# File 'lib/fruity_builder/plistutil.rb', line 59

def self.get_bundle_id_from_plist(plist)
  raise PlistutilCommandError.new('plistutil not found') unless plistutil_available?
  result = execute("plistutil -i #{plist}")
  raise PlistutilCommandError.new(result.stderr) if result.exit != 0
  parse_xml(result.stdout.gsub(/\n\t*/, ''))
end

.get_xml(options = {}) ⇒ Object



8
9
10
11
12
13
14
# File 'lib/fruity_builder/plistutil.rb', line 8

def self.get_xml(options = {})
  if options.key?(:file)
    IO.read(options[:file])
  elsif options.key?(:xml)
    options[:xml]
  end
end

.parse_xml(xml) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/fruity_builder/plistutil.rb', line 66

def self.parse_xml(xml)
  info = Ox.parse(xml)
  nodes = info.locate('*/dict')
  values = {}
  last_key = nil
  nodes.each do |node|
    node.nodes.each do |child|
      if child.value == 'key'
        if child.nodes.first == 'get-task-allow'
          values['get-task-allow'] = nodes.first.nodes[nodes.first.nodes.index(child)+1].value
          next
        end
        last_key = child.nodes.first
      elsif child.value == 'string'
        values[last_key] = child.nodes.first
      end
    end
  end
  values
end

.plistutil_available?Boolean

Check to ensure that plistutil is available

Returns:

  • (Boolean)

    true if plistutil is available, false otherwise



43
44
45
46
# File 'lib/fruity_builder/plistutil.rb', line 43

def self.plistutil_available?
  result = execute('which plistutil')
  result.exit == 0
end

.replace_bundle_id(options = {}) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/fruity_builder/plistutil.rb', line 25

def self.replace_bundle_id(options = {})
  xml = get_xml(options)

  raise PlistutilCommandError.new('No XML was passed') unless xml

  replacements = xml.scan(/.*CFBundleIdentifier<\/key>\n\t<string>(.*?)<\/string>/)
  replacements << xml.scan(/.*CFBundleName<\/key>\n\t<string>(.*?)<\/string>/)

  replacements.flatten.uniq.each do |replacement|
    xml = xml.gsub(replacement, options[:new_id])
  end

  IO.write(options[:file], xml) if options.key?(:file)
  xml
end