Class: Sigh::Resign

Inherits:
Object
  • Object
show all
Defined in:
lib/sigh/resign.rb

Overview

Resigns an existing ipa file

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.resign(ipa, signing_identity, provisioning_profiles, entitlements, version, display_name, short_version, bundle_version, new_bundle_id) ⇒ Object



16
17
18
# File 'lib/sigh/resign.rb', line 16

def self.resign(ipa, signing_identity, provisioning_profiles, entitlements, version, display_name, short_version, bundle_version, new_bundle_id)
  self.new.resign(ipa, signing_identity, provisioning_profiles, entitlements, version, display_name, short_version, bundle_version, new_bundle_id)
end

Instance Method Details

#ask_for_signing_identityObject



135
136
137
138
# File 'lib/sigh/resign.rb', line 135

def ask_for_signing_identity
  print_available_identities
  ask('Signing Identity: ')
end

#find_ipaObject



88
89
90
# File 'lib/sigh/resign.rb', line 88

def find_ipa
  Dir[File.join(Dir.pwd, '*.ipa')].sort { |a, b| File.mtime(a) <=> File.mtime(b) }.first
end

#find_provisioning_profileObject



92
93
94
# File 'lib/sigh/resign.rb', line 92

def find_provisioning_profile
  Dir[File.join(Dir.pwd, '*.mobileprovision')].sort { |a, b| File.mtime(a) <=> File.mtime(b) }.first
end

#find_resign_pathObject



84
85
86
# File 'lib/sigh/resign.rb', line 84

def find_resign_path
  File.join(Helper.gem_path('sigh'), 'lib', 'assets', 'resign.sh')
end

#find_signing_identity(signing_identity) ⇒ Object



96
97
98
99
100
101
102
103
# File 'lib/sigh/resign.rb', line 96

def find_signing_identity(signing_identity)
  until (signing_identity = sha1_for_signing_identity(signing_identity))
    UI.error "Couldn't find signing identity '#{signing_identity}'."
    signing_identity = ask_for_signing_identity
  end

  signing_identity
end

#get_inputs(options, args) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/sigh/resign.rb', line 66

def get_inputs(options, args)
  ipa = args.first || find_ipa || ask('Path to ipa file: ')
  signing_identity = options.signing_identity || ask_for_signing_identity
  provisioning_profiles = options.provisioning_profile || find_provisioning_profile || ask('Path to provisioning file: ')
  entitlements = options.entitlements || nil
  version = options.version_number || nil
  display_name = options.display_name || nil
  short_version = options.short_version || nil
  bundle_version = options.bundle_version || nil
  new_bundle_id = options.new_bundle_id || nil

  if options.provisioning_name
    UI.important "The provisioning_name (-n) option is not applicable to resign. You should use provisioning_profile (-p) instead"
  end

  return ipa, signing_identity, provisioning_profiles, entitlements, version, display_name, short_version, bundle_version, new_bundle_id
end

#installed_identitiesObject

Hash of available signing identities



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/sigh/resign.rb', line 141

def installed_identities
  available = request_valid_identities
  ids = {}
  available.split("\n").each do |current|
    begin
      sha1 = current.match(/[a-zA-Z0-9]{40}/).to_s
      name = current.match(/.*\"(.*)\"/)[1]
      ids[sha1] = name
    rescue
      nil
    end # the last line does not match
  end

  ids
end

#installed_identity_descriptionsObject



161
162
163
164
165
166
167
168
169
170
171
# File 'lib/sigh/resign.rb', line 161

def installed_identity_descriptions
  descriptions = []
  installed_identities.group_by { |sha1, name| name }.each do |name, identities|
    descriptions << name
    # Show SHA-1 for homonymous identities
    descriptions += identities.map do |sha1, _|
      "\t#{sha1}"
    end
  end
  descriptions
end


131
132
133
# File 'lib/sigh/resign.rb', line 131

def print_available_identities
  UI.message "Available identities: \n\t#{installed_identity_descriptions.join("\n\t")}\n"
end

#request_valid_identitiesObject



157
158
159
# File 'lib/sigh/resign.rb', line 157

def request_valid_identities
  `security find-identity -v -p codesigning`
end

#resign(ipa, signing_identity, provisioning_profiles, entitlements, version, display_name, short_version, bundle_version, new_bundle_id) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/sigh/resign.rb', line 20

def resign(ipa, signing_identity, provisioning_profiles, entitlements, version, display_name, short_version, bundle_version, new_bundle_id)
  resign_path = find_resign_path
  signing_identity = find_signing_identity(signing_identity)

  unless provisioning_profiles.kind_of?(Enumerable)
    provisioning_profiles = [provisioning_profiles]
  end

  # validate that we have valid values for all these params, we don't need to check signing_identity because `find_signing_identity` will only ever return a valid value
  validate_params(resign_path, ipa, provisioning_profiles)
  entitlements = "-e #{entitlements}" if entitlements
  provisioning_options = provisioning_profiles.map { |fst, snd| "-p #{[fst, snd].compact.map(&:shellescape).join('=')}" }.join(' ')
  version = "-n #{version}" if version
  display_name = "-d #{display_name.shellescape}" if display_name
  short_version = "--short-version #{short_version}" if short_version
  bundle_version = "--bundle-version #{bundle_version}" if bundle_version
  verbose = "-v" if $verbose
  bundle_id = "-b '#{new_bundle_id}'" if new_bundle_id

  command = [
    resign_path.shellescape,
    ipa.shellescape,
    signing_identity.shellescape,
    provisioning_options, # we are aleady shellescaping this above, when we create the provisioning_options from the provisioning_profiles
    entitlements,
    version,
    display_name,
    short_version,
    bundle_version,
    verbose,
    bundle_id,
    ipa.shellescape
  ].join(' ')

  puts command.magenta
  puts `#{command}`

  if $?.to_i == 0
    UI.success "Successfully signed #{ipa}!"
    true
  else
    UI.error "Something went wrong while code signing #{ipa}"
    false
  end
end

#run(options, args) ⇒ Object



6
7
8
9
10
11
12
13
14
# File 'lib/sigh/resign.rb', line 6

def run(options, args)
  # get the command line inputs and parse those into the vars we need...

  ipa, signing_identity, provisioning_profiles, entitlements, version, display_name, short_version, bundle_version, new_bundle_id = get_inputs(options, args)
  # ... then invoke our programmatic interface with these vars
  unless resign(ipa, signing_identity, provisioning_profiles, entitlements, version, display_name, short_version, bundle_version, new_bundle_id)
    UI.user_error!("Failed to re-sign .ipa")
  end
end

#sha1_for_signing_identity(signing_identity) ⇒ Object



105
106
107
108
109
# File 'lib/sigh/resign.rb', line 105

def sha1_for_signing_identity(signing_identity)
  identities = installed_identities
  return signing_identity if identities.keys.include?(signing_identity)
  identities.key(signing_identity)
end

#validate_ipa_file(ipa) ⇒ Object



121
122
123
# File 'lib/sigh/resign.rb', line 121

def validate_ipa_file(ipa)
  UI.user_error!("ipa file could not be found or is not an ipa file (#{ipa})") unless File.exist?(ipa) && ipa.end_with?('.ipa')
end

#validate_params(resign_path, ipa, provisioning_profiles) ⇒ Object



111
112
113
114
115
# File 'lib/sigh/resign.rb', line 111

def validate_params(resign_path, ipa, provisioning_profiles)
  validate_resign_path(resign_path)
  validate_ipa_file(ipa)
  provisioning_profiles.each { |fst, snd| validate_provisioning_file(snd || fst) }
end

#validate_provisioning_file(provisioning_profile) ⇒ Object



125
126
127
128
129
# File 'lib/sigh/resign.rb', line 125

def validate_provisioning_file(provisioning_profile)
  unless File.exist?(provisioning_profile) && provisioning_profile.end_with?('.mobileprovision')
    UI.user_error!("Provisioning profile file could not be found or is not a .mobileprovision file (#{provisioning_profile})")
  end
end

#validate_resign_path(resign_path) ⇒ Object



117
118
119
# File 'lib/sigh/resign.rb', line 117

def validate_resign_path(resign_path)
  UI.user_error!('Could not find resign.sh file. Please try re-installing the gem') unless File.exist?(resign_path)
end