Class: Dotfu::Repos

Inherits:
Object
  • Object
show all
Defined in:
lib/dotfu/repos.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(arg = nil) ⇒ Repos

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



12
13
14
15
# File 'lib/dotfu/repos.rb', line 12

def initialize(arg = nil)
  parse_arg arg if arg
  parse_config
end

Instance Attribute Details

#backup_dirObject

Specialized attribute methods



18
19
20
# File 'lib/dotfu/repos.rb', line 18

def backup_dir
  @backup_dir
end

#branchObject

Returns the value of attribute branch.



4
5
6
# File 'lib/dotfu/repos.rb', line 4

def branch
  @branch
end

#config_fileObject

Returns the value of attribute config_file.



6
7
8
# File 'lib/dotfu/repos.rb', line 6

def config_file
  @config_file
end

#repoObject

Returns the value of attribute repo.



3
4
5
# File 'lib/dotfu/repos.rb', line 3

def repo
  @repo
end

#target_dirObject

target_dir should always return something.



27
28
29
# File 'lib/dotfu/repos.rb', line 27

def target_dir
  @target_dir
end

#userObject

return user or the user in the config file.



43
44
45
# File 'lib/dotfu/repos.rb', line 43

def user
  @user
end

#working_dirObject

return the explicit directory this repo is cloned into.



37
38
39
# File 'lib/dotfu/repos.rb', line 37

def working_dir
  @working_dir
end

Instance Method Details

#backupObject

Work methods



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# 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

#cloneObject

initial clone



73
74
75
76
77
78
# 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?Boolean

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

Returns:

  • (Boolean)


154
155
156
157
158
# 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) ⇒ Object

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.



187
188
189
190
191
192
193
# 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

#fetchObject

A wrapper method to clone or update a repo.



81
82
83
84
85
86
87
88
# File 'lib/dotfu/repos.rb', line 81

def fetch
  return nil if !repo || !user
  if fetched?
    pull
  else
    clone
  end
end

#fetched?Boolean

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

Returns:

  • (Boolean)


144
145
146
147
148
149
150
151
# 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

#filesObject

return an [Array] of base filenames.



175
176
177
178
179
180
181
182
# 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

#installObject



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# 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?Boolean

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.

Returns:

  • (Boolean)


162
163
164
165
166
# 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) ⇒ Boolean

Return true if this file is linked to this repo.

Returns:

  • (Boolean)


169
170
171
172
# 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

#pullObject



110
111
112
113
114
115
116
# 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

#restoreObject

Restore files (as neccessary)



119
120
121
122
123
124
125
126
127
128
129
130
131
# 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) ⇒ Object

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.



199
200
201
202
203
204
# 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_filesObject

Return an [Array] of target files.



207
208
209
# File 'lib/dotfu/repos.rb', line 207

def target_files
  files.map {|f| target_file f}
end

#uninstallObject



133
134
135
136
137
138
139
# 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) ⇒ Object

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



213
214
215
# File 'lib/dotfu/repos.rb', line 213

def working_file(file)
  "#{working_dir}/#{file_string(file)}"
end

#working_filesObject

Return an [Array] of working files.



218
219
220
# File 'lib/dotfu/repos.rb', line 218

def working_files
  files.map {|f| working_file f}
end