|
#!/usr/bin/env ruby |
|
|
|
require 'fileutils' |
|
require 'pathname' |
|
require 'paint' |
|
require 'set' |
|
|
|
$overwrite = ARGV.delete('-o') or ARGV.delete('--overwrite') |
|
$dry_run = ARGV.delete('-d') or ARGV.delete('--dry-run') |
|
|
|
class Pathname |
|
def cp_r(dest); FileUtils.cp_r(self.to_s, dest.to_s); end |
|
|
|
META_FILES = Set['.DS_Store'].freeze |
|
def regular_children; children.find_all{ |ch| not META_FILES.include?(ch.basename.to_s) }; end |
|
def empty_directory?; directory? and regular_children.empty?; end |
|
def populated_directory?; directory? and not regular_children.empty?; end |
|
end |
|
|
|
if $dry_run |
|
class Pathname |
|
def unlink; $stderr.puts Paint["would unlink '#{self}'", :blue]; end |
|
def mkpath; $stderr.puts Paint["would mkpath '#{self}'", :blue]; end |
|
def rmtree; $stderr.puts Paint["would rmtree '#{self}'", :blue]; end |
|
def make_symlink(src); $stderr.puts Paint["would symlink '#{src}' <- '#{self}'", :blue]; end |
|
def cp_r(dest); $stderr.puts Paint["would recursively copy '#{self}' -> '#{dest}'", :blue]; end |
|
end |
|
end |
|
|
|
home_dir = Pathname.new(ENV['HOME']) |
|
bundles_dir = Pathname.new(__FILE__).parent.parent.expand_path |
|
bins_dir = home_dir + '.bins' |
|
caches_dir = home_dir + 'Library' + 'Caches' |
|
|
|
posix_bundle = bundles_dir + 'POSIX.bundle' |
|
freedesktop_bundle = bundles_dir + 'FreeDesktop.bundle' |
|
scripts_bundle = bundles_dir + 'Scripts.bundle' |
|
|
|
attach_map = { |
|
(home_dir + '.local' + 'share') => (freedesktop_bundle + 'share'), |
|
(home_dir + '.local' + 'bin') => (freedesktop_bundle + 'bin'), |
|
(home_dir + '.config') => (freedesktop_bundle + 'config'), |
|
(home_dir + '.cache') => (caches_dir), |
|
(bins_dir + 'freedesktop') => (home_dir + '.local' + 'bin'), |
|
(bins_dir + 'scripts') => (scripts_bundle + 'bin') |
|
} |
|
|
|
posix_bundle.children.each do |dotfile| |
|
attach_path = home_dir + ('.' + dotfile.basename.to_s) |
|
attach_map[attach_path] = dotfile |
|
end |
|
|
|
attach_map.each do |attach_path, dest| |
|
unless dest.exist? |
|
$stderr.puts Paint["! not attaching non-existent component path '#{dest}'", :red] |
|
next |
|
end |
|
|
|
attach_path.parent.mkpath unless attach_path.parent.exist? |
|
|
|
if dest.basename.to_s =~ /.template/ |
|
copy_path = attach_path.parent + attach_path.basename.to_s.gsub(/\.template$/, '') |
|
|
|
if $overwrite |
|
$stderr.puts Paint["! deleting source '#{copy_path}' to overwrite with template", :yellow] |
|
copy_path.rmtree if copy_path.exist? |
|
else |
|
next if copy_path.exist? |
|
end |
|
|
|
copy_path.unlink if copy_path.symlink? |
|
|
|
FileUtils.cp_r(dest.to_s, copy_path.to_s) |
|
$stderr.puts Paint[" Copied template '#{dest}' to '#{copy_path}'", :green] |
|
else |
|
if attach_path.exist? and (not attach_path.symlink?) and (not $overwrite) |
|
$stderr.puts Paint["! FreeDesktop dir '#{attach_path}' already exists; cannot attach", :red] |
|
next |
|
end |
|
|
|
if attach_path.symlink? |
|
attach_path.unlink |
|
elsif attach_path.exist? |
|
$stderr.puts Paint["! deleting source '#{attach_path}' to make link", :yellow] |
|
attach_path.rmtree |
|
end |
|
|
|
attach_path.make_symlink(dest) |
|
|
|
$stderr.puts Paint[" Linked '#{dest}' <= '#{attach_path}'", :green] |
|
end |
|
end |
|
|
|
cache_map = { |
|
(home_dir + '.cocoapods' + 'repos') => (caches_dir + 'CocoaPods' + 'repos'), |
|
(home_dir + '.bundle' + 'cache') => (caches_dir + 'org.rubygems' + 'bundler'), |
|
(home_dir + '.gem' + 'ruby') => (caches_dir + 'org.rubygems' + 'gem' + 'ruby'), |
|
(home_dir + '.hex' + 'packages') => (caches_dir + 'pm.hex' + 'packages'), |
|
(home_dir + '.docker' + 'machine' + 'cache') => (caches_dir + 'com.docker' + 'machine' + 'cache'), |
|
(home_dir + '.npm') => (caches_dir + 'com.npmjs.npm'), |
|
(home_dir + '.cargo' + 'bin') => (caches_dir + 'rs.rustup' + 'bin'), |
|
(home_dir + '.cargo' + 'registry') => (caches_dir + 'io.crates' + 'registry'), |
|
(home_dir + '.xargo' + 'lib' + 'rustlib') => (caches_dir + 'io.github.japaric.xargo' + 'rustlib'), |
|
(home_dir + '.rustup' + 'toolchains') => (caches_dir + 'rs.rustup' + 'toolchains'), |
|
(home_dir + '.wine' + 'drive_c' + 'windows') => (caches_dir + 'org.winehq.wine' + 'default' + 'windows'), |
|
(home_dir + '.fontconfig') => (caches_dir + 'fontconfig'), |
|
(home_dir + '.node-gyp') => (caches_dir + 'org.nodejs.node-gyp'), |
|
(home_dir + '.heroku') => (caches_dir + 'com.heroku.heroku-toolbelt' + 'home'), |
|
(home_dir + '.local' + 'share' + 'heroku') => (caches_dir + 'com.heroku.heroku-toolbelt' + 'share'), |
|
|
|
(bins_dir + 'rust') => (caches_dir + 'rs.rustup' + 'bin') |
|
} |
|
|
|
cache_map.each do |old_path, new_path| |
|
old_path.unlink if old_path.symlink? |
|
|
|
new_path.parent.mkpath |
|
|
|
if old_path.populated_directory? and new_path.populated_directory? |
|
$stderr.puts Paint["! Cache dest dir '#{new_path}' already exists and has content; not replacing (merge manually)", :red] |
|
next |
|
end |
|
|
|
new_path.rmtree if new_path.empty_directory? |
|
|
|
old_path.rename(new_path) if old_path.exist? |
|
new_path.mkpath unless new_path.exist? |
|
|
|
old_path.parent.mkpath |
|
old_path.make_symlink(new_path) |
|
|
|
$stderr.puts Paint[" Redirected '#{old_path}' to '#{new_path}'", :green] |
|
end |