mac_setup 0.7.2 → 0.8.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f57f9af7d99a2694983bf5d0b09a700eae37b249
4
- data.tar.gz: 06f8d752ef6a7103c1b829d98a5d0e140dd44739
3
+ metadata.gz: 05b25fd9b18c84ceab8c35345f58607111782d0c
4
+ data.tar.gz: 3683dd0949e472f501f9624145ed97f695450f9b
5
5
  SHA512:
6
- metadata.gz: d5ecd9dd676671ea407cd222aca03577a1fa11c670a62edd600619c77dd171020531d3632b4d1a4465ad6f989a53fc0ab9c67b66e3b50435cee9ed986813a204
7
- data.tar.gz: 4110cb066e342f2b4f048b8d6609143cec308eb59789bc04231dc1602cc55a0466540280f87ae315f5d869b0d49652a3bb49ae8c6b3773fda9ad09d8562d14f5
6
+ metadata.gz: 81bd2abe212ca77282c59023e5d1505f6e803715da8791ee94caa9f1046690b7469d152c0a96ef4f2111d177f01cbd5044cd0b712e2f7f5f684a54cb772a48ba
7
+ data.tar.gz: a61fad4936463e8d1e737feb2069f11209733847af307e638e80c9f85169f9376b9d65a9aa3ada6503baa0e5e2a528e143840f80e6787692b0b69d47520dbcfc
data/exe/mac_setup CHANGED
@@ -2,22 +2,21 @@
2
2
 
3
3
  require "mac_setup"
4
4
 
5
- DEFAULT_CONFIG_PATH = "~/.dotfiles/mac_setup/config.yml"
6
-
7
5
  command = ARGV.shift
8
6
  options = ARGV.select { |arg| arg.start_with?("--") }
7
+ config_path = (ARGV - options).first || File.expand_path(DEFAULT_CONFIG_PATH)
9
8
 
10
9
  case command
11
10
  when "bootstrap"
12
- MacSetup.bootstrap(ARGV[0])
11
+ MacSetup.bootstrap(ARGV.take(2))
13
12
  when "install"
14
- config_path = (ARGV - options)[0] || File.expand_path(DEFAULT_CONFIG_PATH)
13
+ # config_path = (ARGV - options)[0] || File.expand_path(DEFAULT_CONFIG_PATH)
15
14
 
16
- if File.exist?(config_path)
17
- MacSetup.install(config_path, options)
18
- else
19
- puts "You must specify a path to config file or create one at #{DEFAULT_CONFIG_PATH}"
20
- end
15
+ # if File.exist?(config_path)
16
+ MacSetup.install # (config_path, options)
17
+ # else
18
+ # puts "You must specify a path to config file or create one at #{DEFAULT_CONFIG_PATH}"
19
+ # end
21
20
  when "encrypt"
22
21
  MacSetup.encrypt
23
22
  else
@@ -1,36 +1,106 @@
1
1
  require "yaml"
2
+ require "set"
2
3
 
3
4
  module MacSetup
4
5
  class Configuration
5
- attr_reader :config
6
+ InvalidConfigError = Class.new(StandardError)
7
+ DEFAULT_KEYS = [:plugins, :git_repos, :symlinks, :brews, :fonts, :casks, :quicklook, :mas]
6
8
 
7
9
  def initialize(config_path)
8
10
  @config_path = config_path
9
11
  load_config
10
12
  end
11
13
 
12
- def reload!
13
- load_config
14
+ def require_value(key)
15
+ value = @config.fetch(key.to_s) do
16
+ raise InvalidConfigError, "Missing config value for #{key}!"
17
+ end
18
+
19
+ define_singleton_method(key) { value }
20
+ allowed_keys << key.to_sym
14
21
  end
15
22
 
16
- def dotfiles_repo
17
- @config.fetch("repo")
23
+ def add(type, value)
24
+ add_method = "add_#{type}"
25
+
26
+ if respond_to?(add_method, include_private: true)
27
+ send(add_method, value)
28
+ else
29
+ collection = public_send(type)
30
+
31
+ case collection
32
+ when Set
33
+ collection << value.to_s
34
+ when Hash
35
+ collection.merge(value) do |key, oldval, newval|
36
+ raise InvalidConfigError, "#{key} is defined twice!: #{oldval}, #{newval}"
37
+ end
38
+ end
39
+ end
18
40
  end
19
41
 
20
- def services
21
- (@config["services"] || []).uniq
42
+ def plugins
43
+ @plugins ||= Set.new(@config["plugins"])
44
+ end
45
+
46
+ def validate!
47
+ extra_keys = @config.keys.map(&:to_i) - allowed_keys
48
+
49
+ return if extra_keys.none?
50
+
51
+ raise InvalidConfigError, "Extra keys in config: #{extra_keys.join(", ")}"
52
+ end
53
+
54
+ def dotfiles_repo
55
+ @config.fetch("repo")
22
56
  end
23
57
 
24
58
  def git_repos
25
- (@config["git_repos"] || []).uniq
59
+ @git_repos ||= @config["git_repos"] || {}
26
60
  end
27
61
 
28
62
  def symlinks
29
- (@config["symlinks"] || []).uniq
63
+ @symlinks ||= @config["symlinks"] || {}
64
+ end
65
+
66
+ def brews
67
+ @brews ||= (@config["brews"] || []).reduce({}) do |merged, item|
68
+ add_brews(item, merged)
69
+ end
70
+ end
71
+
72
+ def fonts
73
+ @fonts ||= Set.new(@config["fonts"])
74
+ end
75
+
76
+ def casks
77
+ @casks ||= Set.new(@config["casks"])
78
+ end
79
+
80
+ def quicklook
81
+ @quicklook ||= Set.new(@config["quicklook"])
82
+ end
83
+
84
+ def mas
85
+ @mas ||= @config["mas"] || {}
30
86
  end
31
87
 
32
88
  private
33
89
 
90
+ def add_brews(item, existing_brews = brews)
91
+ existing_brews.merge(brew_value(item)) do |key, oldval, newval|
92
+ raise InvalidConfigError, "#{key} is defined twice!: #{oldval}, #{newval}"
93
+ end
94
+ end
95
+
96
+ def brew_value(item)
97
+ item.is_a?(Hash) ? item : { item.to_s => {} }
98
+ end
99
+
100
+ def allowed_keys
101
+ @allowed_keys ||= Set.new(DEFAULT_KEYS)
102
+ end
103
+
34
104
  def load_config
35
105
  @config = YAML.load_file(@config_path)
36
106
  end
@@ -16,8 +16,8 @@ module MacSetup
16
16
  end
17
17
  end
18
18
 
19
- def self.install_repo(repo, install_path, tracking_key: nil, status: nil)
20
- new(repo, install_path, tracking_key: tracking_key, status: status).install_or_update
19
+ def self.install_repo(repo, install_path, track: nil, status: nil)
20
+ new(repo, install_path, tracking_key: track, status: status).install_or_update
21
21
  end
22
22
 
23
23
  def initialize(repo, install_path, tracking_key: nil, status: nil)
@@ -44,7 +44,7 @@ module MacSetup
44
44
 
45
45
  def update
46
46
  unless can_update?
47
- puts "\nCan't update. Unstaged changes in #{install_path}"
47
+ MacSetup.log "Can't update. Unstaged changes in #{install_path}"
48
48
  return
49
49
  end
50
50
 
@@ -5,19 +5,13 @@ module MacSetup
5
5
  BREW_INSTALL_URL = "https://raw.githubusercontent.com/Homebrew/install/master/install"
6
6
 
7
7
  def self.run
8
- if homebrew_missing?
8
+ if Shell.command_present?("brew")
9
+ MacSetup.log "Homebrew already installed. Skipping..."
10
+ else
9
11
  MacSetup.log "Installing Homebrew" do
10
12
  Shell.run(%{/usr/bin/ruby -e "$(curl -fsSL #{BREW_INSTALL_URL})"})
11
13
  end
12
- else
13
- MacSetup.log "Homebrew already installed. Updating" do
14
- Shell.run("brew update")
15
- end
16
14
  end
17
15
  end
18
-
19
- def self.homebrew_missing?
20
- Shell.run("which brew").empty?
21
- end
22
16
  end
23
17
  end
@@ -0,0 +1,40 @@
1
+ module MacSetup
2
+ class HomebrewRunner
3
+ def self.run(config, _status)
4
+ brewfile = build_brewfile(config)
5
+
6
+ cmd = [
7
+ "echo << EOF | brew bundle install --file=-",
8
+ brewfile,
9
+ "EOF"
10
+ ]
11
+
12
+ Shell.run(cmd.join("\n"))
13
+ end
14
+
15
+ def self.install_cask(cask)
16
+ Shell.run("brew cask install #{cask}")
17
+ end
18
+
19
+ def self.build_brewfile(config)
20
+ brews = config.brews.map do |name, opts|
21
+ [%(brew "#{name}"), print_args(opts)].compact.join(", ")
22
+ end
23
+
24
+ casks = (config.fonts + config.casks + config.quicklook).map do |name|
25
+ "cask #{name}"
26
+ end
27
+
28
+ (brews + casks).join("\n")
29
+ end
30
+
31
+ def self.print_args(opts)
32
+ args = opts["args"]
33
+
34
+ return unless args
35
+
36
+ args_str = args.sort.map { |arg| %("#{arg}") }.join(", ")
37
+ "args: [#{args_str}]"
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,17 @@
1
+ module MacSetup
2
+ class Plugin
3
+ def self.add_requirements(_config)
4
+ end
5
+
6
+ def self.run(_config, _status)
7
+ end
8
+
9
+ def self.load(plugin_name)
10
+
11
+ end
12
+
13
+ def self.bootstrap
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,32 @@
1
+ module MacSetup
2
+ module Plugins
3
+ class Keybase < MacSetup::Plugin
4
+ def self.bootstrap(config)
5
+ add_requirements(config)
6
+ install
7
+ login(config.keybase)
8
+ install_volume
9
+ end
10
+
11
+ def self.add_requirements(config)
12
+ config.require_value(:keybase)
13
+ config.add(:casks, :keybase)
14
+ end
15
+
16
+ private
17
+
18
+ def self.install
19
+ HomebrewRunner.install_cask(:keybase)
20
+ end
21
+
22
+ def self.login(username)
23
+ Shell.run("keybase login #{username}")
24
+ end
25
+
26
+ # TODO: Investigate making this work with kext permissions
27
+ def self.install_volume
28
+ Shell.run("keybase install --components=helper,fuse,mountdir,kbfs")
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,75 @@
1
+ module MacSetup
2
+ module Plugins
3
+ class MacAppStore < MacSetup::Plugin
4
+ attr_reader :config, :status
5
+
6
+ def self.add_requirements(config)
7
+ config.add(:brews, :mas)
8
+ end
9
+
10
+ def self.get_status(status)
11
+
12
+ end
13
+
14
+ def self.run(config, status)
15
+ new(config, status).run
16
+ end
17
+
18
+ def initialize(config, status)
19
+ @config = config
20
+ @status = status
21
+ end
22
+
23
+ def run
24
+ set_up_mas
25
+ install_brewfile
26
+ end
27
+
28
+ private
29
+
30
+ def set_up_mas
31
+ return unless brewfile.read =~ /^mas /
32
+
33
+ install_mas
34
+ sign_in_to_mas
35
+ end
36
+
37
+ def install_mas
38
+ MacSetup.log "Installing mas" do
39
+ Shell.run("brew install mas")
40
+ end
41
+ end
42
+
43
+ def sign_in_to_mas
44
+ if mas_signed_in?
45
+ MacSetup.log "Already signed into Mac App Store. Skipping."
46
+ else
47
+ apple_id = Shell.ask("What is your Apple ID?")
48
+ Shell.run("mas signin --dialog #{apple_id}")
49
+ end
50
+ end
51
+
52
+ def mas_signed_in?
53
+ Shell.success?("mas account")
54
+ end
55
+
56
+ def install_brewfile
57
+ MacSetup.log "Installing Brewfile" do
58
+ Shell.run("brew bundle --global")
59
+ end
60
+ end
61
+
62
+ def mas_installed?
63
+ Shell.command_present?("mas")
64
+ end
65
+
66
+ def bundle_already_tapped?
67
+ status.installed_taps.include?(BUNDLE_TAP)
68
+ end
69
+
70
+ def brewfile
71
+ @brewfile ||= Pathname.new("~/.Brewfile").expand_path
72
+ end
73
+ end
74
+ end
75
+ end
@@ -3,29 +3,35 @@ require "io/console"
3
3
 
4
4
  module MacSetup
5
5
  class Shell
6
- def self.run(command)
7
- `#{sanitize_command(command)}`
8
- end
6
+ class << self
7
+ def run(command)
8
+ `#{sanitize_command(command)}`
9
+ end
9
10
 
10
- def self.ask(question)
11
- puts question
12
- gets.strip
13
- end
11
+ def ask(question)
12
+ puts question
13
+ gets.strip
14
+ end
14
15
 
15
- def self.password
16
- puts "Enter Password"
17
- STDIN.noecho(&:gets).strip
18
- end
16
+ def password
17
+ puts "Enter Password"
18
+ STDIN.noecho(&:gets).strip
19
+ end
19
20
 
20
- def self.success?(command)
21
- system(sanitize_command(command))
22
- end
21
+ def success?(command)
22
+ system(sanitize_command(command))
23
+ end
24
+
25
+ def command_present?(command)
26
+ success?("command -v #{command} >/dev/null 2>&1")
27
+ end
23
28
 
24
- def self.sanitize_command(command)
25
- if command.respond_to?(:each)
26
- Shellwords.join(command)
27
- else
28
- command
29
+ def sanitize_command(command)
30
+ if command.respond_to?(:each)
31
+ Shellwords.join(command)
32
+ else
33
+ command
34
+ end
29
35
  end
30
36
  end
31
37
  end
@@ -1,3 +1,3 @@
1
1
  module MacSetup
2
- VERSION = "0.7.2"
2
+ VERSION = "0.8.0"
3
3
  end
data/lib/mac_setup.rb CHANGED
@@ -1,58 +1,82 @@
1
+ require "pathname"
2
+
1
3
  require "mac_setup/version"
2
4
  require "mac_setup/configuration"
3
5
  require "mac_setup/system_status"
6
+ require "mac_setup/shell"
7
+ require "mac_setup/homebrew_runner"
4
8
  require "mac_setup/secrets"
5
- require "mac_setup/command_line_tools_installer"
6
9
  require "mac_setup/homebrew_installer"
7
10
  require "mac_setup/git_repo_installer"
8
- require "mac_setup/script_installer"
9
- require "mac_setup/symlink_installer"
10
- require "mac_setup/brewfile_installer"
11
- require "mac_setup/services_installer"
12
- require "mac_setup/secrets_installer"
11
+ require "mac_setup/plugin"
12
+ require "mac_setup/plugins/keybase"
13
+ require "mac_setup/plugins/mac_app_store"
13
14
 
14
15
  module MacSetup
15
- DOTFILES_PATH = File.expand_path("~/.dotfiles")
16
+ DEFAULT_DOTFILES_PATH = File.expand_path("~/.dotfiles")
17
+ DEFAULT_CONFIG_PATH = File.join(DEFAULT_DOTFILES_PATH, "mac_setup/config.yml")
16
18
 
17
19
  INSTALLERS = [
18
20
  GitRepoInstaller,
19
- SecretsInstaller,
20
21
  SymlinkInstaller,
21
- BrewfileInstaller,
22
- ServicesInstaller,
23
- ScriptInstaller
22
+ HomebrewRunner
24
23
  ]
25
24
 
26
- def self.install(config_path, _options)
27
- config = Configuration.new(File.expand_path(config_path))
28
- status = SystemStatus.new
25
+ DEFAULT_PLUGINS = [
26
+ Plugins::MacAppStore,
27
+ Plugins::Keybase
28
+ ]
29
29
 
30
- GitRepoInstaller.install_repo(config.dotfiles_repo, DOTFILES_PATH, status: status, track: :dotfiles)
31
- config.reload!
32
- INSTALLERS.each { |installer| installer.run(config, status) }
33
- end
30
+ class << self
31
+ def bootstrap(dotfiles_repo)
32
+ GitRepoInstaller.install_repo(dotfiles_repo, dotfiles_path)
33
+ HomebrewInstaller.run
34
34
 
35
- def self.bootstrap(dotfiles_repo)
36
- CommandLineToolsInstaller.run
37
- GitRepoInstaller.install_repo(dotfiles_repo, DOTFILES_PATH)
38
- HomebrewInstaller.run
39
- end
35
+ config = Configuration.new(DEFAULT_CONFIG_PATH)
40
36
 
41
- def self.encrypt
42
- Secrets.encrypt(DOTFILES_PATH)
43
- end
37
+ plugins(config).each { |plugin| plugin.bootstrap(config) }
38
+ end
44
39
 
45
- def self.shorten_path(path)
46
- path.sub(/#{ENV['HOME']}/, "~")
47
- end
40
+ def install # (config_path, _options)
41
+ config = Configuration.new(DEFAULT_CONFIG_PATH)
42
+
43
+ GitRepoInstaller.install_repo(config.dotfiles_repo, dotfiles_path)
44
+
45
+ config = Configuration.new(DEFAULT_CONFIG_PATH)
46
+ plugins(config).each { |plugin| plugin.add_requirements(config) }
47
+ config.validate!
48
+ status = SystemStatus.new
49
+
50
+ INSTALLERS.each { |installer| installer.run(config, status) }
51
+ end
52
+
53
+ def encrypt
54
+ Secrets.encrypt(dotfiles_path)
55
+ end
56
+
57
+ def shorten_path(path)
58
+ path.sub(/#{ENV['HOME']}/, "~")
59
+ end
60
+
61
+ def log(message)
62
+ if block_given?
63
+ print "#{message}..."
64
+ yield
65
+ puts "Ok."
66
+ else
67
+ puts message
68
+ end
69
+ end
70
+
71
+ def dotfiles_path
72
+ DEFAULT_DOTFILES_PATH
73
+ end
74
+
75
+ # private
48
76
 
49
- def self.log(message)
50
- if block_given?
51
- print "#{message}..."
52
- yield
53
- puts "Ok."
54
- else
55
- puts message
77
+ def plugins(config)
78
+ DEFAULT_PLUGINS + config.plugins.map { |plugin_name| Plugin.load(plugin_name) }
79
+ # @plugins ||= (DEFAULT_PLUGINS + config.plugins).map { |plugin_name| Plugin.load(plugin) }
56
80
  end
57
81
  end
58
82
  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.7.2
4
+ version: 0.8.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: 2017-03-19 00:00:00.000000000 Z
11
+ date: 2018-08-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -108,6 +108,10 @@ files:
108
108
  - lib/mac_setup/configuration.rb
109
109
  - lib/mac_setup/git_repo_installer.rb
110
110
  - lib/mac_setup/homebrew_installer.rb
111
+ - lib/mac_setup/homebrew_runner.rb
112
+ - lib/mac_setup/plugin.rb
113
+ - lib/mac_setup/plugins/keybase.rb
114
+ - lib/mac_setup/plugins/mac_app_store.rb
111
115
  - lib/mac_setup/script_installer.rb
112
116
  - lib/mac_setup/secrets.rb
113
117
  - lib/mac_setup/secrets_installer.rb