mac_setup 0.3.0 → 0.4.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/.rubocop.yml +34 -23
- data/.ruby-version +1 -1
- data/.travis.yml +1 -3
- data/Gemfile +1 -3
- data/Rakefile +5 -5
- data/bin/console +3 -3
- data/exe/mac_setup +5 -5
- data/lib/mac_setup/brewfile_installer.rb +46 -0
- data/lib/mac_setup/configuration.rb +5 -29
- data/lib/mac_setup/git_repo_installer.rb +7 -7
- data/lib/mac_setup/homebrew_installer.rb +9 -18
- data/lib/mac_setup/script_installer.rb +6 -5
- data/lib/mac_setup/services_installer.rb +67 -0
- data/lib/mac_setup/shell.rb +5 -0
- data/lib/mac_setup/symlink_installer.rb +94 -34
- data/lib/mac_setup/system_status.rb +2 -36
- data/lib/mac_setup/version.rb +1 -1
- data/lib/mac_setup.rb +24 -31
- data/mac_setup.gemspec +14 -14
- metadata +5 -8
- data/lib/mac_setup/cask_installer.rb +0 -20
- data/lib/mac_setup/command_line_tools_installer.rb +0 -30
- data/lib/mac_setup/formula_installer.rb +0 -57
- data/lib/mac_setup/launch_agent_installer.rb +0 -35
- data/lib/mac_setup/tap_installer.rb +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ed05ad2d53e582a5b346bae37ba77ac67d98f95
|
4
|
+
data.tar.gz: e1630c23a4feaa83beb46bb2b170875ed19cd762
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0a70cff07477ff478713745316931a355b54f4246a76b675612afc5b592ddfb1e9853db58aa3d512e9a1c1500ebf88c04563983bc13ac1a6481ec042fd98726
|
7
|
+
data.tar.gz: ffc90185c1df4ccedd9dd00056c150f6252eb7366e13a4edc31402db47bcb06e14630bbb1ef4c9d9fe89fad8ce402a4a8ea1bafb2201bb0574e76db09b90b689
|
data/.rubocop.yml
CHANGED
@@ -1,38 +1,35 @@
|
|
1
1
|
require: rubocop-rspec
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
Metrics/LineLength:
|
7
|
-
Max: 100
|
8
|
-
Exclude:
|
9
|
-
- 'spec/**/*'
|
3
|
+
AllCops:
|
4
|
+
DisplayCopNames: true
|
10
5
|
|
11
|
-
|
12
|
-
Exclude:
|
13
|
-
- 'spec/**/*'
|
6
|
+
## Style
|
14
7
|
|
8
|
+
Style/Documentation:
|
9
|
+
Enabled: false
|
15
10
|
Style/SingleSpaceBeforeFirstArg:
|
16
11
|
Enabled: false
|
17
|
-
|
18
12
|
Style/AccessorMethodName:
|
19
13
|
Enabled: false
|
14
|
+
Style/SymbolArray:
|
15
|
+
Enabled: false
|
16
|
+
Style/SignalException:
|
17
|
+
Enabled: false
|
18
|
+
Style/NumericLiterals:
|
19
|
+
Enabled: false
|
20
|
+
Style/WordArray:
|
21
|
+
Enabled: false
|
20
22
|
|
21
23
|
Style/GuardClause:
|
22
24
|
Enabled: true
|
23
|
-
|
24
25
|
Style/MethodCalledOnDoEndBlock:
|
25
26
|
Enabled: true
|
26
|
-
|
27
|
-
|
28
|
-
Enabled: false
|
27
|
+
Style/CollectionMethods:
|
28
|
+
Enabled: true
|
29
29
|
|
30
30
|
Style/TrivialAccessors:
|
31
31
|
ExactNameMatch: true
|
32
32
|
|
33
|
-
Style/CollectionMethods:
|
34
|
-
Enabled: true
|
35
|
-
|
36
33
|
Style/PredicateName:
|
37
34
|
NamePrefix:
|
38
35
|
- is_
|
@@ -41,16 +38,30 @@ Style/PredicateName:
|
|
41
38
|
- is_
|
42
39
|
- have_
|
43
40
|
|
44
|
-
Style/
|
45
|
-
|
41
|
+
Style/StringLiterals:
|
42
|
+
EnforcedStyle: double_quotes
|
46
43
|
|
47
|
-
|
48
|
-
|
44
|
+
## Metrics
|
45
|
+
|
46
|
+
Metrics/LineLength:
|
47
|
+
Max: 100
|
48
|
+
Exclude:
|
49
|
+
- 'spec/**/*'
|
50
|
+
|
51
|
+
Metrics/MethodLength:
|
52
|
+
Max: 15
|
53
|
+
Exclude:
|
54
|
+
- 'spec/**/*'
|
55
|
+
|
56
|
+
Metrics/CyclomaticComplexity:
|
57
|
+
Max: 10
|
58
|
+
|
59
|
+
## RSpec
|
49
60
|
|
50
61
|
RSpec/DescribeClass:
|
51
62
|
Enabled: false
|
52
63
|
RSpec/DescribedClass:
|
53
|
-
Enabled:
|
64
|
+
Enabled: true
|
54
65
|
RSpec/DescribeMethod:
|
55
66
|
Enabled: false
|
56
67
|
RSpec/FilePath:
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.0.0
|
1
|
+
2.0.0-p648
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
require "rubocop/rake_task"
|
4
4
|
|
5
5
|
RuboCop::RakeTask.new(:rubocop) do |task|
|
6
|
-
task.options = [
|
6
|
+
task.options = ["--display-style-guide"]
|
7
7
|
end
|
8
8
|
|
9
9
|
RSpec::Core::RakeTask.new(:spec)
|
10
10
|
|
11
|
-
task default:
|
11
|
+
task default: "rubocop"
|
12
12
|
task default: :spec
|
data/bin/console
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "bundler/setup"
|
4
|
+
require "mac_setup"
|
5
5
|
|
6
6
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
7
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -10,5 +10,5 @@ require 'mac_setup'
|
|
10
10
|
# require "pry"
|
11
11
|
# Pry.start
|
12
12
|
|
13
|
-
require
|
13
|
+
require "irb"
|
14
14
|
IRB.start
|
data/exe/mac_setup
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
3
|
+
require "mac_setup"
|
4
4
|
|
5
|
-
DEFAULT_CONFIG_PATH =
|
5
|
+
DEFAULT_CONFIG_PATH = "~/.mac_setup/config.yml"
|
6
6
|
|
7
7
|
command = ARGV.shift
|
8
|
-
options = ARGV.select { |arg| arg.start_with?(
|
8
|
+
options = ARGV.select { |arg| arg.start_with?("--") }
|
9
9
|
|
10
10
|
case command
|
11
|
-
when
|
11
|
+
when "bootstrap"
|
12
12
|
MacSetup.bootstrap(ARGV[0])
|
13
|
-
when
|
13
|
+
when "install"
|
14
14
|
config_path = (ARGV - options)[0] || File.expand_path(DEFAULT_CONFIG_PATH)
|
15
15
|
|
16
16
|
if File.exist?(config_path)
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require_relative "shell"
|
2
|
+
|
3
|
+
module MacSetup
|
4
|
+
class BrewfileInstaller
|
5
|
+
BUNDLE_TAP = "homebrew/bundle"
|
6
|
+
|
7
|
+
attr_reader :config, :status
|
8
|
+
|
9
|
+
def self.run(config, status)
|
10
|
+
new(config, status).run
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(config, status)
|
14
|
+
@config = config
|
15
|
+
@status = status
|
16
|
+
end
|
17
|
+
|
18
|
+
def run
|
19
|
+
tap_bundle
|
20
|
+
sign_in_to_mas
|
21
|
+
install_brewfile
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def tap_bundle
|
27
|
+
return if bundle_already_tapped?
|
28
|
+
|
29
|
+
Shell.run("brew tap #{BUNDLE_TAP}")
|
30
|
+
end
|
31
|
+
|
32
|
+
def sign_in_to_mas
|
33
|
+
return unless brewfile.read =~ /^mas /
|
34
|
+
apple_id = Shell.ask("What is your Apple ID?")
|
35
|
+
Shell.run("mas signin --dialog #{apple_id}")
|
36
|
+
end
|
37
|
+
|
38
|
+
def install_brewfile
|
39
|
+
Shell.run("brew bundle --global")
|
40
|
+
end
|
41
|
+
|
42
|
+
def bundle_already_tapped?
|
43
|
+
status.installed_taps.include?(BUNDLE_TAP)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -1,47 +1,23 @@
|
|
1
|
-
require
|
1
|
+
require "yaml"
|
2
2
|
|
3
3
|
module MacSetup
|
4
4
|
class Configuration
|
5
|
-
CASK_FORMULA = 'caskroom/cask/brew-cask'
|
6
|
-
|
7
5
|
attr_reader :config
|
8
6
|
|
9
7
|
def initialize(config_path)
|
10
8
|
@config = YAML.load_file(config_path)
|
11
9
|
end
|
12
10
|
|
13
|
-
def
|
14
|
-
(@config[
|
15
|
-
end
|
16
|
-
|
17
|
-
def formulas
|
18
|
-
add_cask(@config['formulas'] || []).uniq
|
19
|
-
end
|
20
|
-
|
21
|
-
def casks
|
22
|
-
(@config['casks'] || []).uniq
|
23
|
-
end
|
24
|
-
|
25
|
-
def launch_agents
|
26
|
-
(@config['launch_agents'] || []).uniq
|
11
|
+
def services
|
12
|
+
(@config["services"] || []).uniq
|
27
13
|
end
|
28
14
|
|
29
15
|
def git_repos
|
30
|
-
(@config[
|
31
|
-
end
|
32
|
-
|
33
|
-
def scripts
|
34
|
-
(@config['scripts'] || []).uniq
|
16
|
+
(@config["git_repos"] || []).uniq
|
35
17
|
end
|
36
18
|
|
37
19
|
def symlinks
|
38
|
-
(@config[
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
|
43
|
-
def add_cask(specified_formulas)
|
44
|
-
casks.any? ? specified_formulas << CASK_FORMULA : specified_formulas
|
20
|
+
(@config["symlinks"] || []).uniq
|
45
21
|
end
|
46
22
|
end
|
47
23
|
end
|
@@ -1,12 +1,12 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "shell"
|
2
2
|
|
3
3
|
module MacSetup
|
4
4
|
class GitRepoInstaller
|
5
|
-
def self.run(config)
|
5
|
+
def self.run(config, _status)
|
6
6
|
repos = config.git_repos
|
7
7
|
return if repos.none?
|
8
8
|
|
9
|
-
puts
|
9
|
+
puts "Installing Git Repos..."
|
10
10
|
|
11
11
|
repos.each do |repo_and_path|
|
12
12
|
repo, install_path = repo_and_path.to_a.flatten
|
@@ -22,15 +22,15 @@ module MacSetup
|
|
22
22
|
print "Installing #{repo}..."
|
23
23
|
url = expand_url(repo)
|
24
24
|
Shell.run(%(git clone --recursive #{url} "#{install_path}"))
|
25
|
-
puts
|
25
|
+
puts "Ok"
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
29
|
def self.update_repo(install_path)
|
30
30
|
Dir.chdir(install_path) do
|
31
31
|
if can_update?
|
32
|
-
Shell.run(
|
33
|
-
puts
|
32
|
+
Shell.run("git pull && git submodule update --init --recursive")
|
33
|
+
puts "Ok"
|
34
34
|
else
|
35
35
|
puts "\nCan't update. Unstaged changes in #{install_path}"
|
36
36
|
end
|
@@ -38,7 +38,7 @@ module MacSetup
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def self.can_update?
|
41
|
-
Shell.run(
|
41
|
+
Shell.run("git status --porcelain").empty?
|
42
42
|
end
|
43
43
|
|
44
44
|
def self.expand_url(repo)
|
@@ -1,31 +1,22 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "shell"
|
2
2
|
|
3
3
|
module MacSetup
|
4
4
|
class HomebrewInstaller
|
5
|
-
BREW_INSTALL_URL =
|
5
|
+
BREW_INSTALL_URL = "https://raw.githubusercontent.com/Homebrew/install/master/install"
|
6
6
|
|
7
|
-
def self.run
|
7
|
+
def self.run
|
8
8
|
if homebrew_missing?
|
9
|
-
puts
|
10
|
-
Shell.run("curl -
|
9
|
+
puts "Installing Homebrew..."
|
10
|
+
Shell.run(%{/usr/bin/ruby -e "$(curl -fsSL #{BREW_INSTALL_URL})"})
|
11
11
|
else
|
12
|
-
puts
|
13
|
-
end
|
12
|
+
puts "Homebrew already installed. Updating..."
|
14
13
|
|
15
|
-
|
14
|
+
Shell.run("brew update")
|
15
|
+
end
|
16
16
|
end
|
17
17
|
|
18
18
|
def self.homebrew_missing?
|
19
|
-
Shell.run(
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.update_homebrew(options)
|
23
|
-
if options.include?('--skip-brew-update')
|
24
|
-
puts 'Skipping Homebrew Update...'
|
25
|
-
else
|
26
|
-
puts 'Updating Homebrew...'
|
27
|
-
Shell.run('brew update')
|
28
|
-
end
|
19
|
+
Shell.run("which brew").empty?
|
29
20
|
end
|
30
21
|
end
|
31
22
|
end
|
@@ -1,11 +1,12 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "shell"
|
2
2
|
|
3
3
|
module MacSetup
|
4
4
|
class ScriptInstaller
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
SCRIPTS_PATH = "mac_setup/scripts"
|
6
|
+
|
7
|
+
def self.run(_config, _status)
|
8
|
+
Pathname.new(File.join(DOTFILES_PATH, SCRIPTS_PATH)).each_child do |script|
|
9
|
+
Shell.run(script.to_s)
|
9
10
|
end
|
10
11
|
end
|
11
12
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
|
3
|
+
require_relative "shell"
|
4
|
+
|
5
|
+
module MacSetup
|
6
|
+
class ServicesInstaller
|
7
|
+
LAUNCH_AGENTS_PATH = File.expand_path("~/Library/LaunchAgents")
|
8
|
+
SERVICES_TAP = "homebrew/services"
|
9
|
+
|
10
|
+
attr_reader :config, :status, :services, :running_services
|
11
|
+
|
12
|
+
def self.run(config, status)
|
13
|
+
new(config, status).run
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(config, status)
|
17
|
+
@config = config
|
18
|
+
@status = status
|
19
|
+
@services = config.services
|
20
|
+
end
|
21
|
+
|
22
|
+
def run
|
23
|
+
return if services.none?
|
24
|
+
|
25
|
+
puts "Installing services..."
|
26
|
+
|
27
|
+
FileUtils.mkdir_p(LAUNCH_AGENTS_PATH)
|
28
|
+
tap_services
|
29
|
+
get_running_services
|
30
|
+
|
31
|
+
services.each { |service| install_service(service) }
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def get_running_services
|
37
|
+
services_list = Shell.run("brew services list").split("\n").drop(1)
|
38
|
+
services_with_status = services_list.map { |line| line.split(/\s+/, 3).take(2) }
|
39
|
+
|
40
|
+
@running_services = services_with_status.each_with_object([]) do |(service, status), services|
|
41
|
+
services << service if status == "started"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def install_service(service)
|
46
|
+
if running_services.include?(service)
|
47
|
+
puts "Restarting #{service} service..."
|
48
|
+
|
49
|
+
Shell.run("brew services restart #{service}")
|
50
|
+
else
|
51
|
+
puts "Installing #{service} service..."
|
52
|
+
|
53
|
+
Shell.run("brew services start #{service}")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def tap_services
|
58
|
+
return if services_already_tapped?
|
59
|
+
|
60
|
+
Shell.run("brew tap #{SERVICES_TAP}")
|
61
|
+
end
|
62
|
+
|
63
|
+
def services_already_tapped?
|
64
|
+
status.installed_taps.include?(SERVICES_TAP)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/mac_setup/shell.rb
CHANGED
@@ -1,61 +1,121 @@
|
|
1
1
|
module MacSetup
|
2
|
-
class
|
3
|
-
def
|
4
|
-
|
5
|
-
|
2
|
+
class Symlink
|
3
|
+
def initialize(options)
|
4
|
+
@source_path = options[:source_path]
|
5
|
+
@file_name = options[:name]
|
6
|
+
@target_path = options[:target_path]
|
6
7
|
end
|
7
8
|
|
8
|
-
def
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
def link
|
10
|
+
short_sorce_path = MacSetup.shorten_path(source_path)
|
11
|
+
short_target_path = MacSetup.shorten_path(target_path)
|
12
|
+
puts "Linking #{short_sorce_path} to #{short_target_path}..."
|
13
|
+
|
14
|
+
return unless source_exists
|
15
|
+
|
16
|
+
target_exists? ? replace : FileUtils.ln_s(source_path, target_path)
|
13
17
|
end
|
14
18
|
|
15
|
-
|
16
|
-
config.symlinks.each do |file|
|
17
|
-
file_name = File.basename(file)
|
18
|
-
source = File.expand_path(file)
|
19
|
+
private
|
19
20
|
|
20
|
-
|
21
|
+
def source_exists
|
22
|
+
File.exist?(source_path).tap do |exists|
|
23
|
+
unless exists
|
24
|
+
short_sorce_path = MacSetup.shorten_path(source_path)
|
25
|
+
puts "WARNING: Source doesn’t exist at #{short_sorce_path}. Skipping..."
|
26
|
+
end
|
21
27
|
end
|
22
28
|
end
|
23
29
|
|
24
|
-
def
|
25
|
-
|
26
|
-
|
30
|
+
def target_exists?
|
31
|
+
File.exist?(target_path)
|
32
|
+
end
|
27
33
|
|
28
|
-
|
34
|
+
def target
|
35
|
+
@target ||= SymlinkTarget.new(target_path)
|
29
36
|
end
|
30
37
|
|
31
|
-
def
|
32
|
-
|
38
|
+
def source_path
|
39
|
+
@source_path ||= File.expand_path(file_name, DOTFILES_PATH)
|
40
|
+
end
|
41
|
+
|
42
|
+
def target_path
|
43
|
+
@target_path ||= File.join(ENV["HOME"], ".#{file_name}")
|
33
44
|
end
|
34
45
|
|
35
|
-
def
|
36
|
-
|
46
|
+
def file_name
|
47
|
+
@file_name ||= File.basename(source_path)
|
48
|
+
end
|
37
49
|
|
38
|
-
|
39
|
-
|
50
|
+
def replace
|
51
|
+
if File.symlink?(target_path)
|
52
|
+
replace_symlink
|
53
|
+
elsif File.directory?(source_path)
|
54
|
+
link_children
|
40
55
|
else
|
41
|
-
|
56
|
+
puts "WARNING: File already exists at #{MacSetup.shorten_path(target_path)}. Skipping..."
|
42
57
|
end
|
43
58
|
end
|
44
59
|
|
45
|
-
def
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
60
|
+
def link_children
|
61
|
+
puts "Linking children..."
|
62
|
+
|
63
|
+
children.each do |child|
|
64
|
+
child_source = Symlink.new(
|
65
|
+
source_path: File.join(source_path, child),
|
66
|
+
target_path: File.join(target_path, child)
|
67
|
+
)
|
68
|
+
|
69
|
+
child_source.link
|
50
70
|
end
|
51
71
|
end
|
52
72
|
|
53
|
-
def
|
54
|
-
|
55
|
-
|
73
|
+
def replace_symlink
|
74
|
+
existing_link = File.readlink(target_path)
|
75
|
+
|
76
|
+
if existing_link == source_path
|
77
|
+
puts "Already linked. Skipping..."
|
56
78
|
else
|
57
|
-
|
79
|
+
print "Replacing existing symlink at #{MacSetup.shorten_path(target_path)}. "
|
80
|
+
puts "Originally linked to #{MacSetup.shorten_path(existing_link)}..."
|
81
|
+
FileUtils.ln_sf(source_path, target_path)
|
58
82
|
end
|
59
83
|
end
|
84
|
+
|
85
|
+
def children
|
86
|
+
Dir.entries(source_path).reject { |entry| entry.start_with?(".") }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
class SymlinkInstaller
|
91
|
+
def self.run(config, _status)
|
92
|
+
install_dotfiles
|
93
|
+
install_symlinks(config)
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.install_dotfiles
|
97
|
+
dotfiles.each do |file_name|
|
98
|
+
source = Symlink.new(name: file_name)
|
99
|
+
source.link
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.install_symlinks(config)
|
104
|
+
config.symlinks.each do |source_path|
|
105
|
+
source = Symlink.new(source_path: File.expand_path(source_path))
|
106
|
+
source.link
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.install_dotfile(name)
|
111
|
+
dotfile = dotfiles.find { |file| file =~ /#{Regexp.escape(name)}/ }
|
112
|
+
source = Symlink.new(name: dotfile)
|
113
|
+
|
114
|
+
source.link
|
115
|
+
end
|
116
|
+
|
117
|
+
def self.dotfiles
|
118
|
+
Dir.entries(DOTFILES_PATH).reject { |entry| entry.start_with?(".") }
|
119
|
+
end
|
60
120
|
end
|
61
121
|
end
|
@@ -1,49 +1,15 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "shell"
|
2
2
|
|
3
3
|
module MacSetup
|
4
4
|
class SystemStatus
|
5
|
-
def installed_formulas
|
6
|
-
@installed_formulas ||= get_formulas
|
7
|
-
end
|
8
|
-
|
9
|
-
def outdated_formulas
|
10
|
-
@outdated_formulas ||= get_outdated_formulas
|
11
|
-
end
|
12
|
-
|
13
5
|
def installed_taps
|
14
6
|
@installed_taps ||= get_taps
|
15
7
|
end
|
16
8
|
|
17
|
-
def installed_casks
|
18
|
-
@installed_casks ||= get_casks
|
19
|
-
end
|
20
|
-
|
21
|
-
def loaded_agents
|
22
|
-
@loaded_agents ||= get_loaded_agents
|
23
|
-
end
|
24
|
-
|
25
9
|
private
|
26
10
|
|
27
|
-
def get_formulas
|
28
|
-
Shell.run('brew list -1').split("\n")
|
29
|
-
end
|
30
|
-
|
31
11
|
def get_taps
|
32
|
-
Shell.run(
|
33
|
-
end
|
34
|
-
|
35
|
-
def get_casks
|
36
|
-
Shell.run('brew cask list -1').split("\n")
|
37
|
-
end
|
38
|
-
|
39
|
-
def get_outdated_formulas
|
40
|
-
Shell.run('brew outdated --quiet').split("\n")
|
41
|
-
end
|
42
|
-
|
43
|
-
def get_loaded_agents
|
44
|
-
Shell.run('launchctl list | grep homebrew').split("\n").map do |line|
|
45
|
-
line.split(/\s/)[-1]
|
46
|
-
end
|
12
|
+
Shell.run("brew tap").split("\n")
|
47
13
|
end
|
48
14
|
end
|
49
15
|
end
|
data/lib/mac_setup/version.rb
CHANGED
data/lib/mac_setup.rb
CHANGED
@@ -1,45 +1,38 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require 'mac_setup/git_repo_installer'
|
11
|
-
require 'mac_setup/script_installer'
|
12
|
-
require 'mac_setup/symlink_installer'
|
1
|
+
require "mac_setup/version"
|
2
|
+
require "mac_setup/configuration"
|
3
|
+
require "mac_setup/system_status"
|
4
|
+
require "mac_setup/homebrew_installer"
|
5
|
+
require "mac_setup/git_repo_installer"
|
6
|
+
require "mac_setup/script_installer"
|
7
|
+
require "mac_setup/symlink_installer"
|
8
|
+
require "mac_setup/brewfile_installer"
|
9
|
+
require "mac_setup/services_installer"
|
13
10
|
|
14
11
|
module MacSetup
|
15
|
-
DOTFILES_PATH = File.expand_path(
|
12
|
+
DOTFILES_PATH = File.expand_path("~/.dotfiles")
|
16
13
|
|
17
|
-
|
14
|
+
INSTALLERS = [
|
15
|
+
SymlinkInstaller,
|
16
|
+
BrewfileInstaller,
|
17
|
+
ServicesInstaller,
|
18
|
+
GitRepoInstaller,
|
19
|
+
ScriptInstaller
|
20
|
+
]
|
21
|
+
|
22
|
+
def self.install(config_path, _options)
|
18
23
|
config = Configuration.new(File.expand_path(config_path))
|
19
24
|
status = SystemStatus.new
|
20
25
|
|
21
|
-
|
22
|
-
TapInstaller.run(config, status)
|
23
|
-
FormulaInstaller.run(config, status)
|
24
|
-
CaskInstaller.run(config, status)
|
25
|
-
LaunchAgentInstaller.run(config, status)
|
26
|
-
GitRepoInstaller.run(config)
|
27
|
-
ScriptInstaller.run(config)
|
28
|
-
SymlinkInstaller.run(config)
|
26
|
+
INSTALLERS.each { |installer| installer.run(config, status) }
|
29
27
|
end
|
30
28
|
|
31
29
|
def self.bootstrap(dotfiles_repo)
|
32
|
-
check_brew_install_path
|
33
|
-
|
34
30
|
GitRepoInstaller.install_repo(dotfiles_repo, DOTFILES_PATH)
|
35
|
-
|
36
|
-
|
31
|
+
SymlinkInstaller.install_dotfile("mac_setup")
|
32
|
+
HomebrewInstaller.run
|
37
33
|
end
|
38
34
|
|
39
|
-
def self.
|
40
|
-
|
41
|
-
|
42
|
-
puts '/usr/local does not exist.'
|
43
|
-
puts 'Read this to fix: https://github.com/Homebrew/homebrew/blob/master/share/doc/homebrew/El_Capitan_and_Homebrew.md#if-usrlocal-does-not-exist'
|
35
|
+
def self.shorten_path(path)
|
36
|
+
path.sub(/#{ENV['HOME']}/, "~")
|
44
37
|
end
|
45
38
|
end
|
data/mac_setup.gemspec
CHANGED
@@ -1,28 +1,28 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
lib = File.expand_path(
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
4
|
+
require "mac_setup/version"
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = "mac_setup"
|
8
8
|
spec.version = MacSetup::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
9
|
+
spec.authors = ["Matt Wean"]
|
10
|
+
spec.email = ["matthew.wean@gmail.com"]
|
11
11
|
|
12
|
-
spec.summary =
|
13
|
-
spec.license =
|
12
|
+
spec.summary = "Tool to set up a Mac"
|
13
|
+
spec.license = "MIT"
|
14
14
|
|
15
15
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
16
16
|
f.match(%r{^(test|spec|features)/})
|
17
17
|
end
|
18
18
|
|
19
|
-
spec.bindir =
|
19
|
+
spec.bindir = "exe"
|
20
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
-
spec.require_paths = [
|
21
|
+
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
-
spec.add_development_dependency
|
24
|
-
spec.add_development_dependency
|
25
|
-
spec.add_development_dependency
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.10"
|
24
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
25
|
+
spec.add_development_dependency "rspec"
|
26
|
+
spec.add_development_dependency "rubocop", "~> 0.34.2"
|
27
|
+
spec.add_development_dependency "rubocop-rspec"
|
28
28
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mac_setup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Wean
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-01-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -103,18 +103,15 @@ files:
|
|
103
103
|
- bin/setup
|
104
104
|
- exe/mac_setup
|
105
105
|
- lib/mac_setup.rb
|
106
|
-
- lib/mac_setup/
|
107
|
-
- lib/mac_setup/command_line_tools_installer.rb
|
106
|
+
- lib/mac_setup/brewfile_installer.rb
|
108
107
|
- lib/mac_setup/configuration.rb
|
109
|
-
- lib/mac_setup/formula_installer.rb
|
110
108
|
- lib/mac_setup/git_repo_installer.rb
|
111
109
|
- lib/mac_setup/homebrew_installer.rb
|
112
|
-
- lib/mac_setup/launch_agent_installer.rb
|
113
110
|
- lib/mac_setup/script_installer.rb
|
111
|
+
- lib/mac_setup/services_installer.rb
|
114
112
|
- lib/mac_setup/shell.rb
|
115
113
|
- lib/mac_setup/symlink_installer.rb
|
116
114
|
- lib/mac_setup/system_status.rb
|
117
|
-
- lib/mac_setup/tap_installer.rb
|
118
115
|
- lib/mac_setup/version.rb
|
119
116
|
- mac_setup.gemspec
|
120
117
|
homepage:
|
@@ -137,7 +134,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
134
|
version: '0'
|
138
135
|
requirements: []
|
139
136
|
rubyforge_project:
|
140
|
-
rubygems_version: 2.0.14
|
137
|
+
rubygems_version: 2.0.14.1
|
141
138
|
signing_key:
|
142
139
|
specification_version: 4
|
143
140
|
summary: Tool to set up a Mac
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require_relative 'shell'
|
2
|
-
|
3
|
-
module MacSetup
|
4
|
-
class CaskInstaller
|
5
|
-
def self.run(config, status)
|
6
|
-
casks = config.casks
|
7
|
-
return if casks.none?
|
8
|
-
|
9
|
-
puts 'Installing casks...'
|
10
|
-
|
11
|
-
uninstalled_casks = casks - status.installed_casks
|
12
|
-
|
13
|
-
uninstalled_casks.each do |cask|
|
14
|
-
print "Installing #{cask}..."
|
15
|
-
Shell.run("brew cask install #{cask}")
|
16
|
-
puts('Ok')
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
require 'fileutils'
|
2
|
-
|
3
|
-
require_relative 'shell'
|
4
|
-
|
5
|
-
module MacSetup
|
6
|
-
class CommandLineToolsInstaller
|
7
|
-
BIN_PATH = '/Library/Developer/CommandLineTools/usr/bin/clang'
|
8
|
-
TMP_FILE = '/tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress'
|
9
|
-
|
10
|
-
def self.run
|
11
|
-
if File.exist?(BIN_PATH)
|
12
|
-
puts 'Command Line Tools already installed. Skipping...'
|
13
|
-
else
|
14
|
-
install_clts
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.install_clts
|
19
|
-
puts 'Installing Command Line Tools...'
|
20
|
-
FileUtils.touch(TMP_FILE)
|
21
|
-
Shell.run(%(softwareupdate -i "#{package_name}" -v))
|
22
|
-
FileUtils.rm_f(TMP_FILE)
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.package_name
|
26
|
-
response = Shell.run('softwareupdate -l')
|
27
|
-
response.match(/(Command.*$)/)[1]
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
@@ -1,57 +0,0 @@
|
|
1
|
-
require 'English'
|
2
|
-
|
3
|
-
require_relative 'shell'
|
4
|
-
|
5
|
-
module MacSetup
|
6
|
-
class FormulaInstaller
|
7
|
-
attr_reader :config, :status
|
8
|
-
|
9
|
-
def self.run(config, status)
|
10
|
-
new(config, status).run
|
11
|
-
end
|
12
|
-
|
13
|
-
def initialize(config, status)
|
14
|
-
@config = config
|
15
|
-
@status = status
|
16
|
-
end
|
17
|
-
|
18
|
-
def run
|
19
|
-
formulas = config.formulas
|
20
|
-
return if formulas.none?
|
21
|
-
|
22
|
-
puts 'Installing formulas...'
|
23
|
-
|
24
|
-
formulas.each { |formula| install_formula(formula) }
|
25
|
-
end
|
26
|
-
|
27
|
-
def install_formula(formula)
|
28
|
-
if status.installed_formulas.include?(formula)
|
29
|
-
upgrade_formula(formula)
|
30
|
-
else
|
31
|
-
print "Installing #{formula}..."
|
32
|
-
output = Shell.run("brew install #{formula}")
|
33
|
-
|
34
|
-
$CHILD_STATUS.success? ? puts('Ok') : puts("\n#{output}")
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def upgrade_formula(formula)
|
39
|
-
if can_upgrade?(formula)
|
40
|
-
print "Upgrading #{formula}..."
|
41
|
-
output = Shell.run("brew upgrade #{formula}")
|
42
|
-
|
43
|
-
$CHILD_STATUS.success? ? puts('Ok') : puts("\n#{output}")
|
44
|
-
else
|
45
|
-
puts "Already using latest version of #{formula}..."
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def can_upgrade?(formula)
|
50
|
-
status.outdated_formulas.include?(full_name(formula))
|
51
|
-
end
|
52
|
-
|
53
|
-
def full_name(formula)
|
54
|
-
Shell.run("brew info #{formula}").split("\n")[0].split(':')[0]
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
require 'fileutils'
|
2
|
-
|
3
|
-
require_relative 'shell'
|
4
|
-
|
5
|
-
module MacSetup
|
6
|
-
class LaunchAgentInstaller
|
7
|
-
BREW_OPT_PATH = '/usr/local/opt'
|
8
|
-
LAUNCH_AGENTS_PATH = File.expand_path('~/Library/LaunchAgents')
|
9
|
-
|
10
|
-
def self.run(config, status)
|
11
|
-
launch_agents = config.launch_agents
|
12
|
-
return if launch_agents.none?
|
13
|
-
|
14
|
-
puts 'Installing launch agents...'
|
15
|
-
|
16
|
-
FileUtils.mkdir_p(LAUNCH_AGENTS_PATH)
|
17
|
-
|
18
|
-
launch_agents.each { |agent| install_launch_agent(agent, status) }
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.install_launch_agent(agent, status)
|
22
|
-
puts "Installing launch agent for #{agent}..."
|
23
|
-
|
24
|
-
domain = "homebrew.mxcl.#{agent}"
|
25
|
-
plist = "#{domain}.plist"
|
26
|
-
FileUtils.ln_sf(File.join(BREW_OPT_PATH, agent, plist), LAUNCH_AGENTS_PATH)
|
27
|
-
|
28
|
-
agent_plist_path = File.join(LAUNCH_AGENTS_PATH, plist)
|
29
|
-
|
30
|
-
Shell.run("launchctl unload '#{agent_plist_path}'") if status.loaded_agents.include?(domain)
|
31
|
-
|
32
|
-
Shell.run("launchctl load '#{agent_plist_path}'")
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
require 'English'
|
2
|
-
|
3
|
-
require_relative 'shell'
|
4
|
-
|
5
|
-
module MacSetup
|
6
|
-
class TapInstaller
|
7
|
-
def self.run(config, status)
|
8
|
-
return if config.taps.none?
|
9
|
-
|
10
|
-
puts 'Installing taps...'
|
11
|
-
|
12
|
-
uninstalled_taps = config.taps - status.installed_taps
|
13
|
-
|
14
|
-
if uninstalled_taps.none?
|
15
|
-
puts 'No uninstalled taps'
|
16
|
-
else
|
17
|
-
uninstalled_taps.each { |tap| install_tap(tap) }
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.install_tap(tap)
|
22
|
-
print "Installing #{tap}..."
|
23
|
-
output = Shell.run("brew tap #{tap}")
|
24
|
-
|
25
|
-
$CHILD_STATUS.success? ? puts('Ok') : puts("\n#{output}")
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|