106 lines
2.2 KiB
Ruby
106 lines
2.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'optparse'
|
|
require 'etc'
|
|
|
|
COLUMNS = 3
|
|
MARGIN = 3
|
|
|
|
TYPES = {
|
|
'fifo' => 'p',
|
|
'characterSpecial' => 'c',
|
|
'directory' => 'd',
|
|
'blockSpecial' => 'b',
|
|
'file' => '-',
|
|
'link' => 'l',
|
|
'socket' => 's'
|
|
}.freeze
|
|
|
|
PERMISSIONS = {
|
|
'0' => '---',
|
|
'1' => '--x',
|
|
'2' => '-w-',
|
|
'3' => '-wx',
|
|
'4' => 'r--',
|
|
'5' => 'r-x',
|
|
'6' => 'rw-',
|
|
'7' => 'rwx'
|
|
}.freeze
|
|
|
|
def run
|
|
params = ARGV.getopts('a', 'r', 'l')
|
|
filenames = params['a'] ? Dir.glob('*', File::FNM_DOTMATCH) : Dir.glob('*')
|
|
filenames = filenames.reverse if params['r']
|
|
params['l'] ? output_file_datails(filenames) : output(filenames)
|
|
end
|
|
|
|
def output(filenames)
|
|
rows = filenames.size.ceildiv(COLUMNS)
|
|
pads = pad_created(filenames, rows)
|
|
(0...rows).each do |row|
|
|
COLUMNS.times do |column|
|
|
index = row + column * rows
|
|
print filenames[index].ljust(pads[column] + COLUMNS) if filenames[index]
|
|
end
|
|
puts
|
|
end
|
|
end
|
|
|
|
def pad_created(filenames, rows)
|
|
filenames.each_slice(rows).map { _1.map(&:length).max }
|
|
end
|
|
|
|
def output_file_datails(filenames)
|
|
puts total_file_blocks(filenames)
|
|
filenames.each do |file|
|
|
file_stat = File::Stat.new(file)
|
|
print TYPES[file_stat.ftype]
|
|
print file_mode(file_stat)
|
|
print owner_info(file_stat, filenames)
|
|
print time_stamp(file_stat)
|
|
print symbolic(file)
|
|
puts
|
|
end
|
|
end
|
|
|
|
def owner_info(file_stat, filenames)
|
|
[
|
|
file_stat.nlink.to_s.prepend(' '),
|
|
Etc.getpwuid(file_stat.uid).name,
|
|
Etc.getgrgid(file_stat.gid).name,
|
|
file_stat.size.to_s.rjust(max_filename_length(filenames))
|
|
].join(' ')
|
|
end
|
|
|
|
def symbolic(filenames)
|
|
if File.lstat(filenames).symlink?
|
|
" #{filenames} -> #{File.readlink(filenames)}"
|
|
else
|
|
" #{filenames}"
|
|
end
|
|
end
|
|
|
|
def file_mode(file_stat)
|
|
file_count = file_stat.mode.to_s(8).slice(-3, 3)
|
|
file_permission = file_count.split('').map do |file|
|
|
PERMISSIONS[file]
|
|
end
|
|
file_permission.join('')
|
|
end
|
|
|
|
def max_filename_length(filenames)
|
|
filenames.map { |file| File.size(file) }.max.to_s.length + MARGIN
|
|
end
|
|
|
|
def time_stamp(file_stat)
|
|
file_stat.mtime.strftime('%_m月 %_d %H:%M')
|
|
end
|
|
|
|
def total_file_blocks(filenames)
|
|
blocks = filenames.map do |file|
|
|
File::Stat.new(file).blocks
|
|
end
|
|
"total #{blocks.sum}"
|
|
end
|
|
|
|
run
|