Module: FileUtils
- Defined in:
- lib/nub/fileutils.rb
Overview
Monkey patch FileUtils with some useful methods
Class Method Summary collapse
-
.digests_changed?(key, digestfile, files) ⇒ Boolean
Check if any digests have changed based on the given files.
-
.exec?(name, path: nil) ⇒ Boolean
Check PATH for executable.
-
.inc_version(path, regex, major: false, minor: false, rev: true, override: nil) ⇒ Object
Increment SemVer formatted versions.
-
.insert(file, values, regex: nil, offset: 1) ⇒ Object
Insert into a file Location of insert is determined by the given regex and offset.
-
.replace(file, regex, value) ⇒ Object
Replace in file.
-
.resolve(file, vars) ⇒ Object
Resolve template.
-
.update(filename) ⇒ Object
Update the file using a block, revert on failure.
-
.update_copyright(path, copyright, year: Time.now.year) ⇒ Object
Check copyright and update if required.
-
.update_digests(key, digestfile, files) ⇒ Object
Generate digests for array of files given and save them.
-
.version(path, regex) ⇒ Object
Get SemVer formatted versions.
Class Method Details
.digests_changed?(key, digestfile, files) ⇒ Boolean
Check if any digests have changed based on the given files
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/nub/fileutils.rb', line 36 def self.digests_changed?(key, digestfile, files) files = [files] if files.is_a?(String) newfiles, modifiedfiles, deletedfiles = [], [], [] # Since layers are stacked and the digest file may be from a lower # layer this should be ignored unless the layer matches if (digests = File.exist?(digestfile) ? YAML.load_file(digestfile)[key] : nil) # New files: in files but not yaml newfiles = files.select{|x| not digests[x]} # Delete files: in yaml but not files deletedfiles = digests.map{|k,v| k}.select{|x| not files.include?(x)} # Modified files: in both but digest is different modifiedfiles = files.select{|x| digests[x] and Digest::MD5.hexdigest(File.binread(x)) != digests[x]} else newfiles = files end return newfiles, modifiedfiles, deletedfiles end |
.exec?(name, path: nil) ⇒ Boolean
Check PATH for executable
65 66 67 68 69 70 71 72 73 |
# File 'lib/nub/fileutils.rb', line 65 def self.exec?(name, path:nil) (path || ENV['PATH'].split(File::PATH_SEPARATOR).uniq).each{|dir| target = File.join(dir, name) if stat = File.stat(target) rescue nil return target if stat.file? && stat.executable? end } return nil end |
.inc_version(path, regex, major: false, minor: false, rev: true, override: nil) ⇒ Object
Increment SemVer formatted versions
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/nub/fileutils.rb', line 83 def self.inc_version(path, regex, major:false, minor:false, rev:true, override:nil) version = nil self.update(path){|data| # Increment version line = data.split("\n").find{|x| x[regex, 1]} if ver = line[regex, 1] new_ver = nil if not override new_ver = ver.strip.split('.') new_ver[0] = new_ver[0].to_i + 1 if major new_ver[1] = new_ver[1].to_i + 1 if minor new_ver[2] = new_ver[2].to_i + 1 if rev new_ver = new_ver * '.' else new_ver = override end # Modify the original line version = new_ver newline = line.gsub(ver, new_ver) data.gsub!(line, newline) end } return version end |
.insert(file, values, regex: nil, offset: 1) ⇒ Object
Insert into a file Location of insert is determined by the given regex and offset. Append is used if no regex is given.
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/nub/fileutils.rb', line 119 def self.insert(file, values, regex:nil, offset:1) return false if not values or values.empty? values = [values] if values.is_a?(String) FileUtils.touch(file) if not File.exist?(file) changed = self.update(file){|data| lines = data.split("\n") lastline = lines[-1].dup # Match regex for insert location regex = Regexp.new(regex) if regex.is_a?(String) if i = regex ? lines.index{|x| x =~ regex} : lines.size i += offset if regex and offset # Insert at offset values.each{|x| lines.insert(i, x) and i += 1} # Change data inline newdata = lines * "\n" newdata += "\n" if lines[-1] != lastline data.gsub!(data, newdata) end } return changed end |
.replace(file, regex, value) ⇒ Object
Replace in file
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/nub/fileutils.rb', line 153 def self.replace(file, regex, value) changed = self.update(file){|data| lines = data.split("\n") # Search replace regex = Regexp.new(regex) if regex.is_a?(String) lines.each{|x| x.gsub!(regex, value)} # Change data inline newdata = lines * "\n" newdata += "\n" if data[-1] == "\n" data.gsub!(data, newdata) } return changed end |
.resolve(file, vars) ⇒ Object
Resolve template
174 175 176 |
# File 'lib/nub/fileutils.rb', line 174 def self.resolve(file, vars) return self.update(file){|data| data.erb!(vars)} end |
.update(filename) ⇒ Object
Update the file using a block, revert on failure. Use this for file edits. Block is passed in the file data
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/nub/fileutils.rb', line 182 def self.update(filename) changed = false block = Proc.new # Most efficient way to get block begin data = nil File.open(filename, 'r+'){|f| data = f.read data_orig = data.dup # Call block block.call(data) changed |= data_orig != data # Save the changes back to the file if changed f.seek(0) f.truncate(0) f << data end } rescue Exception => e # Revert back to the original incase of failure File.open(filename, 'w'){|f| f << data} if data raise end return changed end |
.update_copyright(path, copyright, year: Time.now.year) ⇒ Object
Check copyright and update if required
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 |
# File 'lib/nub/fileutils.rb', line 217 def self.update_copyright(path, copyright, year:Time.now.year) set_copyright = false changed = self.update(path){|data| line = data.split("\n").find{|x| x[/#{Regexp.quote(copyright)}/]} if !set_copyright && line =~ /#{Regexp.quote(copyright)}/ set_copyright = true _year = line[/#{Regexp.quote(copyright)}\s+((\d{4}\s)|(\d{4}-\d{4})).*/, 1].strip if _year.include?("-") years = _year.split("-") if years.last != year newline = line.gsub(_year, "#{years.first}-#{year}") data.gsub!(line, newline) end elsif prev_year = _year != year.to_s ? year.to_i - 1 : nil newline = line.gsub(_year.to_s, "#{prev_year}-#{year}") data.gsub!(line, newline) end end } return changed end |
.update_digests(key, digestfile, files) ⇒ Object
Generate digests for array of files given and save them
244 245 246 247 248 249 250 251 252 253 |
# File 'lib/nub/fileutils.rb', line 244 def self.update_digests(key, digestfile, files) files = [files] if files.is_a?(String) # Build up digests structure digests = {} files.each{|x| digests[x] = Digest::MD5.hexdigest(File.binread(x)) if File.exist?(x)} # Write out digests structure as yaml with named header File.open(digestfile, 'w'){|f| f.puts({key => digests}.to_yaml)} end |
.version(path, regex) ⇒ Object
Get SemVer formatted versions
259 260 261 262 263 264 265 266 267 268 |
# File 'lib/nub/fileutils.rb', line 259 def self.version(path, regex) if File.file?(path) File.readlines(path).each{|line| if ver = line[regex, 1] return ver end } end return nil end |