Class: Makit::Directory

Inherits:
Object
  • Object
show all
Defined in:
lib/makit/directory.rb

Overview

This class provide methods for working with Directories/

Example:

Makit::Directory.find_directory_with_pattern("/home/user", "*.rb")

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.contains_pattern?(directory, pattern) ⇒ Boolean

Returns:

  • (Boolean)


90
91
92
93
94
95
96
# File 'lib/makit/directory.rb', line 90

def self.contains_pattern?(directory, pattern)
  Dir.foreach(directory) do |entry|
    next if [".", ".."].include?(entry)
    return true if File.fnmatch(pattern, entry)
  end
  false
end

.copy(src_dir, dst_dir, verbose = false) ⇒ Object



205
206
207
# File 'lib/makit/directory.rb', line 205

def self.copy(src_dir, dst_dir, verbose = false)
  FileUtils.cp_r(src_dir, dst_dir, verbose: verbose)
end

.deep_clean(dir) ⇒ Object

cleans all git repositories found in the given directory



233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/makit/directory.rb', line 233

def self.deep_clean(dir)
  git_dirs = []
  # Dir.chdir(dir) do

  # scan all subdirectories for git repositories

  puts "  scanning #{dir} for git repositories".colorize(:green)
  Find.find(dir) do |path|
    git_dirs << path if File.directory?(path) && File.exist?("#{path}/.git")
  end
  # end

  git_dirs.each do |path|
    puts "  cleaning #{path} of untracked files".colorize(:green)
    Dir.chdir(path) do
      puts `git clean -fdx`
    end
  end
end

.find_directory_with_pattern(starting_directory, pattern) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/makit/directory.rb', line 75

def self.find_directory_with_pattern(starting_directory, pattern)
  current_directory = File.expand_path(starting_directory)

  loop do
    return current_directory if contains_pattern?(current_directory, pattern)

    parent_directory = File.dirname(current_directory)
    break if parent_directory == current_directory # Reached the root directory


    current_directory = parent_directory
  end

  nil
end

.find_directory_with_patterns(starting_directory, patterns) ⇒ Object



66
67
68
69
70
71
72
73
# File 'lib/makit/directory.rb', line 66

def self.find_directory_with_patterns(starting_directory, patterns)
  patterns.each do |pattern|
    result = find_directory_with_pattern(starting_directory, pattern)
    return result if Dir.exist?(result)
  end

  nil
end

.generate_manifest(dir) ⇒ Object



209
210
211
212
213
214
215
216
217
218
# File 'lib/makit/directory.rb', line 209

def self.generate_manifest(dir)
  FileUtils.rm_f("#{dir}/manifest.txt")
  File.open("#{dir}/manifest.txt", "w") do |f|
    Dir.glob("#{dir}/**/*").each do |file|
      next if File.directory?(file)

      f.puts file.sub("#{dir}/", "")
    end
  end
end

.get_git_tracked_files(directory_path) ⇒ Object



128
129
130
131
132
133
134
135
136
# File 'lib/makit/directory.rb', line 128

def self.get_git_tracked_files(directory_path)
  # raise "do not use this method"

  # output, status = Open3.capture2("git ls-files directory", chdir: directory_path)

  # raise "Failed to list git-tracked files" unless status.success?

  # command = "git ls-files #{directory_path}".run


  # command.output.split("\n")

  `git ls-files #{directory_path}`.split("\n")
end

.get_humanized_size(size_in_bytes, precision = 2) ⇒ Object



108
# File 'lib/makit/directory.rb', line 108

def self.get_humanized_size(size_in_bytes, precision = 2); end

.get_latest_file_change_date(path) ⇒ Object

for a given path, get the most recent file change date for any file in the directory



177
178
179
180
181
182
183
184
185
186
187
# File 'lib/makit/directory.rb', line 177

def self.get_latest_file_change_date(path)
  # loop over all files in the directory

  latest_date = nil
  Find.find(path) do |file|
    if File.file?(file)
      date = File.mtime(file)
      latest_date = date if latest_date.nil? || date > latest_date
    end
  end
  latest_date
end

.get_line_count(file) ⇒ Object



60
61
62
63
64
# File 'lib/makit/directory.rb', line 60

def self.get_line_count(file)
  line_count = 0
  File.foreach(file) { line_count += 1 }
  line_count
end

.get_newest_file(path) ⇒ Object

for a given path, return the filename of the most recently modified file



190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/makit/directory.rb', line 190

def self.get_newest_file(path)
  newest_file = nil
  latest_date = nil
  if Dir.exist?(path)
    Find.find(path) do |file|
      next unless File.file?(file)

      date = File.mtime(file)
      latest_date = date if latest_date.nil? || date > latest_date
      newest_file = file if date == latest_date
    end
  end
  newest_file
end

.get_newest_file_timestamp(directory_path) ⇒ Object



146
147
148
149
# File 'lib/makit/directory.rb', line 146

def self.get_newest_file_timestamp(directory_path)
  newest_file = get_git_tracked_files(directory_path).select { |f| File.file?(f) }.max_by { |f| File.mtime(f) }
  newest_file.nil? ? Time.now : File.mtime(newest_file)
end

.get_newest_git_file(directory_path) ⇒ Object



138
139
140
# File 'lib/makit/directory.rb', line 138

def self.get_newest_git_file(directory_path)
  get_git_tracked_files(directory_path).select { |f| File.file?(f) }.max_by { |f| File.mtime(f) }
end

.get_newest_git_file_timestamp(directory_path) ⇒ Object



142
143
144
# File 'lib/makit/directory.rb', line 142

def self.get_newest_git_file_timestamp(directory_path)
  get_newest_git_file(directory_path).nil? ? Time.now : File.mtime(get_newest_git_file(directory_path))
end

.get_relative_paths(directory_path, pattern = "**/*") ⇒ Object



250
251
252
253
254
255
256
257
258
259
260
# File 'lib/makit/directory.rb', line 250

def self.get_relative_paths(directory_path, pattern = "**/*")
  relative_paths = []

  Dir.chdir(directory_path) do
    Dir.glob(pattern).each do |file|
      relative_paths << file
    end
  end

  relative_paths
end

.get_size(directory) ⇒ Object



98
99
100
101
102
103
104
105
106
# File 'lib/makit/directory.rb', line 98

def self.get_size(directory)
  total_size = 0

  Find.find(directory) do |file|
    total_size += File.size(file) if File.file?(file)
  end

  total_size
end

.get_version_directories(path) ⇒ Object

for a given path, collect all the subdirectories that match a version pattern. for example 2.57.0, 2.62, or 2.65.0



162
163
164
165
166
167
168
169
170
# File 'lib/makit/directory.rb', line 162

def self.get_version_directories(path)
  version_directories = []
  Dir.foreach(path) do |entry|
    next if [".", ".."].include?(entry)

    version_directories << entry if entry.match?(/^\d+\.\d+\.\d+$/)
  end
  version_directories
end

.human_size(bytes) ⇒ Object



50
51
52
53
54
55
56
57
58
# File 'lib/makit/directory.rb', line 50

def self.human_size(bytes)
  units = %w[B KB MB GB TB]
  return "0 B" if bytes.zero?

  exp = (Math.log(bytes) / Math.log(1024)).to_i
  exp = units.size - 1 if exp >= units.size

  format("%.2f %s", bytes.to_f / (1024 ** exp), units[exp])
end

.modified(path) ⇒ Object



172
173
174
# File 'lib/makit/directory.rb', line 172

def self.modified(path)
  get_newest_file(path)
end

.normalize(path) ⇒ Object

Normalize the path by removing any leading or trailing slashes and replacing any backslashes with forward slashes



153
154
155
156
157
158
# File 'lib/makit/directory.rb', line 153

def self.normalize(path)
  path = path.gsub("\\", "/")
  # path = path[1..-1] if path.start_with?("/")

  path = path[0..-2] if path.end_with?("/")
  path
end

.remove_empty_directories(dir) ⇒ Object



220
221
222
223
224
# File 'lib/makit/directory.rb', line 220

def self.remove_empty_directories(dir)
  Find.find(dir) do |path|
    FileUtils.rm_rf(path) if File.directory?(path) && Dir.empty?(path)
  end
end

.remove_empty_directories_recursively(dir) ⇒ Object



226
227
228
229
230
# File 'lib/makit/directory.rb', line 226

def self.remove_empty_directories_recursively(dir)
  Find.find(dir) do |path|
    FileUtils.rm_rf(path) if File.directory?(path) && Dir.empty?(path)
  end
end

.show_dir_size(dir) ⇒ Object



15
16
17
18
19
20
21
22
# File 'lib/makit/directory.rb', line 15

def self.show_dir_size(dir)
  total_bytes = Dir.glob(File.join(dir, "**", "*"))
                   .select { |f| File.file?(f) }
                   .sum { |f| File.size(f) }

  human_size(total_bytes)
  puts "  directory #{dir.to_s.colorize(:green)} size is #{human_size(total_bytes).to_s.colorize(:green)}"
end

.show_largest_files(dir, limit) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/makit/directory.rb', line 24

def self.show_largest_files(dir, limit)
  puts "  directory #{dir.to_s.colorize(:green)} #{limit} largest files"
  files = Dir.glob(File.join(dir, "**", "*"), File::FNM_DOTMATCH)
             .select { |f| File.file?(f) }

  sorted = files.map { |f| [f, File.size(f)] }
                .sort_by { |_, size| -size }
                .first(limit)

  sorted.each do |path, size|
    # right justify human_size to be at least 10 characters wide

    padded_size = human_size(size).rjust(10)
    puts "  #{padded_size}" + " #{path}".colorize(:green)
  end
end

.zip_source_files(directory_path, zip_file_name) ⇒ Object

Raises:

  • (ArgumentError)


110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/makit/directory.rb', line 110

def self.zip_source_files(directory_path, zip_file_name)
  raise ArgumentError, "Directory path cannot be nil" if directory_path.nil?
  raise ArgumentError, "Zip file name cannot be nil or empty" if zip_file_name.nil? || zip_file_name.strip.empty?

  raise ArgumentError, "Directory '#{directory_path}' does not exist." unless Dir.exist?(directory_path)

  tracked_files = get_git_tracked_files(directory_path)

  raise "No tracked files found in the directory." if tracked_files.empty?

  Zip::File.open(zip_file_name, Zip::File::CREATE) do |zipfile|
    tracked_files.each do |file|
      full_path = File.join(directory_path, file)
      zipfile.add(file, full_path) if File.exist?(full_path)
    end
  end
end

Instance Method Details

#human_size(bytes) ⇒ Object



40
41
42
43
44
45
46
47
48
# File 'lib/makit/directory.rb', line 40

def human_size(bytes)
  units = %w[B KB MB GB TB]
  return "0 B" if bytes.zero?

  exp = (Math.log(bytes) / Math.log(1024)).to_i
  exp = units.size - 1 if exp >= units.size

  format("%.2f %s", bytes.to_f / (1024 ** exp), units[exp])
end