xcode-install 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -0
- data/README.md +12 -15
- data/lib/xcode/install.rb +67 -3
- data/lib/xcode/install/command.rb +22 -9
- data/lib/xcode/install/install.rb +1 -10
- data/lib/xcode/install/installed.rb +15 -0
- data/lib/xcode/install/uninstall.rb +33 -0
- data/lib/xcode/install/update.rb +14 -0
- data/lib/xcode/install/version.rb +1 -1
- data/xcode-install.gemspec +2 -1
- metadata +24 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fdef01fa4c03558490899178ca7b62aca5ba736a
|
4
|
+
data.tar.gz: 8d9a02735355dce8bb78b87348aff3817b6e8479
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e1f449d7bf48d8f8dbe44be046d6807ef345ffdd5d0577dffec6fbba258f691151bfde2d87c15debd4b2ab0fa57ed674582133915932955cd3834d10857b6608
|
7
|
+
data.tar.gz: 99c467cf89a99efb2adae5bb9caff96b5582618525f53663be9f2f539794b91cc565ac3c593124b262c4ad9507a23ed1194f0a3440500127b5c7ede3191134da
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,28 +1,23 @@
|
|
1
1
|
# Xcode::Install
|
2
2
|
|
3
|
+
[![Build Status](http://img.shields.io/travis/neonichu/xcode-install/master.svg?style=flat)](https://travis-ci.org/neonichu/xcode-install)
|
4
|
+
[![Coverage Status](https://coveralls.io/repos/neonichu/xcode-install/badge.svg)](https://coveralls.io/r/neonichu/xcode-install)
|
5
|
+
[![Gem Version](http://img.shields.io/gem/v/xcode-install.svg?style=flat)](http://badge.fury.io/rb/xcode-install)
|
6
|
+
[![Code Climate](http://img.shields.io/codeclimate/github/neonichu/xcode-install.svg?style=flat)](https://codeclimate.com/github/neonichu/xcode-install)
|
7
|
+
|
3
8
|
Install and update your Xcodes automatically.
|
4
9
|
|
5
10
|
```bash
|
6
|
-
$ gem install
|
11
|
+
$ gem install xcode-install
|
7
12
|
$ xcode-install install 6.3
|
8
13
|
```
|
9
14
|
|
10
15
|
## Installation
|
11
16
|
|
12
|
-
|
13
|
-
|
14
|
-
```ruby
|
15
|
-
gem 'xcode-install'
|
17
|
+
```bash
|
18
|
+
$ gem install xcode-install
|
16
19
|
```
|
17
20
|
|
18
|
-
And then execute:
|
19
|
-
|
20
|
-
$ bundle
|
21
|
-
|
22
|
-
Or install it yourself as:
|
23
|
-
|
24
|
-
$ gem install xcode-install
|
25
|
-
|
26
21
|
## Usage
|
27
22
|
|
28
23
|
XcodeInstall will ask for your credentials to access the Apple Developer Center, they are stored
|
@@ -61,12 +56,14 @@ This is a first shot, there are currently some limitations:
|
|
61
56
|
|
62
57
|
- No cleanup of caches in `~/Library/Caches/XcodeInstall` [#6](/../../issues/6)
|
63
58
|
- No automatic uninstallation [#3](/../../issues/3)
|
64
|
-
- No notion of installed versions [#1](/../../issues/1)
|
65
|
-
- No support for preleases [#5](/../../issues/5)
|
66
59
|
|
67
60
|
I will be addressing those in the future, but feel free to send PRs or report additional
|
68
61
|
bugs and shortcomings.
|
69
62
|
|
63
|
+
![](http://f.cl.ly/items/3h2O2k2K37280I331C3j/Screen%20Shot%202015-04-12%20at%2015.32.38.png)
|
64
|
+
|
65
|
+
Unfortunately, the installation size of Xcodes downloaded will be bigger than when downloading via the Mac App Store, see [#10](/../../issues/10) and feel free to dupe the radar. 📡
|
66
|
+
|
70
67
|
## Thanks
|
71
68
|
|
72
69
|
[This][3] downloading script which has been used for some inspiration, also [this][4]
|
data/lib/xcode/install.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "fastlane_core"
|
2
2
|
require "fastlane_core/developer_center/developer_center"
|
3
|
+
require "nokogiri"
|
3
4
|
require "xcode/install/command"
|
4
5
|
require "xcode/install/version"
|
5
6
|
|
@@ -61,6 +62,10 @@ module XcodeInstall
|
|
61
62
|
FileUtils.mkdir_p(CACHE_DIR)
|
62
63
|
end
|
63
64
|
|
65
|
+
def current_symlink
|
66
|
+
File.symlink?(SYMLINK_PATH) ? SYMLINK_PATH : nil
|
67
|
+
end
|
68
|
+
|
64
69
|
def download(version)
|
65
70
|
return unless exist?(version)
|
66
71
|
xcode = seedlist.select { |x| x.name == version }.first
|
@@ -74,12 +79,20 @@ module XcodeInstall
|
|
74
79
|
list_versions.include?(version)
|
75
80
|
end
|
76
81
|
|
82
|
+
def installed?(version)
|
83
|
+
installed_versions.map { |x| x.version }.include?(version)
|
84
|
+
end
|
85
|
+
|
86
|
+
def installed_versions
|
87
|
+
@installed ||= installed.map { |x| InstalledXcode.new(x) }
|
88
|
+
end
|
89
|
+
|
77
90
|
def install_dmg(dmgPath, suffix = '')
|
78
91
|
xcode_path = "/Applications/Xcode#{suffix}.app"
|
79
92
|
|
80
|
-
`hdiutil mount -noverify #{dmgPath}`
|
93
|
+
`hdiutil mount -nobrowse -noverify #{dmgPath}`
|
81
94
|
puts 'Please authenticate for Xcode installation...'
|
82
|
-
`sudo
|
95
|
+
`sudo ditto "/Volumes/Xcode/Xcode.app" "#{xcode_path}"`
|
83
96
|
`umount "/Volumes/Xcode"`
|
84
97
|
|
85
98
|
`sudo xcode-select -s #{xcode_path}`
|
@@ -95,10 +108,25 @@ module XcodeInstall
|
|
95
108
|
list_versions.join("\n")
|
96
109
|
end
|
97
110
|
|
111
|
+
def rm_list_cache
|
112
|
+
FileUtils.rm_f(LIST_FILE)
|
113
|
+
end
|
114
|
+
|
115
|
+
def symlink(version)
|
116
|
+
xcode = installed_versions.select { |x| x.version == version }.first
|
117
|
+
`sudo rm -f #{SYMLINK_PATH}` unless current_symlink.nil?
|
118
|
+
`sudo ln -sf #{xcode.path} #{SYMLINK_PATH}` unless xcode.nil? || SYMLINK_PATH.exist?
|
119
|
+
end
|
120
|
+
|
121
|
+
def symlinks_to
|
122
|
+
File.absolute_path(File.readlink(current_symlink), SYMLINK_PATH.dirname) if current_symlink
|
123
|
+
end
|
124
|
+
|
98
125
|
:private
|
99
126
|
|
100
127
|
CACHE_DIR = Pathname.new("#{ENV['HOME']}/Library/Caches/XcodeInstall")
|
101
128
|
LIST_FILE = CACHE_DIR + Pathname.new('xcodes.bin')
|
129
|
+
SYMLINK_PATH = Pathname.new('/Applications/Xcode.app')
|
102
130
|
|
103
131
|
def devcenter
|
104
132
|
@devcenter ||= FastlaneCore::DeveloperCenter.new
|
@@ -106,6 +134,7 @@ module XcodeInstall
|
|
106
134
|
|
107
135
|
def get_seedlist
|
108
136
|
@xcodes = parse_seedlist(devcenter.download_seedlist)
|
137
|
+
@xcodes += prereleases
|
109
138
|
|
110
139
|
File.open(LIST_FILE,'w') do |f|
|
111
140
|
f << Marshal.dump(xcodes)
|
@@ -114,6 +143,10 @@ module XcodeInstall
|
|
114
143
|
xcodes
|
115
144
|
end
|
116
145
|
|
146
|
+
def installed
|
147
|
+
`mdfind "kMDItemCFBundleIdentifier == 'com.apple.dt.Xcode'" 2>/dev/null`.split("\n")
|
148
|
+
end
|
149
|
+
|
117
150
|
def parse_seedlist(seedlist)
|
118
151
|
seedlist['data'].select {
|
119
152
|
|t| /^Xcode [0-9]/.match(t['name'])
|
@@ -121,7 +154,15 @@ module XcodeInstall
|
|
121
154
|
end
|
122
155
|
|
123
156
|
def list_versions
|
124
|
-
|
157
|
+
installed = installed_versions.map { |x| x.version }
|
158
|
+
seedlist.map { |x| x.name }.reject { |x| installed.include?(x) }
|
159
|
+
end
|
160
|
+
|
161
|
+
def prereleases
|
162
|
+
page = Nokogiri::HTML.parse(devcenter.download_file('/xcode/downloads/'))
|
163
|
+
links = page.xpath('//a').select { |link| link['href'].end_with?('.dmg') }
|
164
|
+
|
165
|
+
links.map { |pre| Xcode.new_prelease(pre.text.strip.gsub(/.*Xcode /, ''), pre['href']) }
|
125
166
|
end
|
126
167
|
|
127
168
|
def seedlist
|
@@ -130,6 +171,23 @@ module XcodeInstall
|
|
130
171
|
end
|
131
172
|
end
|
132
173
|
|
174
|
+
class InstalledXcode
|
175
|
+
attr_reader :path
|
176
|
+
attr_reader :version
|
177
|
+
|
178
|
+
def initialize(path)
|
179
|
+
@path = Pathname.new(path)
|
180
|
+
@version = get_version(path)
|
181
|
+
end
|
182
|
+
|
183
|
+
:private
|
184
|
+
|
185
|
+
def get_version(xcode_path)
|
186
|
+
output = `DEVELOPER_DIR='' #{xcode_path}/Contents/Developer/usr/bin/xcodebuild -version`
|
187
|
+
output.split("\n").first.split(' ')[1]
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
133
191
|
class Xcode
|
134
192
|
attr_reader :dateModified
|
135
193
|
attr_reader :name
|
@@ -142,5 +200,11 @@ module XcodeInstall
|
|
142
200
|
@path = json['files'].first['remotePath']
|
143
201
|
@url = "https://developer.apple.com/devcenter/download.action?path=#{@path}"
|
144
202
|
end
|
203
|
+
|
204
|
+
def self.new_prelease(version, url)
|
205
|
+
self.new({'name' => version,
|
206
|
+
'dateModified' => Time.now.to_i,
|
207
|
+
'files' => [{'remotePath' => url.split('=').last}]})
|
208
|
+
end
|
145
209
|
end
|
146
210
|
end
|
@@ -2,13 +2,26 @@ require 'claide'
|
|
2
2
|
require "xcode/install/version"
|
3
3
|
|
4
4
|
module XcodeInstall
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
5
|
+
class PlainInformative < StandardError
|
6
|
+
include CLAide::InformativeError
|
7
|
+
end
|
8
|
+
|
9
|
+
class Informative < PlainInformative
|
10
|
+
def message
|
11
|
+
"[!] #{super}".red
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Command < CLAide::Command
|
16
|
+
require "xcode/install/install"
|
17
|
+
require "xcode/install/installed"
|
18
|
+
require "xcode/install/list"
|
19
|
+
require "xcode/install/uninstall"
|
20
|
+
require "xcode/install/update"
|
21
|
+
|
22
|
+
self.abstract_command = true
|
23
|
+
self.command = 'xcode-install'
|
24
|
+
self.version = VERSION
|
25
|
+
self.description = 'Xcode installation manager.'
|
26
|
+
end
|
14
27
|
end
|
@@ -1,14 +1,4 @@
|
|
1
1
|
module XcodeInstall
|
2
|
-
class PlainInformative < StandardError
|
3
|
-
include CLAide::InformativeError
|
4
|
-
end
|
5
|
-
|
6
|
-
class Informative < PlainInformative
|
7
|
-
def message
|
8
|
-
"[!] #{super}".red
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
2
|
class Command
|
13
3
|
class Install < Command
|
14
4
|
self.command = 'install'
|
@@ -24,6 +14,7 @@ module XcodeInstall
|
|
24
14
|
end
|
25
15
|
|
26
16
|
def validate!
|
17
|
+
raise Informative, "Version #{@version} already installed." if @installer.installed?(@version)
|
27
18
|
raise Informative, "Version #{@version} doesn't exist." unless @installer.exist?(@version)
|
28
19
|
end
|
29
20
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module XcodeInstall
|
2
|
+
class Command
|
3
|
+
class Installed < Command
|
4
|
+
self.command = 'installed'
|
5
|
+
self.summary = 'List installed Xcodes.'
|
6
|
+
|
7
|
+
def run
|
8
|
+
installer = XcodeInstall::Installer.new
|
9
|
+
installer.installed_versions.each do |xcode|
|
10
|
+
puts "#{xcode.version}\t(#{xcode.path})"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module XcodeInstall
|
2
|
+
class Command
|
3
|
+
class Uninstall < Command
|
4
|
+
self.command = 'uninstall'
|
5
|
+
self.summary = 'Uninstall a specific version of Xcode.'
|
6
|
+
|
7
|
+
self.arguments = [
|
8
|
+
CLAide::Argument.new('VERSION', :true),
|
9
|
+
]
|
10
|
+
|
11
|
+
def initialize(argv)
|
12
|
+
@installer = Installer.new
|
13
|
+
@version = argv.shift_argument
|
14
|
+
end
|
15
|
+
|
16
|
+
def validate!
|
17
|
+
raise Informative, "Version #{@version} is not installed." unless @installer.installed?(@version)
|
18
|
+
end
|
19
|
+
|
20
|
+
def run
|
21
|
+
installed_path = @installer.installed_versions.select { |x| x.version == @version }.first
|
22
|
+
return if installed_path.nil? || installed_path.path.nil?
|
23
|
+
|
24
|
+
`sudo rm -rf #{installed_path.path}`
|
25
|
+
|
26
|
+
if @installer.symlinks_to == '/Applications/Xcode-6.3.app' #installed_path.path
|
27
|
+
newest_version = @installer.installed_versions.last
|
28
|
+
@installer.symlink(newest_version)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module XcodeInstall
|
2
|
+
class Command
|
3
|
+
class Update < Command
|
4
|
+
self.command = 'update'
|
5
|
+
self.summary = 'Update cached list of available Xcodes.'
|
6
|
+
|
7
|
+
def run
|
8
|
+
installer = XcodeInstall::Installer.new
|
9
|
+
installer.rm_list_cache
|
10
|
+
installer.list
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/xcode-install.gemspec
CHANGED
@@ -19,7 +19,8 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_dependency "claide", "~> 0.8.1"
|
22
|
-
spec.add_dependency "fastlane_core"
|
22
|
+
spec.add_dependency "fastlane_core", "~> 0.5.0"
|
23
|
+
spec.add_dependency "nokogiri", "~> 1.3"
|
23
24
|
|
24
25
|
spec.add_development_dependency "bundler", "~> 1.7"
|
25
26
|
spec.add_development_dependency "rake", "~> 10.0"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xcode-install
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Boris Bügling
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-04-
|
11
|
+
date: 2015-04-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: claide
|
@@ -28,16 +28,30 @@ dependencies:
|
|
28
28
|
name: fastlane_core
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 0.5.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.5.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: nokogiri
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
39
53
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
54
|
+
version: '1.3'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: bundler
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -75,6 +89,7 @@ extensions: []
|
|
75
89
|
extra_rdoc_files: []
|
76
90
|
files:
|
77
91
|
- .gitignore
|
92
|
+
- .travis.yml
|
78
93
|
- Gemfile
|
79
94
|
- LICENSE.txt
|
80
95
|
- README.md
|
@@ -83,7 +98,10 @@ files:
|
|
83
98
|
- lib/xcode/install.rb
|
84
99
|
- lib/xcode/install/command.rb
|
85
100
|
- lib/xcode/install/install.rb
|
101
|
+
- lib/xcode/install/installed.rb
|
86
102
|
- lib/xcode/install/list.rb
|
103
|
+
- lib/xcode/install/uninstall.rb
|
104
|
+
- lib/xcode/install/update.rb
|
87
105
|
- lib/xcode/install/version.rb
|
88
106
|
- spec/fixtures/xcode.json
|
89
107
|
- spec/fixtures/yolo.json
|