xcode-install 0.0.3 → 0.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/lib/xcode/install.rb +48 -6
- data/lib/xcode/install/cleanup.rb +14 -0
- data/lib/xcode/install/command.rb +1 -0
- data/lib/xcode/install/install.rb +10 -2
- data/lib/xcode/install/version.rb +1 -1
- data/spec/fixtures/xcode_63.json +46 -0
- data/spec/install_spec.rb +25 -0
- data/spec/json_spec.rb +1 -0
- data/spec/spec_helper.rb +3 -0
- metadata +6 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f35f3bf3a7aac145047a95d07c5bdb1344600dc
|
4
|
+
data.tar.gz: 283c261a2a28d86116dcfcad1677f2df5e000a2d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 99fb6cb82e6131948512f46f082c7eff162e4c414bba18da8c32d36346ff8080ea3ade45a413d43973c43098346443488a8ec6f6b947439ad4e1c82f536f9fd5
|
7
|
+
data.tar.gz: 760efcea4598e41a98dde02f23345ed7de599d70dd43ee6782da57c1a8a6be26481db2df9b7cedf5079eb4db09661001e9486b279a8908a8aa77c8eb1384da64
|
data/lib/xcode/install.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require "fastlane_core"
|
2
2
|
require "fastlane_core/developer_center/developer_center"
|
3
3
|
require "nokogiri"
|
4
|
+
require "rubygems/version"
|
4
5
|
require "xcode/install/command"
|
5
6
|
require "xcode/install/version"
|
6
7
|
|
@@ -62,6 +63,10 @@ module XcodeInstall
|
|
62
63
|
FileUtils.mkdir_p(CACHE_DIR)
|
63
64
|
end
|
64
65
|
|
66
|
+
def cache_dir
|
67
|
+
CACHE_DIR
|
68
|
+
end
|
69
|
+
|
65
70
|
def current_symlink
|
66
71
|
File.symlink?(SYMLINK_PATH) ? SYMLINK_PATH : nil
|
67
72
|
end
|
@@ -84,20 +89,38 @@ module XcodeInstall
|
|
84
89
|
end
|
85
90
|
|
86
91
|
def installed_versions
|
87
|
-
@installed ||= installed.map { |x| InstalledXcode.new(x) }
|
92
|
+
@installed ||= installed.map { |x| InstalledXcode.new(x) }.sort {
|
93
|
+
|a,b| Gem::Version.new(a.version) <=> Gem::Version.new(b.version)
|
94
|
+
}
|
88
95
|
end
|
89
96
|
|
90
|
-
def install_dmg(dmgPath, suffix = '')
|
97
|
+
def install_dmg(dmgPath, suffix = '', switch = true, clean = true)
|
91
98
|
xcode_path = "/Applications/Xcode#{suffix}.app"
|
92
99
|
|
93
100
|
`hdiutil mount -nobrowse -noverify #{dmgPath}`
|
94
101
|
puts 'Please authenticate for Xcode installation...'
|
95
102
|
source = Dir.glob('/Volumes/Xcode/Xcode*.app').first
|
103
|
+
|
104
|
+
if source.nil?
|
105
|
+
puts 'No `Xcode.app` found in DMG.'
|
106
|
+
return
|
107
|
+
end
|
108
|
+
|
96
109
|
`sudo ditto "#{source}" "#{xcode_path}"`
|
97
110
|
`umount "/Volumes/Xcode"`
|
98
111
|
|
99
|
-
|
100
|
-
|
112
|
+
enable_developer_mode
|
113
|
+
`sudo xcodebuild -license` unless xcode_license_approved?
|
114
|
+
|
115
|
+
if switch
|
116
|
+
`sudo rm -f #{SYMLINK_PATH}` unless current_symlink.nil?
|
117
|
+
`sudo ln -sf #{xcode_path} #{SYMLINK_PATH}` unless SYMLINK_PATH.exist?
|
118
|
+
|
119
|
+
`sudo xcode-select --switch #{xcode_path}`
|
120
|
+
puts `xcodebuild -version`
|
121
|
+
end
|
122
|
+
|
123
|
+
FileUtils.rm_f(dmgPath) if clean
|
101
124
|
end
|
102
125
|
|
103
126
|
def list_current
|
@@ -127,12 +150,18 @@ module XcodeInstall
|
|
127
150
|
|
128
151
|
CACHE_DIR = Pathname.new("#{ENV['HOME']}/Library/Caches/XcodeInstall")
|
129
152
|
LIST_FILE = CACHE_DIR + Pathname.new('xcodes.bin')
|
153
|
+
MINIMUM_VERSION = Gem::Version.new('4.3')
|
130
154
|
SYMLINK_PATH = Pathname.new('/Applications/Xcode.app')
|
131
155
|
|
132
156
|
def devcenter
|
133
157
|
@devcenter ||= FastlaneCore::DeveloperCenter.new
|
134
158
|
end
|
135
159
|
|
160
|
+
def enable_developer_mode
|
161
|
+
`sudo /usr/sbin/DevToolsSecurity -enable`
|
162
|
+
`sudo /usr/sbin/dseditgroup -o edit -t group -a staff _developer`
|
163
|
+
end
|
164
|
+
|
136
165
|
def get_seedlist
|
137
166
|
@xcodes = parse_seedlist(devcenter.download_seedlist)
|
138
167
|
@xcodes += prereleases
|
@@ -151,7 +180,9 @@ module XcodeInstall
|
|
151
180
|
def parse_seedlist(seedlist)
|
152
181
|
seedlist['data'].select {
|
153
182
|
|t| /^Xcode [0-9]/.match(t['name'])
|
154
|
-
}.map { |x| Xcode.new(x) }.
|
183
|
+
}.map { |x| Xcode.new(x) }.reject { |x| x.version < MINIMUM_VERSION }.sort {
|
184
|
+
|a,b| a.dateModified <=> b.dateModified
|
185
|
+
}
|
155
186
|
end
|
156
187
|
|
157
188
|
def list_versions
|
@@ -170,6 +201,10 @@ module XcodeInstall
|
|
170
201
|
@xcodes = Marshal.load(File.read(LIST_FILE)) if LIST_FILE.exist? && xcodes.nil?
|
171
202
|
xcodes || get_seedlist
|
172
203
|
end
|
204
|
+
|
205
|
+
def xcode_license_approved?
|
206
|
+
!(`/usr/bin/xcrun clang 2>&1` =~ /license/ && !$?.success?)
|
207
|
+
end
|
173
208
|
end
|
174
209
|
|
175
210
|
class InstalledXcode
|
@@ -194,12 +229,19 @@ module XcodeInstall
|
|
194
229
|
attr_reader :name
|
195
230
|
attr_reader :path
|
196
231
|
attr_reader :url
|
232
|
+
attr_reader :version
|
197
233
|
|
198
234
|
def initialize(json)
|
199
235
|
@dateModified = json['dateModified'].to_i
|
200
236
|
@name = json['name'].gsub(/^Xcode /, '')
|
201
237
|
@path = json['files'].first['remotePath']
|
202
238
|
@url = "https://developer.apple.com/devcenter/download.action?path=#{@path}"
|
239
|
+
|
240
|
+
begin
|
241
|
+
@version = Gem::Version.new(@name.split(' ')[0])
|
242
|
+
rescue
|
243
|
+
@version = Installer::MINIMUM_VERSION
|
244
|
+
end
|
203
245
|
end
|
204
246
|
|
205
247
|
def self.new_prelease(version, url)
|
@@ -208,4 +250,4 @@ module XcodeInstall
|
|
208
250
|
'files' => [{'remotePath' => url.split('=').last}]})
|
209
251
|
end
|
210
252
|
end
|
211
|
-
end
|
253
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module XcodeInstall
|
2
|
+
class Command
|
3
|
+
class Cleanup < Command
|
4
|
+
self.command = 'cleanup'
|
5
|
+
self.summary = 'Cleanup cached downloads.'
|
6
|
+
|
7
|
+
def run
|
8
|
+
installer = XcodeInstall::Installer.new
|
9
|
+
return if installer.cache_dir.nil? || installer.cache_dir.to_s.length < 5
|
10
|
+
FileUtils.rm_f(Dir.glob("#{installer.cache_dir}/*"))
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -8,9 +8,17 @@ module XcodeInstall
|
|
8
8
|
CLAide::Argument.new('VERSION', :true),
|
9
9
|
]
|
10
10
|
|
11
|
+
def self.options
|
12
|
+
[['--no-switch', 'Don’t switch to this version after installation'],
|
13
|
+
['--no-clean', 'Don’t delete DMG after installation.']].concat(super)
|
14
|
+
end
|
15
|
+
|
11
16
|
def initialize(argv)
|
12
17
|
@installer = Installer.new
|
13
18
|
@version = argv.shift_argument
|
19
|
+
@should_clean = argv.flag?('clean', true)
|
20
|
+
@should_switch = argv.flag?('switch', true)
|
21
|
+
super
|
14
22
|
end
|
15
23
|
|
16
24
|
def validate!
|
@@ -22,8 +30,8 @@ module XcodeInstall
|
|
22
30
|
dmgPath = @installer.download(@version)
|
23
31
|
raise Informative, "Failed to download Xcode #{@version}." if dmgPath.nil?
|
24
32
|
|
25
|
-
@installer.install_dmg(dmgPath, "-#{@version}")
|
33
|
+
@installer.install_dmg(dmgPath, "-#{@version.split(' ')[0]}", @should_switch, @should_clean)
|
26
34
|
end
|
27
35
|
end
|
28
36
|
end
|
29
|
-
end
|
37
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
{
|
2
|
+
"active": true,
|
3
|
+
"availableInMemberSite": true,
|
4
|
+
"categories": [
|
5
|
+
{
|
6
|
+
"active": null,
|
7
|
+
"dateCreated": 1052825460000,
|
8
|
+
"dateModified": 1079108316000,
|
9
|
+
"enabled": true,
|
10
|
+
"id": 187,
|
11
|
+
"name": "Developer Tools",
|
12
|
+
"sortOrder": 28
|
13
|
+
}
|
14
|
+
],
|
15
|
+
"dateAvailable": null,
|
16
|
+
"dateCreated": 1425695047000,
|
17
|
+
"dateDisabled": null,
|
18
|
+
"dateModified": 1425943753000,
|
19
|
+
"description": "This is the complete Xcode developer toolset for Mac, iPhone, and iPad. It includes the Xcode IDE, iOS Simulator, and all required tools and frameworks for building OS X and iOS apps.",
|
20
|
+
"files": [
|
21
|
+
{
|
22
|
+
"active": true,
|
23
|
+
"dateCreated": 1425696402000,
|
24
|
+
"dateModified": 1425929405000,
|
25
|
+
"fileSize": 2778059898,
|
26
|
+
"format": {
|
27
|
+
"active": null,
|
28
|
+
"dateCreated": 1066327569000,
|
29
|
+
"dateModified": null,
|
30
|
+
"description": "Disk Image",
|
31
|
+
"extension": ".dmg",
|
32
|
+
"id": 12
|
33
|
+
},
|
34
|
+
"id": 35240,
|
35
|
+
"name": "Xcode 6.3",
|
36
|
+
"remotePath": "/Developer_Tools/Xcode_6.2/Xcode_6.2.dmg",
|
37
|
+
"sortOrder": null,
|
38
|
+
"state": "ENABLED"
|
39
|
+
}
|
40
|
+
],
|
41
|
+
"id": 23600,
|
42
|
+
"name": "Xcode 6.3",
|
43
|
+
"prerelease": false,
|
44
|
+
"releasedSeed": true,
|
45
|
+
"state": "ENABLED"
|
46
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.expand_path('../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
module XcodeInstall
|
4
|
+
describe Command::Install do
|
5
|
+
before do
|
6
|
+
Installer.any_instance.stubs(:exists).returns(true)
|
7
|
+
Installer.any_instance.stubs(:installed).returns([])
|
8
|
+
fixture = Pathname.new('spec/fixtures/xcode_63.json').read
|
9
|
+
xcode = Xcode.new(JSON.parse(fixture))
|
10
|
+
Installer.any_instance.stubs(:seedlist).returns([xcode])
|
11
|
+
end
|
12
|
+
|
13
|
+
it "downloads and installs" do
|
14
|
+
Installer.any_instance.expects(:download).with("6.3").returns("/some/path")
|
15
|
+
Installer.any_instance.expects(:install_dmg).with("/some/path", "-6.3", true, true)
|
16
|
+
Command::Install.run(["6.3"])
|
17
|
+
end
|
18
|
+
|
19
|
+
it "downloads and installs and does not switch if --no-switch given" do
|
20
|
+
Installer.any_instance.expects(:download).with("6.3").returns("/some/path")
|
21
|
+
Installer.any_instance.expects(:install_dmg).with("/some/path", "-6.3", false, true)
|
22
|
+
Command::Install.run(["6.3", "--no-switch"])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/spec/json_spec.rb
CHANGED
@@ -16,6 +16,7 @@ module XcodeInstall
|
|
16
16
|
installer = Installer.new
|
17
17
|
|
18
18
|
seedlist = installer.send(:parse_seedlist, JSON.parse(fixture))
|
19
|
+
installer.stubs(:installed_versions).returns([])
|
19
20
|
installer.stubs(:xcodes).returns(seedlist)
|
20
21
|
|
21
22
|
installer.list.should == "6.1\n6.1.1\n6.2"
|
data/spec/spec_helper.rb
CHANGED
@@ -6,6 +6,9 @@ ROOT = Pathname.new(File.expand_path('../../', __FILE__))
|
|
6
6
|
$:.unshift((ROOT + 'lib').to_s)
|
7
7
|
$:.unshift((ROOT + 'spec').to_s)
|
8
8
|
|
9
|
+
ENV['DELIVER_USER'] = "xcode-install"
|
10
|
+
ENV['DELIVER_PASSWORD'] = "12345password"
|
11
|
+
|
9
12
|
require 'bundler/setup'
|
10
13
|
require 'bacon'
|
11
14
|
require 'mocha-on-bacon'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
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.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Boris Bügling
|
@@ -96,6 +96,7 @@ files:
|
|
96
96
|
- Rakefile
|
97
97
|
- bin/xcode-install
|
98
98
|
- lib/xcode/install.rb
|
99
|
+
- lib/xcode/install/cleanup.rb
|
99
100
|
- lib/xcode/install/command.rb
|
100
101
|
- lib/xcode/install/install.rb
|
101
102
|
- lib/xcode/install/installed.rb
|
@@ -104,7 +105,9 @@ files:
|
|
104
105
|
- lib/xcode/install/update.rb
|
105
106
|
- lib/xcode/install/version.rb
|
106
107
|
- spec/fixtures/xcode.json
|
108
|
+
- spec/fixtures/xcode_63.json
|
107
109
|
- spec/fixtures/yolo.json
|
110
|
+
- spec/install_spec.rb
|
108
111
|
- spec/json_spec.rb
|
109
112
|
- spec/spec_helper.rb
|
110
113
|
- xcode-install.gemspec
|
@@ -134,7 +137,9 @@ specification_version: 4
|
|
134
137
|
summary: Xcode installation manager.
|
135
138
|
test_files:
|
136
139
|
- spec/fixtures/xcode.json
|
140
|
+
- spec/fixtures/xcode_63.json
|
137
141
|
- spec/fixtures/yolo.json
|
142
|
+
- spec/install_spec.rb
|
138
143
|
- spec/json_spec.rb
|
139
144
|
- spec/spec_helper.rb
|
140
145
|
has_rdoc:
|