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