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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f8bbc4de2d24fa4645d941ceec44a782cffbdc9d
4
- data.tar.gz: 6a85175f9b418c5c4f6c6e7e34e4fdbd4a3d337d
3
+ metadata.gz: fdef01fa4c03558490899178ca7b62aca5ba736a
4
+ data.tar.gz: 8d9a02735355dce8bb78b87348aff3817b6e8479
5
5
  SHA512:
6
- metadata.gz: 1369f85d45345a4834696a6687d8a5f844e9a9c0aea48af6b01af454c1c33eeb94e6216cdc40616834fab75dd8c7547aa04c1d6c76fbba53b18f8d0d1447c904
7
- data.tar.gz: 3ea5f88d064808fddf282df80ad787afd13c39d6959466541e1503aab1123270a66ea527f718b44507e8825aab79ef48ea62a51199fd1cb65da7f41bd73d2b1b
6
+ metadata.gz: e1f449d7bf48d8f8dbe44be046d6807ef345ffdd5d0577dffec6fbba258f691151bfde2d87c15debd4b2ab0fa57ed674582133915932955cd3834d10857b6608
7
+ data.tar.gz: 99c467cf89a99efb2adae5bb9caff96b5582618525f53663be9f2f539794b91cc565ac3c593124b262c4ad9507a23ed1194f0a3440500127b5c7ede3191134da
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm: 2.0.0-p598
3
+ cache: bundler
4
+ script: bundle exec rake spec
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 'xcode-install'
11
+ $ gem install xcode-install
7
12
  $ xcode-install install 6.3
8
13
  ```
9
14
 
10
15
  ## Installation
11
16
 
12
- Add this line to your application's Gemfile:
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 cp -R "/Volumes/Xcode/Xcode.app" "#{xcode_path}"`
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
- seedlist.map { |x| x.name }
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
- class Command < CLAide::Command
6
- require "xcode/install/install"
7
- require "xcode/install/list"
8
-
9
- self.abstract_command = true
10
- self.command = 'xcode-install'
11
- self.version = VERSION
12
- self.description = 'Xcode installation manager.'
13
- end
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
@@ -1,3 +1,3 @@
1
1
  module XcodeInstall
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -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.1
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-10 00:00:00.000000000 Z
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: '0'
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: '0'
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