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 +4 -4
- data/bin/add-password-to-keychain.sh +21 -0
- data/bin/app-tools +2 -0
- data/bin/kcpass +76 -0
- data/bin/resignipa +131 -0
- data/bin/set-hardware-keyboard.applescript +47 -0
- data/bin/syncpp +92 -0
- data/bin/upload2itunes +105 -0
- data/bin/xcarchive2ipa +4 -4
- data/lib/app_tools/version.rb +1 -1
- metadata +74 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3fe657959e9ea56d1406b80163d00dfd78f7b116
|
4
|
+
data.tar.gz: ff2f7a2e3878d85b6b815c59bd98883c81406526
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
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
|
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
|
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 '
|
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
|
data/lib/app_tools/version.rb
CHANGED
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
|
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-
|
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
|
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
|
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
|
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
|
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:
|