app-tools 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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:
|