xcode-install 0.0.1 → 0.0.2
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/.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
|
+
[](https://travis-ci.org/neonichu/xcode-install)
|
4
|
+
[](https://coveralls.io/r/neonichu/xcode-install)
|
5
|
+
[](http://badge.fury.io/rb/xcode-install)
|
6
|
+
[](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
|
+

|
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
|