class Dotfu::Repos

Attributes

backup_dir[RW]
branch[RW]
config_file[RW]
repo[RW]
target_dir[RW]
user[RW]
working_dir[RW]

Public Class Methods

new(arg = nil) click to toggle source

r can be either a repo, or a user:repo pair.

# File lib/dotfu/repos.rb, line 12
def initialize(arg = nil)
  parse_arg arg if arg
  parse_config
end

Public Instance Methods

backup() click to toggle source

Work methods

# File lib/dotfu/repos.rb, line 48
def backup
  return nil if installed?
  files = existing_files false

  if files.any?
    FileUtils.mkdir_p backup_dir

    files.each do |target_file|
      working_file = target_file.split("#{target_dir}/").last
      next if is_my_file? target_file

      begin
        FileUtils.mv target_file, "#{backup_dir}/#{working_file}"
      rescue Exception => e
        puts e
        exit
        #puts raise RuntimeError.new "File move failed for: #{working_file} to #{backup_dir}/#{working_file} failed: #{e}"
      end
    end
  end

  return true
end
clone() click to toggle source

initial clone

# File lib/dotfu/repos.rb, line 73
def clone
  return nil if !repo || !user
  uri = "git://github.com/#{user}/#{repo}.git"
  FileUtils.mkdir_p working_dir
  return true if Git.clone(uri, repo, path:"#{Bini.data_dir}/repos/#{user}" )
end
config_file?() click to toggle source

does it have a config file? Must be fetched or will return nil.

# File lib/dotfu/repos.rb, line 154
def config_file?
  return false unless fetched?

  return File.exist? "#{working_dir}/#{config_file}"
end
existing_files(my_files = true) click to toggle source

return an array of existing files in the way. Accepts a [Boolean] as the only argument, true to return files we linked (default), false if we want just the files that are in the way.

# File lib/dotfu/repos.rb, line 187
def existing_files(my_files = true)
  # I can do this in a convoluted set of if checks, of a couple readable selects.
  output = target_files.select { |f| File.exist? f }
  output.delete_if { |f| my_files && is_my_file?(f)}

  return output
end
fetch() click to toggle source

A wrapper method to clone or update a repo.

# File lib/dotfu/repos.rb, line 81
def fetch
  return nil if !repo || !user
  if fetched?
    pull
  else
    clone
  end
end
fetched?() click to toggle source

I need to make this more sophisticated. Or make a like updated? method.

# File lib/dotfu/repos.rb, line 144
def fetched?
  return nil if !repo
  return false if !working_dir
  files = Dir.glob("#{working_dir}/**/*")

  return true if files.any?
  return false
end
files() click to toggle source

return an [Array] of base filenames.

# File lib/dotfu/repos.rb, line 175
def files
  if !@files
    files = Dir.glob("#{working_dir}/*").map {|f| f.split(working_dir)[1][1..-1]}
    files.delete config_file
    @files = files
  end
  return @files
end
install() click to toggle source
# File lib/dotfu/repos.rb, line 91
def install
  r = Git.init working_dir

  result = r.checkout(@branch ? branch : "master")
  raise RuntimeError.new result unless result

  # Backup!
  if existing_files(false)
    puts "wtf, backup failed" unless backup
  end

  # And now that we are ok with everything, lets make some fucking files.
  # TODO: add deep linking (mkdir + ln_s for each target) or shallow (just the first directory)
  FileUtils.mkdir_p target_dir
  files.each {|file| FileUtils.ln_s working_file(file), target_file(file)}

  return true
end
installed?() click to toggle source

returns true if every file is installed. I need to make this more indepth, but it will at lease ensure all files are linked to something in the working dir.

# File lib/dotfu/repos.rb, line 162
def installed?
  results = target_files.map {|f| is_my_file?(f) }
  return false if results.include? false
  return true
end
is_my_file?(file) click to toggle source

Return true if this file is linked to this repo.

# File lib/dotfu/repos.rb, line 169
def is_my_file?(file)
  return true if File.exist?(file) && File.symlink?(file) && File.readlink(file).start_with?(working_dir)
  return false
end
pull() click to toggle source
# File lib/dotfu/repos.rb, line 110
def pull
  return nil if !repo || !user
  r = Git.init working_dir
  r.fetch
  #TODO: I'm confident that the implicit decleration of first here is going to muck something up for someone.  Find a way to do this explicitly.
  return r.remote.merge
end
repo=(word) click to toggle source

prepend repo with dotfiles- if it doesn’t exist as it is set.

# File lib/dotfu/repos.rb, line 32
def repo=(word)
  return @repo = word.start_with?('dotfiles-') ? word : "dotfiles-#{word}"
end
restore() click to toggle source

Restore files (as neccessary)

# File lib/dotfu/repos.rb, line 119
def restore
  files = Dir.glob("#{backup_dir}/**/*")

  raise "Files in the way" if existing_files

  return true if files.empty?

  files.each do |f|
    FileUtils.mv f, target_dir
  end

  return true
end
target_file(file, dot_home = true) click to toggle source

Return the target file. Takes a [String] (explicit conversion) or [Array] for index lookup. dot_home is a [Boolean] that will dot the target dir if it is the home dir only.

# File lib/dotfu/repos.rb, line 199
def target_file(file, dot_home = true)
  output = "#{target_dir}/"
  output += "." if dot_home && target_dir == Dir.home
  output += file_string(file)
  return output
end
target_files() click to toggle source

Return an [Array] of target files.

# File lib/dotfu/repos.rb, line 207
def target_files
  files.map {|f| target_file f}
end
uninstall() click to toggle source
# File lib/dotfu/repos.rb, line 133
def uninstall
  raise RuntimeError.new "Not installed." unless installed?

  target_files.each {|f| FileUtils.rm f}
  restore
  return true
end
working_file(file) click to toggle source

return the working file. Takes a [String] (explicit conversion) or [Array] for index lookup.

# File lib/dotfu/repos.rb, line 213
def working_file(file)
  "#{working_dir}/#{file_string(file)}"
end
working_files() click to toggle source

Return an [Array] of working files.

# File lib/dotfu/repos.rb, line 218
def working_files
  files.map {|f| working_file f}
end

Private Instance Methods

file_string(file) click to toggle source

Accepts a string or fixnum. Returns either the string or the files TODO: figure out a better fucking name for this.

# File lib/dotfu/repos.rb, line 246
def file_string(file)
  return file.class == Fixnum ? files[file] : file
end
parse_arg(word) click to toggle source

So our input is now username@repo:branch Repo is the only one required.

# File lib/dotfu/repos.rb, line 225
def parse_arg(word)
  if word.include? "@"
    self.name,word = word.split("@")
  end

  if word.include? ":"
    self.repo, self.branch = word.split(":")
  end

  self.repo = word if !self.repo
end
parse_config() click to toggle source
# File lib/dotfu/repos.rb, line 237
def parse_config
  return nil unless config_file?

  content = Yajl.load open("#{working_dir}/#{config_file}")
  @target_dir = content["target_directory"].chomp("/") if content["target_directory"]
end