79 lines
1.7 KiB
Ruby
79 lines
1.7 KiB
Ruby
# typed: strict
|
|
# frozen_string_literal: true
|
|
|
|
module DiskUsageExtension
|
|
extend T::Helpers
|
|
|
|
requires_ancestor { Pathname }
|
|
|
|
sig { returns(Integer) }
|
|
def disk_usage
|
|
@disk_usage ||= T.let(nil, T.nilable(Integer))
|
|
return @disk_usage unless @disk_usage.nil?
|
|
|
|
@file_count, @disk_usage = compute_disk_usage
|
|
@disk_usage
|
|
end
|
|
|
|
sig { returns(Integer) }
|
|
def file_count
|
|
@file_count ||= T.let(nil, T.nilable(Integer))
|
|
return @file_count unless @file_count.nil?
|
|
|
|
@file_count, @disk_usage = compute_disk_usage
|
|
@file_count
|
|
end
|
|
|
|
sig { returns(String) }
|
|
def abv
|
|
out = +""
|
|
@file_count, @disk_usage = compute_disk_usage
|
|
out << "#{number_readable(@file_count)} files, " if @file_count > 1
|
|
out << disk_usage_readable(@disk_usage).to_s
|
|
out.freeze
|
|
end
|
|
|
|
private
|
|
|
|
sig { returns([Integer, Integer]) }
|
|
def compute_disk_usage
|
|
if symlink? && !exist?
|
|
file_count = 1
|
|
disk_usage = 0
|
|
return [file_count, disk_usage]
|
|
end
|
|
|
|
path = if symlink?
|
|
resolved_path
|
|
else
|
|
self
|
|
end
|
|
|
|
if path.directory?
|
|
scanned_files = Set.new
|
|
file_count = 0
|
|
disk_usage = 0
|
|
path.find do |f|
|
|
if f.directory?
|
|
disk_usage += f.lstat.size
|
|
else
|
|
file_count += 1 if f.basename.to_s != ".DS_Store"
|
|
# use Pathname#lstat instead of Pathname#stat to get info of symlink itself.
|
|
stat = f.lstat
|
|
file_id = [stat.dev, stat.ino]
|
|
# count hardlinks only once.
|
|
unless scanned_files.include?(file_id)
|
|
disk_usage += stat.size
|
|
scanned_files.add(file_id)
|
|
end
|
|
end
|
|
end
|
|
else
|
|
file_count = 1
|
|
disk_usage = path.lstat.size
|
|
end
|
|
|
|
[file_count, disk_usage]
|
|
end
|
|
end
|