module DotMe
Manage dotfiles.
Constants
- HAVE_GIT
- HOME
- IGNORE
- VERSION
Public Instance Methods
dotfiles()
click to toggle source
# File Rakefile.rb, line 212 def dotfiles files = inclexcl(git(:tracked).split("\0") - IGNORE) custom = [] files.each { |file| if File.readable?(mine = "#{file}.mine") custom << mine end } files + custom end
install()
click to toggle source
}}}
# File Rakefile.rb, line 107 def install symlinks.each { |target, symlink| dryrun(:symlink, target, symlink) { status, actual = status_for(symlink, target) begin File.symlink(target, symlink) puts "[ADDED] #{symlink} -> #{target}" rescue Errno::EEXIST => err warn "[ERROR=#{status}] #{err}" end } } end
pristine()
click to toggle source
# File Rakefile.rb, line 186 def pristine abort unless agreed?('This will undo all your local modifications AND remove all untracked files.') reset(false) git(:untracked).split("\0").sort.each { |file| dryrun(:rm_r, file) { FileUtils.rm_r(file) puts "[REMOVED] #{file}" } } end
reset(ask = true)
click to toggle source
# File Rakefile.rb, line 181 def reset(ask = true) abort unless agreed?('This will undo all your local modifications (untracked files are kept).') if ask git(:reset) end
status()
click to toggle source
# File Rakefile.rb, line 133 def status puts git(:status) puts symlinks.each { |target, symlink| status, actual = status_for(symlink, target) msg = "[#{status}] #{symlink}" case status when :MISMATCH msg << ':' << "\n expected: #{target}" << "\n got: #{actual}" else msg << " -> #{target}" end puts msg } end
symlinks()
click to toggle source
# File Rakefile.rb, line 198 def symlinks hash = {} dotfiles.each { |path| parts = path.split(File::SEPARATOR) target = File.join(parts[0..1]) symlink = File.join(HOME, ".#{parts[1] || parts[0]}") hash[File.expand_path(target)] = symlink } hash.sort end
uninstall()
click to toggle source
# File Rakefile.rb, line 153 def uninstall symlinks.each { |target, symlink| dryrun(:unlink, symlink) { status, actual = status_for(symlink, target) case status when :UNTRACKED warn "[ERROR=#{status}] Not removing '#{symlink}' - NOT A SYMLINK" when :NOT_FOUND warn "[ERROR=#{status}] Not removing '#{symlink}' - NOT FOUND" when :MISMATCH warn "[ERROR=#{status}] Not removing symlink '#{symlink}' - targets don't match:" warn " expected: #{target}" warn " got: #{actual}" when :TRACKED begin File.unlink(symlink) puts "[REMOVED] #{symlink} -> #{target}" rescue Errno::ENOENT => err warn "[ERROR] #{err}" end else warn "[ERROR=#{status}] #{symlink}" end } } end
update()
click to toggle source
# File Rakefile.rb, line 122 def update with_clean_working_directory do if out = git(:update) and git(:fetch) out.lines.grep(/^Updating\s+(\S+)/) { puts git(:log, '--oneline', '--reverse', $1) } end end install end
Private Instance Methods
agree(msg)
click to toggle source
# File Rakefile.rb, line 335 def agree(msg) print "#{msg} (yes/no) " case $stdin.gets.chomp[0].downcase when 'y' then true when 'n' then false else puts 'Please enter "[y]es" or "[n]o".' agree(msg) end rescue Interrupt abort '' end
agreed?(msg)
click to toggle source
# File Rakefile.rb, line 349 def agreed?(msg) puts msg agree('Are you sure you want that?') && agree('Are you REALLY sure?') end
dryrun(what, *args) { || ... }
click to toggle source
# File Rakefile.rb, line 354 def dryrun(what, *args) if ENV['DRYRUN'] _return = args.last.delete(:_return) if args.last.is_a?(Hash) warn ['[DRYRUN]', what, *args].join(' ') _return else yield end end
git(cmd, *args)
click to toggle source
# File Rakefile.rb, line 255 def git(cmd, *args) abort "Please install `git'." unless HAVE_GIT # aliases case cmd when :update cmd = 'pull' args << 'origin' << 'master' when :reset cmd = 'checkout' args << '-f' when :stash cmd = 'stash' args << 'save' when :unstash cmd = 'stash' args << 'pop' when :tracked cmd = 'ls-files' args << '-z' _return = %w[foo/x foo/y bar/y bar/z/a bar/z/b].join("\0") when :untracked cmd = 'ls-files' args << '-z' << '-o' << '--directory' _return = %w[foo/x.mine bar/y.mine blah].join("\0") end dryrun(:git, cmd, *args + [:_return => _return]) { %x{git #{[cmd, *args].join(' ')}} } end
glob2re(pattern)
click to toggle source
# File Rakefile.rb, line 323 def glob2re(pattern) %r{ \A #{ pattern. gsub(/\?/, '.'). gsub(/\*/, '.*?') } (?:/|\z) }x end
inclexcl(files)
click to toggle source
# File Rakefile.rb, line 287 def inclexcl(files) if File.readable?(inclexcl = 'inclexcl') incl, excl, replace = [], [], false File.foreach(inclexcl) { |pattern| pattern.sub!(/\A\s*/, '') pattern.sub!(/\s*\z/, '') next if pattern.empty? pattern.sub!(/\A([#+-])/, '') prefix = $1 # save capture next if prefix == '#' pattern.sub!(/\/\z/, '') if pattern.count('/') > 1 warn "[ERROR] Illegal pattern - #{pattern}" next end matches = files.grep(glob2re(pattern)) if prefix == '-' excl += matches else replace = true incl += matches end } files = incl if replace files -= excl end files.uniq end
status_for(symlink, target)
click to toggle source
{{{ Utility methods
# File Rakefile.rb, line 229 def status_for(symlink, target) if File.symlink?(symlink) if File.exists?(target) actual = Pathname.new(File.readlink(symlink)).realpath.to_s status = target == actual ? :TRACKED : :MISMATCH else status = :MISSING end else if File.exists?(symlink) status = File.exists?(target) ? :ALIEN : :UNTRACKED else status = File.exists?(target) ? :NOT_FOUND : :UNTRACKED end end [Status[status], actual] end
with_clean_working_directory() { || ... }
click to toggle source
# File Rakefile.rb, line 248 def with_clean_working_directory git(:stash) yield ensure git(:unstash) end