app-tools 1.0.1 → 1.1.0

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
  SHA1:
3
- metadata.gz: 6326905b9573269c9ed0753e38a97b5048c0f010
4
- data.tar.gz: 92d9e9e866278888dc960b7b52afb7a98b2b8b56
3
+ metadata.gz: 3fe657959e9ea56d1406b80163d00dfd78f7b116
4
+ data.tar.gz: ff2f7a2e3878d85b6b815c59bd98883c81406526
5
5
  SHA512:
6
- metadata.gz: 7bc5ec29793733ecb8f02329a389f03618c45c1e28654748a2f1eef8ffa0146f78a0351001f0e3330c8712aeeea5bd41c1bd0a44323bc3db028b113a50b5de42
7
- data.tar.gz: be7ecd38df31f223e65f554c697c30779fc2ade885d7108b8c48c5f56c67ba48365c48100cf3e7b7933627996771daa3d312c7d9a5e6e5b6903badd4d1a9f360
6
+ metadata.gz: 7cfb0498810b3be5d6173d0c956d982c210cca09d152dab244fd611ceb5e0e49d5b647b0ddf5a036b0b414b130c267b6f2ca6d57aa31a74d5baff3298392cfe4
7
+ data.tar.gz: 5e30aca44fb2938e51deaebd1503716d5a65b85adc61542782c883d3d6df725b9e354048eb200a96230df051553b5a4d0510d9a011a01c0cebe21a7d9d88575d
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Passed in from build script
4
+ if [[ -z "$USER_NAME" || -z "$USER_PASSWORD" ]]; then
5
+ echo Must set USER_NAME and USER_PASSWORD variables. Use single quotes around the USER_PASSWORD value to escape special bash characters.
6
+ exit 1
7
+ fi
8
+
9
+ ITMSTRANSPORTER=/Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/itms/bin/iTMSTransporter
10
+
11
+ # See http://qntm.org/bash for explanation of why we escape everything in the password string
12
+
13
+ security add-generic-password -a $USER_NAME -s "app-tools/iTunesConnect" -w $(echo $USER_PASSWORD | sed -E 's/([^a-zA-Z0-9])/\1/g') -T "$ITMSTRANSPORTER" -T $(which security)
14
+
15
+ # This password can be deleted with:
16
+ #
17
+ # security delete-generic-password -a ${USER_NAME} -s "iTunesConnect - ${USER_NAME}"
18
+ #
19
+ # It can be retrieved with:
20
+ #
21
+ # security find-generic-password -a ${USER_NAME} -s "iTunesConnect - ${USER_NAME}" -w
data/bin/app-tools CHANGED
@@ -1,2 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
  puts "xcarchive2ipa - Generate IPA from XCArchive"
3
+ puts "upload2itunes - Upload an IPA to iTunesConnect"
4
+ puts "resignipa - Resign an IPA file"
data/bin/kcpass ADDED
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'methadone'
5
+ require 'app_tools/version'
6
+ require 'fileutils'
7
+ require 'highline'
8
+
9
+ module AppTools
10
+ module KcPass
11
+ include Methadone::Main
12
+ include Methadone::CLILogging
13
+ include Methadone::ExitNow
14
+
15
+ main do |action|
16
+ itunes_password = options[:p]
17
+ itunes_user = options[:u]
18
+ cli = HighLine.new
19
+ name = "app-tools-itunesconnect"
20
+
21
+ case action
22
+ when 'add'
23
+ if itunes_user.nil?
24
+ exit_now! "Must supply an iTunesConnect user email"
25
+ end
26
+
27
+ if itunes_password.nil?
28
+ itunes_password = cli.ask("Password:") { |q| q.echo = 'x' }
29
+ end
30
+
31
+ pid = Process.spawn('security', 'add-generic-password', '-a', itunes_user, '-w', itunes_password, '-s', name, '-A')
32
+ Process.wait(pid)
33
+
34
+ if $?.exitstatus == 0
35
+ info "Successfully added generic password for '#{name}'"
36
+ else
37
+ error "Unable to add password for '#{name}'"
38
+ end
39
+ when 'delete'
40
+ pid = Process.spawn('security', 'delete-generic-password', '-s', name)
41
+ Process.wait pid
42
+
43
+ if $?.exitstatus == 0
44
+ info "Deleted generic password '#{name}'"
45
+ else
46
+ error "Could not find generic password '#{name}'"
47
+ end
48
+ when 'find'
49
+ r, w = IO.pipe
50
+ pid = Process.spawn('security', 'find-generic-password', '-s', name, '-w', :out => w)
51
+ w.close
52
+ Process.wait(pid)
53
+ if $?.exitstatus != 0
54
+ exit_now! "Could not find generic password '#{name}'"
55
+ end
56
+ itunes_password = r.read
57
+ r.close
58
+ puts itunes_password
59
+ else
60
+ exit_now! "Unknown command #{action}"
61
+ end
62
+ end
63
+
64
+ description 'kcpass - Adds, removes or finds generic keychain password for use by app-tools'
65
+ version AppTools::VERSION
66
+
67
+ on("-u", "--itunes-user USER", "iTunesConnect user")
68
+ on("-p", "--itunes-password PASSWORD", "iTunesConnect password")
69
+
70
+ arg :action, "An action either add, delete or password", :require
71
+
72
+ use_log_level_option :toggle_debug_on_signal => 'USR1'
73
+
74
+ go!
75
+ end
76
+ end
data/bin/resignipa ADDED
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'methadone'
5
+ require 'app_tools/version'
6
+ require 'fileutils'
7
+ require 'cfpropertylist'
8
+ require 'zip'
9
+
10
+ #
11
+ # This project is an extraction and rewrite in Ruby of
12
+ # https://github.com/drewcrawford/CaveJohnson/blob/master/cavejohnson/__init__.py#L122
13
+ #
14
+
15
+ module AppTools
16
+ module ResignIpa
17
+ include Methadone::Main
18
+ include Methadone::CLILogging
19
+ include Methadone::ExitNow
20
+
21
+ main do |ipa_path|
22
+ unless File.exist?(ipa_path) and File.extname(ipa_path) == '.ipa'
23
+ exit_now! "Must supply an .ipa path to process"
24
+ end
25
+
26
+ ipa_basename = File.basename(ipa_path)
27
+ profile_path = options[:p]
28
+
29
+ unless File.exist?(profile_path)
30
+ exit_now! "Must supply a valid provisioning profile"
31
+ end
32
+
33
+ ## Extract the entitlements from the provisioning profile
34
+ cms_xml = `security cms -D -i "#{profile_path}"`
35
+ cms_data = CFPropertyList.native_types(CFPropertyList::List.new(:data => cms_xml).value)
36
+ entitlements_data = cms_data["Entitlements"]
37
+
38
+ ## Get the app PList
39
+ ipa_plist_data = nil
40
+
41
+ Zip::File.open(ipa_path) do |zip_file|
42
+ entry = zip_file.glob('Payload/*/Info.plist').first
43
+ plist = CFPropertyList::List.new(:data => entry.get_input_stream.read)
44
+ ipa_plist_data = CFPropertyList.native_types(plist.value)
45
+ end
46
+
47
+ ## Make sure app id and entitlements id match
48
+ entitlements_app_id = entitlements_data["application-identifier"]
49
+ ipa_app_id = ipa_plist_data["CFBundleIdentifier"]
50
+
51
+ unless entitlements_app_id.end_with?(ipa_app_id)
52
+ exit_now!("Entitlements app id #{entitlements_app_id} doesn't match Info.plist identifier #{ipa_app_id}")
53
+ end
54
+
55
+ ## Creating a temp dir to work in
56
+ temp_dir = File.join(File.dirname(ipa_path), ipa_basename + '.tmp')
57
+ contents_dir = File.join(temp_dir, "Contents")
58
+
59
+ FileUtils.rm_rf temp_dir
60
+ FileUtils.mkdir temp_dir
61
+
62
+ ## Unzip the existing IPA into the temp dir
63
+ `unzip #{ipa_path} -d #{contents_dir}`
64
+
65
+ ## Get all dirs to be signed
66
+ # See http://www.xgiovio.com/blog-photos-videos-other/blog/resign-your-ios-ipa-frameworks-and-plugins-included/
67
+ payload_dir = File.join(contents_dir, "Payload")
68
+ sign_dirs = `find -d #{payload_dir} \\( -name \\*.app -o -name \\*.framework -o -name \\*.appex -name \\*.dylib \\)`.split("\n")
69
+
70
+ ## Embed the new provisioning profile
71
+ app_dir = `find -d #{payload_dir} -name \\*.app`.split("\n")
72
+ FileUtils.cp profile_path, File.join(app_dir, "embedded.mobileprovision")
73
+
74
+ ## Get the app entitlements if any
75
+ app_path = `find -d #{payload_dir} -name \\*.app`.chomp
76
+ app_entitlements_xml = `codesign -d --entitlements :- #{app_path}`
77
+
78
+ unless app_entitlements_xml.empty?
79
+ app_entitlements_data = CFPropertyList.native_types(CFPropertyList::List.new(:data => app_entitlements_xml).value)
80
+
81
+ # TODO: What about other values?
82
+ if entitlements_data.has_key? "com.apple.developer.associated-domains"
83
+ entitlements_data["com.apple.developer.associated-domains"] = app_entitlements_data["com.apple.developer.associated-domains"]
84
+ end
85
+ end
86
+
87
+ ## Write the entitlements file
88
+ entitlements_path = File.join(temp_dir, "entitlements.plist")
89
+ File.write(entitlements_path,
90
+ entitlements_data.to_plist(:plist_format => CFPropertyList::List::FORMAT_XML))
91
+
92
+ ## Finally, resign all the files
93
+ sign_dirs.each do |sign_dir|
94
+ if sign_dir.end_with?(".framework") or sign_dir.end_with?(".dylib")
95
+ # See https://github.com/fastlane/sigh/blob/master/lib/assets/resign.sh#L412
96
+ pid = Process.spawn("codesign", "-f", "-s", "iPhone Distribution: " + options[:c], sign_dir)
97
+ else
98
+ pid = Process.spawn("codesign", "-f", "-s", "iPhone Distribution: " + options[:c], "--entitlements", entitlements_path, sign_dir)
99
+ end
100
+ Process.wait(pid)
101
+
102
+ unless $?.exitstatus == 0
103
+ exit_now! "Failed to sign files in #{sign_dir}"
104
+ end
105
+ end
106
+
107
+ ## Repack
108
+ new_ipa_dir = File.join(File.dirname(ipa_path), ipa_basename + ".resigned")
109
+ new_ipa_path = File.expand_path(File.join(new_ipa_dir, File.basename(ipa_path)))
110
+ FileUtils.rm_rf new_ipa_dir
111
+ FileUtils.mkdir new_ipa_dir
112
+
113
+ # NOTE: The zip tool
114
+ `cd #{contents_dir}; zip -r #{new_ipa_path} *`
115
+ #FileUtils.rm_rf temp_dir
116
+ puts new_ipa_path
117
+ end
118
+
119
+ description 'resignipa - Resign an IPA with a certificate and provisioning profile'
120
+ version AppTools::VERSION
121
+
122
+ on("-p", "--provisioning-profile PROFILE_PATH", "File name of the provisioning profile")
123
+ on("-c", "--certificate-name CERTIFICATE_NAME", "Name of the certificate to use for signing")
124
+
125
+ arg :ipa_path, "Original IPA file", :require
126
+
127
+ use_log_level_option :toggle_debug_on_signal => 'USR1'
128
+
129
+ go!
130
+ end
131
+ end
@@ -0,0 +1,47 @@
1
+ on run argv
2
+
3
+ tell application "Simulator" to launch
4
+
5
+ set inTime to current date
6
+ repeat
7
+ tell application "System Events"
8
+ if "Simulator" is in (get name of processes) then exit repeat
9
+ end tell
10
+ if (current date) - inTime is greater than 10 then exit repeat
11
+ delay 0.2
12
+ end repeat
13
+
14
+ tell application "Simulator" to activate
15
+
16
+ set inTime to current date
17
+ repeat
18
+ tell application "System Events"
19
+ if visible of process "Simulator" is true then exit repeat
20
+ end tell
21
+ if (current date) - inTime is greater than 10 then exit repeat
22
+ delay 0.2
23
+ end repeat
24
+
25
+ set wantChecked to ("0" is not (item 1 of argv))
26
+
27
+ tell application "System Events"
28
+ tell process "Simulator"
29
+ tell menu bar 1
30
+ tell menu bar item "Hardware"
31
+ tell menu 1
32
+ tell menu item "Keyboard"
33
+ tell menu 1
34
+ set isChecked to ("✓" is (value of attribute "AXMenuItemMarkChar" of menu item "Connect Hardware Keyboard") as string)
35
+ -- display dialog "checking: " & wantChecked & " vs " & isChecked
36
+ if wantChecked is not isChecked then
37
+ click menu item "Connect Hardware Keyboard"
38
+ end if
39
+ end tell
40
+ end tell
41
+ end tell
42
+ end tell
43
+ end tell
44
+ end tell
45
+ end tell
46
+
47
+ end run
data/bin/syncpp ADDED
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'methadone'
5
+ require 'app_tools/version'
6
+ require 'fileutils'
7
+ require 'spaceship'
8
+
9
+ #
10
+ # This project is an extraction and rewrite in Ruby of
11
+ # https://github.com/drewcrawford/CaveJohnson/blob/master/cavejohnson/__init__.py#L122
12
+ #
13
+
14
+ module AppTools
15
+ module SyncPp
16
+ include Methadone::Main
17
+ include Methadone::CLILogging
18
+ include Methadone::ExitNow
19
+
20
+ main do |profile_name|
21
+ itunes_user = options[:u]
22
+ itunes_password = options[:p]
23
+ name = "app-tools-itunesconnect"
24
+
25
+ if itunes_user.nil?
26
+ exit_now! "Must supply a user name"
27
+ end
28
+
29
+ if itunes_password.nil?
30
+ r, w = IO.pipe
31
+ pid = Process.spawn('security', 'find-generic-password', '-s', name, '-w', :out => w)
32
+ w.close
33
+ Process.wait(pid)
34
+ if $?.exitstatus != 0
35
+ exit_now! "Could not find generic password '#{name}'"
36
+ end
37
+ itunes_password = r.read.chomp
38
+ r.close
39
+ end
40
+
41
+ if itunes_password.nil?
42
+ exit_now! "No password given and non found in keychain"
43
+ end
44
+
45
+ Spaceship.login(itunes_user, itunes_password)
46
+
47
+ profiles = Spaceship.provisioning_profile.app_store.all
48
+ profile = profiles.find do |profile|
49
+ profile.name == profile_name
50
+ end
51
+
52
+ if profile.nil?
53
+ exit_now! "Provisioning profile #{profile_name} not found"
54
+ end
55
+
56
+ if profile.type != 'iOS Distribution'
57
+ exit_now! "The profile must use an iOS distribution certificate"
58
+ end
59
+
60
+ unless profile.valid?
61
+ profile.repair!
62
+ end
63
+
64
+ profile_prod_cert = profile.certificates.find do |cert|
65
+ cert.name == profile.type
66
+ end
67
+
68
+ prod_certs = Spaceship.certificate.production.all
69
+ prod_cert = prod_certs.find do |cert|
70
+ cert.id == profile.certificates.first.id
71
+ end
72
+
73
+ profile_path = "#{profile_name}.mobileprovision"
74
+
75
+ File.write(profile_path, profile.download)
76
+
77
+ puts prod_cert.name
78
+ end
79
+
80
+ description 'syncpp - Synchronize a certificate and provisioning profile'
81
+ version AppTools::VERSION
82
+
83
+ on("-u", "--itunes-user USER", "iTunesConnect user")
84
+ on("-p", "--itunes-password PASSWORD", "iTunesConnect password")
85
+
86
+ arg :profile_name, "Profile name", :required
87
+
88
+ use_log_level_option :toggle_debug_on_signal => 'USR1'
89
+
90
+ go!
91
+ end
92
+ end
data/bin/upload2itunes ADDED
@@ -0,0 +1,105 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'methadone'
5
+ require 'app_tools/version'
6
+ require 'fileutils'
7
+ require 'cfpropertylist'
8
+ require 'zip'
9
+
10
+ #
11
+ # This project is an extraction and rewrite in Ruby of
12
+ # https://github.com/drewcrawford/CaveJohnson/blob/master/cavejohnson/__init__.py#L122
13
+ #
14
+
15
+ module AppTools
16
+ module Upload2Itunes
17
+ include Methadone::Main
18
+ include Methadone::CLILogging
19
+ include Methadone::ExitNow
20
+
21
+ main do |ipa_path|
22
+ if !File.exist?(ipa_path) or !File.extname(ipa_path) == '.ipa'
23
+ exit_now! "Must supply a .ipa path to process"
24
+ end
25
+
26
+ # Create working variables
27
+ ipa_basename = File.basename(ipa_path)
28
+ itmsp_path = File.dirname(ipa_path) + '/' + ipa_basename[0...-4] + '.itmsp'
29
+
30
+ FileUtils.rm_rf itmsp_path
31
+ FileUtils.mkdir itmsp_path
32
+
33
+ plist_data = nil
34
+
35
+ Zip::File.open(ipa_path) do |zip_file|
36
+ entry = zip_file.glob('Payload/*/Info.plist').first
37
+ plist = CFPropertyList::List.new(:data => entry.get_input_stream.read)
38
+ plist_data = CFPropertyList.native_types(plist.value)
39
+ end
40
+
41
+ itunes_app_id = options[:i]
42
+ short_bundle_version = plist_data['CFBundleShortVersionString']
43
+ bundle_version = plist_data['CFBundleVersion']
44
+ bundle_identifier = plist_data['CFBundleIdentifier']
45
+ new_ipa_path = File.join(itmsp_path, ipa_basename)
46
+
47
+ FileUtils.cp ipa_path, new_ipa_path
48
+
49
+ md5 = `md5 -q #{new_ipa_path}`.chop
50
+ file_size = `stat -f "%z" #{new_ipa_path}`.chop
51
+
52
+ metadata_xml = %Q(<?xml version="1.0" encoding="UTF-8"?>
53
+ <package version="software5.2" xmlns="http://apple.com/itunes/importer">
54
+ <software_assets apple_id="#{itunes_app_id}"
55
+ bundle_short_version_string="#{short_bundle_version}"
56
+ bundle_version="#{bundle_version}"
57
+ bundle_identifier="#{bundle_identifier}">
58
+ <asset type="bundle">
59
+ <data_file>
60
+ <file_name>#{ipa_basename}</file_name>
61
+ <checksum type="md5">#{md5}</checksum>
62
+ <size>#{file_size}</size>
63
+ </data_file>
64
+ </asset>
65
+ </software_assets>
66
+ </package>)
67
+
68
+ File.open(itmsp_path + '/metadata.xml', 'w') { |file| file.write(metadata_xml) }
69
+
70
+ itmstransporter = "/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/itms/bin/iTMSTransporter"
71
+
72
+ itunes_user = options[:u]
73
+ itunes_password = options[:p]
74
+
75
+ if itunes_password.nil?
76
+ IO.popen(['security', 'find-generic-password', '-s', "app-tools-itunesconnect", '-w']) do |io|
77
+ itunes_password = io.read.chop
78
+ end
79
+ end
80
+
81
+ safe_password = itunes_password.gsub!('&', '\\\&')
82
+ IO.popen([itmstransporter, '-m', 'upload', '-u', itunes_user, '-p', safe_password, '-f', itmsp_path]) do |io|
83
+ while not io.eof?
84
+ puts io.readline()
85
+ end
86
+ end
87
+ exitstatus = $?.exitstatus
88
+ FileUtils.rm_rf itmsp_path
89
+ exitstatus
90
+ end
91
+
92
+ description 'upload2itunes - Upload an IPA file to iTunesConnect'
93
+ version AppTools::VERSION
94
+
95
+ on("-u", "--itunes-user USER", "The iTunesConnect user name")
96
+ on("-i", "--itunes-app-id APP_ID", "The iTunesConnect app ID")
97
+ on("-p", "--itunes-password PASSWORD", "The iTunes user password. If not supplied keychain entry with the name 'app-tools-itunesconnect' is used.")
98
+
99
+ arg :ipa_path, "An IPA path", :require
100
+
101
+ use_log_level_option :toggle_debug_on_signal => 'USR1'
102
+
103
+ go!
104
+ end
105
+ end
data/bin/xcarchive2ipa CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'rubygems'
4
- require 'bundler/setup'
5
4
  require 'methadone'
6
5
  require 'app_tools/version'
7
6
  require 'fileutils'
7
+ require 'zip'
8
8
 
9
9
  #
10
10
  # This project is an extraction and rewrite in Ruby of
@@ -12,13 +12,13 @@ require 'fileutils'
12
12
  #
13
13
 
14
14
  module AppTools
15
- module Xcarchive2ipa
15
+ module Xcarchive2Ipa
16
16
  include Methadone::Main
17
17
  include Methadone::CLILogging
18
18
  include Methadone::ExitNow
19
19
 
20
20
  main do |xcarchive_path|
21
- if xcarchive_path.nil? or !File.exist?(xcarchive_path)
21
+ if !Dir.exist?(xcarchive_path) or !File.extname(xcarchive_path) == '.xcarchive'
22
22
  exit_now! "Must supply a .xcarchive path to process"
23
23
  end
24
24
 
@@ -58,7 +58,7 @@ module AppTools
58
58
  puts ipa_path
59
59
  end
60
60
 
61
- description 'xcharchive2ipa - Create an iTunesConnect uploadable .ipa files from your .xcarchive'
61
+ description 'xcarchive2ipa - Create an iTunesConnect uploadable .ipa files from your .xcarchive'
62
62
  version AppTools::VERSION
63
63
 
64
64
  arg :xcarchive_path, "An XCArchive path", :require
@@ -1,3 +1,3 @@
1
1
  module AppTools
2
- VERSION = "1.0.1"
2
+ VERSION = "1.1.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: app-tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Lyon-Smith
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-23 00:00:00.000000000 Z
11
+ date: 2016-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -44,42 +44,109 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 5.0.0
47
+ version: '5.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 5.0.0
54
+ version: '5.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: methadone
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 1.9.2
61
+ version: '1.9'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 1.9.2
68
+ version: '1.9'
69
+ - !ruby/object:Gem::Dependency
70
+ name: CFPropertyList
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.3'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.3'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubyzip
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.1'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.1'
97
+ - !ruby/object:Gem::Dependency
98
+ name: spaceship
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.19'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.19'
111
+ - !ruby/object:Gem::Dependency
112
+ name: highline
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.7'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.7'
69
125
  description: |
70
126
  Generate IPA files with correct Swift and symbol files for uploading to iTunesConnect.
71
127
  Resign IPA files with correct certificate and provisioning profiles for distribution. Upload IPA files to iTunesConnect.
72
- These tools are based the CaveJohnson toolset.
73
128
  email:
74
129
  - john@jamoki.com
75
130
  executables:
131
+ - add-password-to-keychain.sh
76
132
  - app-tools
133
+ - kcpass
134
+ - resignipa
135
+ - set-hardware-keyboard.applescript
136
+ - syncpp
137
+ - upload2itunes
77
138
  - xcarchive2ipa
78
139
  extensions: []
79
140
  extra_rdoc_files: []
80
141
  files:
81
142
  - lib/app_tools/version.rb
143
+ - bin/add-password-to-keychain.sh
82
144
  - bin/app-tools
145
+ - bin/kcpass
146
+ - bin/resignipa
147
+ - bin/set-hardware-keyboard.applescript
148
+ - bin/syncpp
149
+ - bin/upload2itunes
83
150
  - bin/xcarchive2ipa
84
151
  homepage: http://github.com/jlyonsmith/app-tools
85
152
  licenses: