xcode-installer 0.1.1
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 +15 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +68 -0
- data/README.md +1 -0
- data/Rakefile +14 -0
- data/bin/xcode-installer +28 -0
- data/http/downloads-get.request +30 -0
- data/http/login-get.request +30 -0
- data/http/login-post.request +47 -0
- data/http/xcode-get.request +30 -0
- data/lib/xcode-installer.rb +5 -0
- data/lib/xcode-installer/agent.rb +92 -0
- data/lib/xcode-installer/apple-developer-center.rb +10 -0
- data/lib/xcode-installer/commands.rb +9 -0
- data/lib/xcode-installer/commands/download.rb +37 -0
- data/lib/xcode-installer/commands/install.rb +33 -0
- data/lib/xcode-installer/commands/list.rb +51 -0
- data/lib/xcode-installer/commands/login.rb +16 -0
- data/lib/xcode-installer/commands/logout.rb +13 -0
- data/lib/xcode-installer/helpers.rb +55 -0
- data/lib/xcode-installer/xcode-versions.rb +31 -0
- metadata +176 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
Zjc3Mzg0MjFkODNhOTUzYWFjMDI4ODhiYjRlNmY3YzVlZDNiNjUxOA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MGY0ODZhMjc1NDlhNmY4YmZlNTQ3YjUzNTZmMWZmNmVlNWRlN2U0MQ==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZDA5YjY0MGE2MWJhMGM1ZTlhNzkyNjJlZDQ1ZDg1Njk1NjViNjQ1ZDI1NDZl
|
10
|
+
ZGUwM2E0MTFkMDU5Yzg0YjI3ODk3OTVmYzkwMGY5NjAxYzU5ODNhMWM5MTMw
|
11
|
+
Y2Q0N2I2YWFiMjhkZDljYjc3MWIwMWZmMWEyZGIzMzY2MjkyYjQ=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
YTRmMDdhZDRlNGE3ZDE4YTI0OTIzZmVlZTJjYzE2YTcwNTI3YzQ0NmIyY2Qx
|
14
|
+
ODViZTdkZjhlMmFlZjI0YWFkYTk2ZWUwOGFiNjM2MmRiYWRlNTdmM2I1ODJi
|
15
|
+
ZGI2ZmFjNmRlMmM1YzU3NTY2ODRiNjI0YzdiYWM2YWRmZDk5YWE=
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
GIT
|
2
|
+
remote: git://github.com/phatblat/Mechanize-ProgressBar.git
|
3
|
+
revision: d95190161e50cbf8a18ee3263cc5255edc389004
|
4
|
+
branch: devel
|
5
|
+
specs:
|
6
|
+
mechanize-progressbar (0.2.0)
|
7
|
+
mechanize (>= 1.0.0)
|
8
|
+
progressbar (>= 0.9.0)
|
9
|
+
|
10
|
+
PATH
|
11
|
+
remote: .
|
12
|
+
specs:
|
13
|
+
xcode-installer (0.1)
|
14
|
+
commander (~> 4.1.2)
|
15
|
+
mechanize (~> 2.5.1)
|
16
|
+
mechanize-progressbar (~> 0.2.0)
|
17
|
+
security (~> 0.1.2)
|
18
|
+
terminal-table (~> 1.4.5)
|
19
|
+
trash (~> 0.2.0)
|
20
|
+
|
21
|
+
GEM
|
22
|
+
remote: https://rubygems.org/
|
23
|
+
specs:
|
24
|
+
commander (4.1.3)
|
25
|
+
highline (~> 1.6.11)
|
26
|
+
diff-lcs (1.2.4)
|
27
|
+
domain_name (0.5.11)
|
28
|
+
unf (>= 0.0.5, < 1.0.0)
|
29
|
+
highline (1.6.19)
|
30
|
+
mechanize (2.5.1)
|
31
|
+
domain_name (~> 0.5, >= 0.5.1)
|
32
|
+
mime-types (~> 1.17, >= 1.17.2)
|
33
|
+
net-http-digest_auth (~> 1.1, >= 1.1.1)
|
34
|
+
net-http-persistent (~> 2.5, >= 2.5.2)
|
35
|
+
nokogiri (~> 1.4)
|
36
|
+
ntlm-http (~> 0.1, >= 0.1.1)
|
37
|
+
webrobots (~> 0.0, >= 0.0.9)
|
38
|
+
mime-types (1.23)
|
39
|
+
net-http-digest_auth (1.3)
|
40
|
+
net-http-persistent (2.8)
|
41
|
+
nokogiri (1.5.9)
|
42
|
+
ntlm-http (0.1.1)
|
43
|
+
progressbar (0.20.0)
|
44
|
+
rake (10.0.4)
|
45
|
+
rspec (2.13.0)
|
46
|
+
rspec-core (~> 2.13.0)
|
47
|
+
rspec-expectations (~> 2.13.0)
|
48
|
+
rspec-mocks (~> 2.13.0)
|
49
|
+
rspec-core (2.13.1)
|
50
|
+
rspec-expectations (2.13.0)
|
51
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
52
|
+
rspec-mocks (2.13.1)
|
53
|
+
security (0.1.2)
|
54
|
+
terminal-table (1.4.5)
|
55
|
+
trash (0.2.0)
|
56
|
+
unf (0.1.1)
|
57
|
+
unf_ext
|
58
|
+
unf_ext (0.0.6)
|
59
|
+
webrobots (0.1.1)
|
60
|
+
|
61
|
+
PLATFORMS
|
62
|
+
ruby
|
63
|
+
|
64
|
+
DEPENDENCIES
|
65
|
+
mechanize-progressbar!
|
66
|
+
rake
|
67
|
+
rspec
|
68
|
+
xcode-installer!
|
data/README.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
### gem install xcode-installer
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "bundler"
|
2
|
+
Bundler.setup
|
3
|
+
|
4
|
+
gemspec = eval(File.read("xcode-installer.gemspec"))
|
5
|
+
|
6
|
+
task :build => "#{gemspec.full_name}.gem"
|
7
|
+
|
8
|
+
file "#{gemspec.full_name}.gem" => gemspec.files + ["xcode-installer.gemspec"] do
|
9
|
+
system "gem build xcode-installer.gemspec"
|
10
|
+
end
|
11
|
+
|
12
|
+
task :install => ["#{gemspec.full_name}.gem"] do |t|
|
13
|
+
system "gem install ./#{gemspec.full_name}.gem"
|
14
|
+
end
|
data/bin/xcode-installer
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'commander/import'
|
4
|
+
require 'terminal-table'
|
5
|
+
# require 'term/ansicolor'
|
6
|
+
require 'trash'
|
7
|
+
|
8
|
+
require 'xcode-installer'
|
9
|
+
|
10
|
+
HighLine.track_eof = false # Fix for built-in Ruby
|
11
|
+
Signal.trap("INT") { exit }
|
12
|
+
|
13
|
+
program :version, '0.1' #XcodeInstaller::VERSION
|
14
|
+
program :description, 'A command-line interface for downloading Xcode'
|
15
|
+
|
16
|
+
program :help, 'Author', 'Ben Chatelain <benchatelain@gmail.com>'
|
17
|
+
program :help, 'Website', 'https://github.com/phatblat/xcode-installer'
|
18
|
+
program :help_formatter, :compact
|
19
|
+
|
20
|
+
default_command :help
|
21
|
+
|
22
|
+
global_option '--verbose'
|
23
|
+
|
24
|
+
require 'xcode-installer/apple-developer-center'
|
25
|
+
require 'xcode-installer/xcode-versions'
|
26
|
+
require 'xcode-installer/helpers'
|
27
|
+
require 'xcode-installer/agent'
|
28
|
+
require 'xcode-installer/commands'
|
@@ -0,0 +1,30 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
3
|
+
<plist version="1.0">
|
4
|
+
<dict>
|
5
|
+
<key>baseURL</key>
|
6
|
+
<string>https://developer.apple.com/downloads/index.action</string>
|
7
|
+
<key>followRedirect</key>
|
8
|
+
<true/>
|
9
|
+
<key>handleJSONPCallbacks</key>
|
10
|
+
<false/>
|
11
|
+
<key>headers</key>
|
12
|
+
<array/>
|
13
|
+
<key>httpMethod</key>
|
14
|
+
<string>GET</string>
|
15
|
+
<key>jsonpScript</key>
|
16
|
+
<string></string>
|
17
|
+
<key>paramBodyUIChoice</key>
|
18
|
+
<integer>2</integer>
|
19
|
+
<key>parameters</key>
|
20
|
+
<array/>
|
21
|
+
<key>parametersType</key>
|
22
|
+
<integer>0</integer>
|
23
|
+
<key>presentBeforeChallenge</key>
|
24
|
+
<false/>
|
25
|
+
<key>stringEncoding</key>
|
26
|
+
<integer>4</integer>
|
27
|
+
<key>usingHTTPBody</key>
|
28
|
+
<false/>
|
29
|
+
</dict>
|
30
|
+
</plist>
|
@@ -0,0 +1,30 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
3
|
+
<plist version="1.0">
|
4
|
+
<dict>
|
5
|
+
<key>baseURL</key>
|
6
|
+
<string>https://daw.apple.com/cgi-bin/WebObjects/DSAuthWeb.woa/wa/login?appIdKey=d4f7d769c2abecc664d0dadfed6a67f943442b5e9c87524d4587a95773750cea&path=%2F%2Fdownloads%2Findex.action</string>
|
7
|
+
<key>followRedirect</key>
|
8
|
+
<true/>
|
9
|
+
<key>handleJSONPCallbacks</key>
|
10
|
+
<false/>
|
11
|
+
<key>headers</key>
|
12
|
+
<array/>
|
13
|
+
<key>httpMethod</key>
|
14
|
+
<string>GET</string>
|
15
|
+
<key>jsonpScript</key>
|
16
|
+
<string></string>
|
17
|
+
<key>paramBodyUIChoice</key>
|
18
|
+
<integer>0</integer>
|
19
|
+
<key>parameters</key>
|
20
|
+
<array/>
|
21
|
+
<key>parametersType</key>
|
22
|
+
<integer>0</integer>
|
23
|
+
<key>presentBeforeChallenge</key>
|
24
|
+
<false/>
|
25
|
+
<key>stringEncoding</key>
|
26
|
+
<integer>4</integer>
|
27
|
+
<key>usingHTTPBody</key>
|
28
|
+
<false/>
|
29
|
+
</dict>
|
30
|
+
</plist>
|
@@ -0,0 +1,47 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
3
|
+
<plist version="1.0">
|
4
|
+
<dict>
|
5
|
+
<key>baseURL</key>
|
6
|
+
<string>https://daw.apple.com/cgi-bin/WebObjects/DSAuthWeb.woa/882/wo/HGmoVjj5TruD6JxtNC1KHg/0.1.3.1.1.2.1.1.3.1.1</string>
|
7
|
+
<key>followRedirect</key>
|
8
|
+
<true/>
|
9
|
+
<key>handleJSONPCallbacks</key>
|
10
|
+
<false/>
|
11
|
+
<key>headers</key>
|
12
|
+
<array/>
|
13
|
+
<key>httpMethod</key>
|
14
|
+
<string>POST</string>
|
15
|
+
<key>jsonpScript</key>
|
16
|
+
<string></string>
|
17
|
+
<key>paramBodyUIChoice</key>
|
18
|
+
<integer>0</integer>
|
19
|
+
<key>parameters</key>
|
20
|
+
<array>
|
21
|
+
<dict>
|
22
|
+
<key>inUse</key>
|
23
|
+
<true/>
|
24
|
+
<key>parameter</key>
|
25
|
+
<string>theAccountName</string>
|
26
|
+
<key>value</key>
|
27
|
+
<string>ben.d.chatelain@kp.org</string>
|
28
|
+
</dict>
|
29
|
+
<dict>
|
30
|
+
<key>inUse</key>
|
31
|
+
<true/>
|
32
|
+
<key>parameter</key>
|
33
|
+
<string>theAccountPW</string>
|
34
|
+
<key>value</key>
|
35
|
+
<string>pharse</string>
|
36
|
+
</dict>
|
37
|
+
</array>
|
38
|
+
<key>parametersType</key>
|
39
|
+
<integer>0</integer>
|
40
|
+
<key>presentBeforeChallenge</key>
|
41
|
+
<false/>
|
42
|
+
<key>stringEncoding</key>
|
43
|
+
<integer>4</integer>
|
44
|
+
<key>usingHTTPBody</key>
|
45
|
+
<false/>
|
46
|
+
</dict>
|
47
|
+
</plist>
|
@@ -0,0 +1,30 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
3
|
+
<plist version="1.0">
|
4
|
+
<dict>
|
5
|
+
<key>baseURL</key>
|
6
|
+
<string>https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_4.6.2/xcode4620419895a.dmg</string>
|
7
|
+
<key>followRedirect</key>
|
8
|
+
<true/>
|
9
|
+
<key>handleJSONPCallbacks</key>
|
10
|
+
<false/>
|
11
|
+
<key>headers</key>
|
12
|
+
<array/>
|
13
|
+
<key>httpMethod</key>
|
14
|
+
<string>HEAD</string>
|
15
|
+
<key>jsonpScript</key>
|
16
|
+
<string></string>
|
17
|
+
<key>paramBodyUIChoice</key>
|
18
|
+
<integer>0</integer>
|
19
|
+
<key>parameters</key>
|
20
|
+
<array/>
|
21
|
+
<key>parametersType</key>
|
22
|
+
<integer>0</integer>
|
23
|
+
<key>presentBeforeChallenge</key>
|
24
|
+
<false/>
|
25
|
+
<key>stringEncoding</key>
|
26
|
+
<integer>4</integer>
|
27
|
+
<key>usingHTTPBody</key>
|
28
|
+
<false/>
|
29
|
+
</dict>
|
30
|
+
</plist>
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'mechanize'
|
2
|
+
# require 'mechanize/progressbar'
|
3
|
+
require 'security'
|
4
|
+
|
5
|
+
module XcodeInstaller
|
6
|
+
class Agent < ::Mechanize
|
7
|
+
attr_accessor :username, :password, :verbose, :dry_run
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
super
|
11
|
+
self.user_agent_alias = 'Mac Safari'
|
12
|
+
|
13
|
+
pw = Security::InternetPassword.find(:server => XcodeInstaller::AppleDeveloperCenter::HOST)
|
14
|
+
@username, @password = pw.attributes['acct'], pw.password if pw
|
15
|
+
end
|
16
|
+
|
17
|
+
def download(xcode_url)
|
18
|
+
adc_login_url = XcodeInstaller::AppleDeveloperCenter::LOGIN_URL
|
19
|
+
downloads_url = XcodeInstaller::AppleDeveloperCenter::DOWNLOADS_URL
|
20
|
+
|
21
|
+
begin
|
22
|
+
# Request login response
|
23
|
+
puts "\n>>> Login response >>>" if @verbose
|
24
|
+
response = get(adc_login_url)
|
25
|
+
if @verbose
|
26
|
+
puts "status code: #{response.code}\n"
|
27
|
+
pp response
|
28
|
+
puts cookie_jar.jar
|
29
|
+
end
|
30
|
+
|
31
|
+
# Submit login form
|
32
|
+
puts "\n>>> Submit Login Form >>>" if @verbose
|
33
|
+
form = response.form_with(:name => 'appleConnectForm')
|
34
|
+
form.theAccountName = username
|
35
|
+
form.theAccountPW = password
|
36
|
+
response = form.submit
|
37
|
+
if @verbose
|
38
|
+
puts "status code: #{response.code}\n"
|
39
|
+
pp response
|
40
|
+
puts cookie_jar.jar
|
41
|
+
end
|
42
|
+
|
43
|
+
# Request downloads response
|
44
|
+
puts "\n>>> Downloads >>>" if @verbose
|
45
|
+
response = get(downloads_url)
|
46
|
+
if @verbose
|
47
|
+
puts "status code: #{response.code}\n"
|
48
|
+
pp response
|
49
|
+
puts cookie_jar.jar
|
50
|
+
end
|
51
|
+
# Shouldn't get the login form if login was successful
|
52
|
+
form = response.form_with(:name => 'appleConnectForm')
|
53
|
+
raise UnsuccessfulAuthenticationError if form
|
54
|
+
|
55
|
+
# Download
|
56
|
+
puts "\n>>> Xcode >>>" if @verbose
|
57
|
+
|
58
|
+
if @dry_run
|
59
|
+
# HEAD request for testing
|
60
|
+
response = head(xcode_url)
|
61
|
+
if @verbose
|
62
|
+
puts "status code: #{response.code}\n"
|
63
|
+
pp response
|
64
|
+
else
|
65
|
+
puts "filename: #{response.filename}"
|
66
|
+
puts "size: #{response.header['content-length']}"
|
67
|
+
puts "last-modified: #{response.header['last-modified']}"
|
68
|
+
return response.filename
|
69
|
+
end
|
70
|
+
else
|
71
|
+
# GET request for actual download
|
72
|
+
pluggable_parser.default = Mechanize::Download
|
73
|
+
# self.progressbar{ file = get(xcode_url) }
|
74
|
+
file = get(xcode_url)
|
75
|
+
file.save
|
76
|
+
return file.filename
|
77
|
+
end
|
78
|
+
|
79
|
+
rescue Mechanize::ResponseCodeError => exception
|
80
|
+
if exception.response_code == '403'
|
81
|
+
response = exception.page
|
82
|
+
puts "status code: #{response.code}\n"
|
83
|
+
pp response
|
84
|
+
puts cookie_jar.jar
|
85
|
+
else
|
86
|
+
raise # Some other error, re-raise
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module XcodeInstaller
|
2
|
+
module AppleDeveloperCenter
|
3
|
+
|
4
|
+
HOST = "developer.apple.com"
|
5
|
+
|
6
|
+
LOGIN_URL = 'https://daw.apple.com/cgi-bin/WebObjects/DSAuthWeb.woa/wa/login?appIdKey=d4f7d769c2abecc664d0dadfed6a67f943442b5e9c87524d4587a95773750cea&path=%2F%2Fdownloads%2Findex.action'
|
7
|
+
DOWNLOADS_URL = 'https://developer.apple.com/downloads/index.action'
|
8
|
+
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
include XcodeInstaller
|
2
|
+
include XcodeInstaller::Helpers
|
3
|
+
include XcodeInstaller::XcodeVersions
|
4
|
+
|
5
|
+
require 'xcode-installer/commands/download'
|
6
|
+
require 'xcode-installer/commands/install'
|
7
|
+
require 'xcode-installer/commands/list'
|
8
|
+
require 'xcode-installer/commands/login'
|
9
|
+
require 'xcode-installer/commands/logout'
|
@@ -0,0 +1,37 @@
|
|
1
|
+
command :'download' do |c|
|
2
|
+
c.syntax = 'xcode-installer download [options]'
|
3
|
+
c.option '--dry-run', 'Enables a HEAD request instead of downloading the file'
|
4
|
+
c.option '--release STRING', 'Used to specify an old or pre-release version of Xcode. Otherwise, latest GA release of Xcode is downloaded.'
|
5
|
+
c.option '--pre-release', 'Specifies to download the latest pre-release version of Xcode.'
|
6
|
+
c.summary = 'Initiates the download'
|
7
|
+
c.description = ''
|
8
|
+
|
9
|
+
c.action do |args, options|
|
10
|
+
if options.release
|
11
|
+
xcode_version = options.release
|
12
|
+
else
|
13
|
+
if options.pre_release
|
14
|
+
xcode_version = XcodeInstaller::XcodeVersions::LATEST_DP
|
15
|
+
else
|
16
|
+
xcode_version = XcodeInstaller::XcodeVersions::LATEST_GA
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
if XcodeInstaller::XcodeVersions::GUI.has_key?(xcode_version)
|
21
|
+
xcode_url = XcodeInstaller::XcodeVersions::GUI[xcode_version]
|
22
|
+
else
|
23
|
+
puts "No Xcode release with number #{xcode_version}. Use the 'list' command to see a list of known releases."
|
24
|
+
exit
|
25
|
+
end
|
26
|
+
|
27
|
+
puts "Downloading Xcode #{xcode_version}"
|
28
|
+
puts xcode_url
|
29
|
+
|
30
|
+
agent.verbose = options.verbose
|
31
|
+
agent.dry_run = options.dry_run
|
32
|
+
try {
|
33
|
+
filename = agent.download(xcode_url)
|
34
|
+
puts "File saved to: #{Dir.pwd}/#{filename}"
|
35
|
+
}
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
command :'install' do |c|
|
2
|
+
c.syntax = 'xcode-installer install [options]'
|
3
|
+
c.option '--release STRING', 'Used to specify an old or pre-release version of Xcode. Otherwise, latest GA release of Xcode is installed.'
|
4
|
+
c.summary = 'Installs xcode from a previous download'
|
5
|
+
c.description = 'NEEDS SOME WORK - Use download and mount .dmg manually for now'
|
6
|
+
|
7
|
+
c.action do |args, options|
|
8
|
+
files = Dir.glob('*.dmg')
|
9
|
+
if files.length == 0
|
10
|
+
puts 'No .dmg files found in current directory. Run the download command first.'
|
11
|
+
return
|
12
|
+
elsif files.length > 1
|
13
|
+
puts 'Multiple .dmg files found in the current directory. Currently no support for specifying file.'
|
14
|
+
return
|
15
|
+
end
|
16
|
+
dmg_file = files[0]
|
17
|
+
|
18
|
+
# Mount disk image
|
19
|
+
mountpoint = '/Volumes/Xcode'
|
20
|
+
# TODO: get file name from elsewhere (ideally a model object)
|
21
|
+
system 'hdiutil attach -quiet xcode4620419895a.dmg'
|
22
|
+
|
23
|
+
# Trash existing install (so command is rerunnable)
|
24
|
+
destination = '/Applications/Xcode.app'
|
25
|
+
Trash.new.throw_out(destination)
|
26
|
+
|
27
|
+
# Copy into /Applications
|
28
|
+
puts 'Copying Xcode.app into Applications directory (this can take a little while)'
|
29
|
+
system "cp -R #{mountpoint}/Xcode.app #{destination}"
|
30
|
+
|
31
|
+
system 'hdiutil detach -quiet #{mountpoint}'
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
command :'list' do |c|
|
2
|
+
c.syntax = 'xcode-installer list'
|
3
|
+
c.summary = 'Lists the versions of Xcode available for downloading'
|
4
|
+
c.description = 'Shows only the Xcode GUI versions by default. Specify "all" or "cli" to show command-line tools'
|
5
|
+
|
6
|
+
c.action do |args, options|
|
7
|
+
# puts "args: #{args}"
|
8
|
+
|
9
|
+
show_all = args.include? 'all'
|
10
|
+
show_gui = args.include? 'gui'
|
11
|
+
show_cli = args.include? 'cli'
|
12
|
+
# Show GUI when no args given
|
13
|
+
show_gui = true if !show_all && !show_gui && !show_cli
|
14
|
+
|
15
|
+
# latest = XcodeInstaller::XcodeVersions::LATEST
|
16
|
+
gui_versions = XcodeInstaller::XcodeVersions::GUI
|
17
|
+
cli_versions = XcodeInstaller::XcodeVersions::CLI
|
18
|
+
|
19
|
+
if show_all || show_gui
|
20
|
+
title = 'Xcode GUI'
|
21
|
+
table = Terminal::Table.new :title => title do |t|
|
22
|
+
t << ['Version', 'Download URL']
|
23
|
+
gui_versions.keys.each do |version|
|
24
|
+
t << :separator
|
25
|
+
|
26
|
+
row = [version, gui_versions[version]]
|
27
|
+
t << row
|
28
|
+
end
|
29
|
+
end
|
30
|
+
puts table
|
31
|
+
end
|
32
|
+
|
33
|
+
# Extra line between tables
|
34
|
+
puts if show_all
|
35
|
+
|
36
|
+
if show_all || show_cli
|
37
|
+
title = 'Xcode Command-Line'
|
38
|
+
table = Terminal::Table.new :title => title do |t|
|
39
|
+
t << ['Version', 'Download URL']
|
40
|
+
cli_versions.keys.each do |version|
|
41
|
+
t << :separator
|
42
|
+
|
43
|
+
row = [version, cli_versions[version]]
|
44
|
+
t << row
|
45
|
+
end
|
46
|
+
end
|
47
|
+
puts table
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
command :login do |c|
|
2
|
+
c.syntax = 'xcode-installer login'
|
3
|
+
c.summary = 'Save account credentials'
|
4
|
+
c.description = ''
|
5
|
+
|
6
|
+
c.action do |args, options|
|
7
|
+
say_warning "You are already authenticated" if Security::InternetPassword.find(:server => XcodeInstaller::AppleDeveloperCenter::HOST)
|
8
|
+
|
9
|
+
user = ask "Username:"
|
10
|
+
pass = password "Password:"
|
11
|
+
|
12
|
+
Security::InternetPassword.add(XcodeInstaller::AppleDeveloperCenter::HOST, user, pass)
|
13
|
+
|
14
|
+
say_ok "Account credentials saved"
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
command :logout do |c|
|
2
|
+
c.syntax = 'xcode-installer logout'
|
3
|
+
c.summary = 'Remove account credentials'
|
4
|
+
c.description = ''
|
5
|
+
|
6
|
+
c.action do |args, options|
|
7
|
+
say_error "You are not authenticated" and abort unless Security::InternetPassword.find(:server => XcodeInstaller::AppleDeveloperCenter::HOST)
|
8
|
+
|
9
|
+
Security::InternetPassword.delete(:server => XcodeInstaller::AppleDeveloperCenter::HOST)
|
10
|
+
|
11
|
+
say_ok "Account credentials removed"
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# Monkey Patch Commander::UI to alias password to avoid conflicts
|
2
|
+
module Commander::UI
|
3
|
+
alias :pw :password
|
4
|
+
end
|
5
|
+
|
6
|
+
# class String
|
7
|
+
# include Term::ANSIColor
|
8
|
+
# end
|
9
|
+
|
10
|
+
module XcodeInstaller
|
11
|
+
module Helpers
|
12
|
+
def agent
|
13
|
+
unless @agent
|
14
|
+
@agent = XcodeInstaller::Agent.new
|
15
|
+
|
16
|
+
@agent.instance_eval do
|
17
|
+
def username
|
18
|
+
@username ||= ask "Username:"
|
19
|
+
end
|
20
|
+
|
21
|
+
def password
|
22
|
+
@password ||= pw "Password:"
|
23
|
+
end
|
24
|
+
|
25
|
+
# def team
|
26
|
+
# teams_by_name = {}
|
27
|
+
# page.form_with(:name => 'saveTeamSelection').radiobuttons.each do |radio|
|
28
|
+
# name = page.search("label[for=\"#{radio.dom_id}\"]").first.text.strip
|
29
|
+
# teams_by_name[name] = radio.value
|
30
|
+
# end
|
31
|
+
|
32
|
+
# name = choose "Select a team:", *teams_by_name.keys
|
33
|
+
# @team ||= teams_by_name[name]
|
34
|
+
# end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
@agent
|
39
|
+
end
|
40
|
+
|
41
|
+
def pluralize(n, singular, plural = nil)
|
42
|
+
n.to_i == 1 ? "1 #{singular}" : "#{n} #{plural || singular + 's'}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def try
|
46
|
+
return unless block_given?
|
47
|
+
|
48
|
+
begin
|
49
|
+
yield
|
50
|
+
rescue UnsuccessfulAuthenticationError
|
51
|
+
say_error "Could not authenticate with Apple Developer Center. Check that your username & password are correct, and that your membership is valid and all pending Terms of Service & agreements are accepted. If this problem continues, try logging into https://developer.apple.com/membercenter/ from a browser to see what's going on." and abort
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module XcodeInstaller
|
2
|
+
module XcodeVersions
|
3
|
+
|
4
|
+
# General availability
|
5
|
+
LATEST_GA = '4.6.3'
|
6
|
+
# Developer preview
|
7
|
+
LATEST_DP = '5-DP'
|
8
|
+
|
9
|
+
GUI = {
|
10
|
+
'5-DP' => 'https://developer.apple.com/devcenter/download.action?path=/wwdc_2013/xcode_5_developer_preview/xcode_5_developer_preview.dmg', # 2013-06-10
|
11
|
+
'4.6.3' => 'https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_4.6.3/xcode4630916281a.dmg', # 2013-06-13
|
12
|
+
'4.6.2' => 'https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_4.6.2/xcode4620419895a.dmg', # 2013-04-15
|
13
|
+
'4.6.1' => 'https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_4.6.1/xcode4610419628a.dmg', # 2013-03-14
|
14
|
+
'4.6' => 'https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_4.6/xcode460417218a.dmg' # 2013-02-20
|
15
|
+
}
|
16
|
+
|
17
|
+
# Assuming Mountain Lion for now
|
18
|
+
CLI = {
|
19
|
+
'5-DP' => 'https://developer.apple.com/downloads/download.action?path=Developer_Tools/command_line_tools_os_x_mountain_lion_for_xcode_5__june_2013/command_line_tools_mountain_lion_for_xcode_5_june_2013.dmg', # 2013-06-10
|
20
|
+
'4.6.3' => 'https://developer.apple.com/downloads/download.action?path=wwdc_2013/command_line_tools_os_x_v10.9_for_xcode_5__june_2013/command_line_tools_os_x_v10.9_for_xcode_5_developer_preview.dmg', # 2013-06-14
|
21
|
+
'4.6.2' => 'https://developer.apple.com/downloads/download.action?path=Developer_Tools/command_line_tools_os_x_mountain_lion_for_xcode__april_2013/xcode462_cltools_10_86938259a.dmg', # 2013-04-15
|
22
|
+
'4.6.1' => 'https://developer.apple.com/downloads/download.action?path=Developer_Tools/command_line_tools_os_x_mountain_lion_for_xcode__march_2013/xcode461_cltools_10_86938245a.dmg', # 2013-03-14
|
23
|
+
'4.6' => 'https://developer.apple.com/downloads/download.action?path=Developer_Tools/command_line_tools_os_x_mountain_lion_for_xcode__january_2013/xcode46cltools_10_86938131a.dmg' # 2013-02-19
|
24
|
+
}
|
25
|
+
|
26
|
+
# Lion => {
|
27
|
+
# '4.6.2' => 'https://developer.apple.com/downloads/download.action?path=Developer_Tools/command_line_tools_os_x_lion_for_xcode__april_2013/xcode462_cltools_10_76938260a.dmg'
|
28
|
+
# }
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: xcode-installer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ben Chatelain
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-06-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: commander
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.1.2
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 4.1.2
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: terminal-table
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.4.5
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.4.5
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: mechanize
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 2.5.1
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 2.5.1
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: mechanize-progressbar
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.2.0
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.2.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: security
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.1.2
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.1.2
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: trash
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.2.0
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.2.0
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ! '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ! '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rake
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ! '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
description: A command-line interface for the downloading Xcode
|
126
|
+
email: benchatelain@gmail.com
|
127
|
+
executables:
|
128
|
+
- xcode-installer
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- ./Gemfile
|
133
|
+
- ./Gemfile.lock
|
134
|
+
- ./http/downloads-get.request
|
135
|
+
- ./http/login-get.request
|
136
|
+
- ./http/login-post.request
|
137
|
+
- ./http/xcode-get.request
|
138
|
+
- ./lib/xcode-installer/agent.rb
|
139
|
+
- ./lib/xcode-installer/apple-developer-center.rb
|
140
|
+
- ./lib/xcode-installer/commands/download.rb
|
141
|
+
- ./lib/xcode-installer/commands/install.rb
|
142
|
+
- ./lib/xcode-installer/commands/list.rb
|
143
|
+
- ./lib/xcode-installer/commands/login.rb
|
144
|
+
- ./lib/xcode-installer/commands/logout.rb
|
145
|
+
- ./lib/xcode-installer/commands.rb
|
146
|
+
- ./lib/xcode-installer/helpers.rb
|
147
|
+
- ./lib/xcode-installer/xcode-versions.rb
|
148
|
+
- ./lib/xcode-installer.rb
|
149
|
+
- ./Rakefile
|
150
|
+
- ./README.md
|
151
|
+
- bin/xcode-installer
|
152
|
+
homepage: https://github.com/phatblat/xcode-installer
|
153
|
+
licenses:
|
154
|
+
- MIT
|
155
|
+
metadata: {}
|
156
|
+
post_install_message:
|
157
|
+
rdoc_options: []
|
158
|
+
require_paths:
|
159
|
+
- lib
|
160
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
161
|
+
requirements:
|
162
|
+
- - ! '>='
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '0'
|
165
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
166
|
+
requirements:
|
167
|
+
- - ! '>='
|
168
|
+
- !ruby/object:Gem::Version
|
169
|
+
version: '0'
|
170
|
+
requirements: []
|
171
|
+
rubyforge_project:
|
172
|
+
rubygems_version: 2.0.3
|
173
|
+
signing_key:
|
174
|
+
specification_version: 4
|
175
|
+
summary: XcodeInstaller
|
176
|
+
test_files: []
|