class Dotfu::Repos
Attributes
Public Class Methods
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
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
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
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
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
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
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
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
# 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
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
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
# 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
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 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
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
Return an [Array] of target files.
# File lib/dotfu/repos.rb, line 207 def target_files files.map {|f| target_file f} end
# 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
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
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
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
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
# 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