From 3e9e24aaa7c9259c80dbaa004f379969888c3fab Mon Sep 17 00:00:00 2001 From: Miya096jp Date: Mon, 16 Dec 2024 17:43:04 +0900 Subject: [PATCH 01/24] =?UTF-8?q?=E3=81=A8=E3=82=8A=E3=81=82=E3=81=88?= =?UTF-8?q?=E3=81=9A-a=E3=82=AA=E3=83=97=E3=82=B7=E3=83=A7=E3=83=B3?= =?UTF-8?q?=E3=80=81-r=E3=82=AA=E3=83=97=E3=82=B7=E3=83=A7=E3=83=B3?= =?UTF-8?q?=E3=82=92=E6=B8=A1=E3=81=97=E3=81=A6=E6=AD=A3=E5=B8=B8=E3=81=AB?= =?UTF-8?q?=E5=8B=95=E4=BD=9C=E3=81=97=E3=81=9F=E3=81=AE=E3=81=A7=E3=80=81?= =?UTF-8?q?=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AB=E5=88=86=E5=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/ls.rb | 90 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 07.ls_object/ls.rb diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb new file mode 100644 index 0000000000..a15fe81ca8 --- /dev/null +++ b/07.ls_object/ls.rb @@ -0,0 +1,90 @@ +#!/usr/bin/env ruby + +# frozen_string_literal: true + +require 'pathname' +require 'optparse' +require 'debug' + +COLUMN = 3 + +class Options + def self.parse + opt = OptionParser.new + params = { long_format: false, reverse: false, dot_match: false } + opt.on('-l') { |v| params[:long_format] = v } + opt.on('-r') { |v| params[:reverse] = v } + opt.on('-a') { |v| params[:dot_match] = v } + opt.parse!(ARGV) + params + end +end + +class Paths + def initialize(params) + @reverse = params[:reverse] + @dot_match = params[:dot_match] + end + + def detect_path + ARGV[0] || '.' + end + + def create_pathname + Pathname(detect_path) + end + + def parse + paths = @dot_match ? Dir.glob(create_pathname.join('*'), File::FNM_DOTMATCH).sort : Dir.glob(create_pathname.join('*')) + reverse(paths) + end + + def reverse(paths) + @reverse ? paths.reverse : paths + end +end + +class LsShort + def initialize(paths) + @paths = paths + end + + def parse + paths = jusify_paths + row = count_row + sliced_paths = slice_paths(paths, row) + transpose(sliced_paths).each { |a| puts a.join } + end + + private + + def jusify_paths + max_length = @paths.map(&:size).max + @paths.map { |path| path.ljust(max_length) } + end + + def count_row + (@paths.size.to_f / COLUMN).ceil + end + + def slice_paths(paths, row) + paths.each_slice(row).to_a + end + + def transpose(sliced_paths) + sliced_paths[0].zip(*sliced_paths[1..]) + end +end + +class Ls + def self.run + params = Options.parse + paths = Paths.new(params).parse + params[:long_format] ? LsLong.new(paths).parse : LsShort.new(paths).parse + end +end + +Ls.run + +class LsLong +end From 4d0ace7420e375c57c29a27e22e336a967394853 Mon Sep 17 00:00:00 2001 From: Miya096jp Date: Tue, 17 Dec 2024 20:17:25 +0900 Subject: [PATCH 02/24] =?UTF-8?q?=E3=83=99=E3=82=BF=E6=89=93=E3=81=A1?= =?UTF-8?q?=E3=81=A7l=E3=82=AA=E3=83=97=E3=82=B7=E3=83=A7=E3=83=B3?= =?UTF-8?q?=E3=81=AB=E5=AF=BE=E5=BF=9C=E3=81=97=E3=80=81=E3=82=AF=E3=83=A9?= =?UTF-8?q?=E3=82=B9=E3=81=AB=E5=88=86=E5=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/ls.rb | 196 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 156 insertions(+), 40 deletions(-) diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb index a15fe81ca8..c59008fd7f 100644 --- a/07.ls_object/ls.rb +++ b/07.ls_object/ls.rb @@ -4,87 +4,203 @@ require 'pathname' require 'optparse' -require 'debug' +require 'etc' + +COLUMN = 3 + +MODE_TABLE = { + '0' => '___', + '1' => '__x', + '2' => '_w_', + '3' => '_wx', + '4' => 'r__', + '5' => 'r_x', + '6' => 'rw_', + '7' => 'rwx' +} COLUMN = 3 class Options - def self.parse - opt = OptionParser.new - params = { long_format: false, reverse: false, dot_match: false } - opt.on('-l') { |v| params[:long_format] = v } - opt.on('-r') { |v| params[:reverse] = v } - opt.on('-a') { |v| params[:dot_match] = v } - opt.parse!(ARGV) - params + def initialize(opts) + opts.on('-l') { |v| @long_format = v } + opts.on('-r') { |v| @reverse = v } + opts.on('-a') { |v| @dot_match = v } + opts.parse!(ARGV) end -end -class Paths - def initialize(params) - @reverse = params[:reverse] - @dot_match = params[:dot_match] + def long_format? + @long_format end - def detect_path - ARGV[0] || '.' + def reverse? + @reverse + end + + def dot_match? + @dot_match + end +end + +class Paths + def initialize(options, input) + @options = options + @input = input end def create_pathname - Pathname(detect_path) + Pathname(@input) end def parse - paths = @dot_match ? Dir.glob(create_pathname.join('*'), File::FNM_DOTMATCH).sort : Dir.glob(create_pathname.join('*')) + paths = @options.dot_match? ? Dir.glob(create_pathname.join('*'), File::FNM_DOTMATCH).sort : Dir.glob(create_pathname.join('*')) reverse(paths) end def reverse(paths) - @reverse ? paths.reverse : paths + @options.reverse? ? paths.reverse : paths end end -class LsShort - def initialize(paths) - @paths = paths +class Entry + def initialize(path) + @path = path + @stat = File::Stat.new(path) end - def parse - paths = jusify_paths + def name + File.basename(@path) + end + + def type_and_mode + format_type_and_mode(@stat) + end + + def nlink + @stat.nlink.to_s + end + + def username + Etc.getpwuid(@stat.uid).name + end + + def groupname + Etc.getgrgid(@stat.uid).name + end + + def bytesize + @stat.size.to_s + end + + def mtime + format_mtime(@stat.mtime) + end + + def blocks + @stat.blocks + end + + private + + def format_type_and_mode(stat) + type = stat.directory? ? 'd' : '-' + digits = stat.mode.to_s(8)[-3..] + mode = digits.gsub(/./, MODE_TABLE) + "#{type}#{mode}" + end + + def format_mtime(mtime) + format('%2d %2d %2d:%2d', mon: mtime.mon, mday: mtime.mday, hour: mtime.hour, min: mtime.min) + end +end + +class LsFormatter + def initialize(entries, options = nil) + @entries = entries + @options = options + end + + def print + @options.long_format? ? LsLong.new(@entries).print : LsShort.new(@entries).print + end +end + +class LsShort < LsFormatter + def print + entries = justfy_entries row = count_row - sliced_paths = slice_paths(paths, row) - transpose(sliced_paths).each { |a| puts a.join } + sliced_entries = slice_entries(entries, row) + transpose(sliced_entries).each { |entry| puts entry.join } end private - def jusify_paths - max_length = @paths.map(&:size).max - @paths.map { |path| path.ljust(max_length) } + def justfy_entries + max_length = @entries.map { |entry| entry.name.size }.max + @entries.map { |entry| entry.name.ljust(max_length) } end def count_row - (@paths.size.to_f / COLUMN).ceil + (@entries.size.to_f / COLUMN ).ceil end - def slice_paths(paths, row) - paths.each_slice(row).to_a + def slice_entries(entries, row) + entries.each_slice(row).to_a end - def transpose(sliced_paths) - sliced_paths[0].zip(*sliced_paths[1..]) + def transpose(sliced_entries) + sliced_entries[0].zip(*sliced_entries[1..]) + end +end + +class LsLong < LsFormatter + def print + max_size = build_max_size + puts build_total_row + puts build_body(max_size) + end + + def build_max_size + { + nlink: @entries.map { |entry| entry.nlink.size }.max, + username: @entries.map { |entry| entry.username.size }.max, + groupname: @entries.map { |entry| entry.groupname.size }.max, + bytesize: @entries.map { |entry| entry.bytesize.size }.max + } + end + + def build_total_row + total = @entries.sum { |entry| entry.blocks.to_i } + "total: #{total}" + end + + def build_body(max_size) + @entries.map do |entry| + [ + entry.type_and_mode, + entry.nlink.rjust(max_size[:nlink] + 1), + entry.username.rjust(max_size[:username] + 1), + entry.groupname.rjust(max_size[:groupname] + 1), + entry.bytesize.rjust(max_size[:bytesize] + 1), + " #{entry.mtime}", + " #{entry.name}" + ].join + end end end class Ls def self.run - params = Options.parse - paths = Paths.new(params).parse - params[:long_format] ? LsLong.new(paths).parse : LsShort.new(paths).parse + opts = OptionParser.new + options = Options.new(opts) + paths = Paths.new(options, find_input).parse + entries = paths.map { |path| Entry.new(path) } + LsFormatter.new(entries, options).print + end + + def self.find_input + ARGV[0] || '.' end end Ls.run - -class LsLong -end From 1b19a84cab0999584ef08906a0c66bce8057401c Mon Sep 17 00:00:00 2001 From: Miya096jp Date: Wed, 18 Dec 2024 00:14:22 +0900 Subject: [PATCH 03/24] =?UTF-8?q?Entry=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=8B?= =?UTF-8?q?=E3=82=89=E3=80=81=E5=90=84=E3=83=A1=E3=82=BF=E3=83=87=E3=83=BC?= =?UTF-8?q?=E3=82=BF=E3=81=AE=E5=87=BA=E5=8A=9B=E3=83=95=E3=82=A9=E3=83=BC?= =?UTF-8?q?=E3=83=9E=E3=83=83=E3=83=88=E3=81=AB=E9=96=A2=E3=81=99=E3=82=8B?= =?UTF-8?q?=E5=87=A6=E7=90=86=E3=82=92LsLong=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=81=AB=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/ls.rb | 69 +++++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb index c59008fd7f..35c868705b 100644 --- a/07.ls_object/ls.rb +++ b/07.ls_object/ls.rb @@ -17,7 +17,7 @@ '5' => 'r_x', '6' => 'rw_', '7' => 'rwx' -} +}.freeze COLUMN = 3 @@ -63,21 +63,25 @@ def reverse(paths) end class Entry - def initialize(path) + def initialize(path, stat) @path = path - @stat = File::Stat.new(path) + @stat = stat end def name File.basename(@path) end - def type_and_mode - format_type_and_mode(@stat) + def type + format_type(@stat) + end + + def mode + format_mode(@stat) end def nlink - @stat.nlink.to_s + @stat.nlink end def username @@ -85,15 +89,15 @@ def username end def groupname - Etc.getgrgid(@stat.uid).name + Etc.getgrgid(@stat.gid).name end def bytesize - @stat.size.to_s + @stat.size end def mtime - format_mtime(@stat.mtime) + @stat.mtime end def blocks @@ -102,26 +106,18 @@ def blocks private - def format_type_and_mode(stat) - type = stat.directory? ? 'd' : '-' - digits = stat.mode.to_s(8)[-3..] - mode = digits.gsub(/./, MODE_TABLE) - "#{type}#{mode}" + def format_type(stat) + stat.directory? ? 'd' : '-' end - def format_mtime(mtime) - format('%2d %2d %2d:%2d', mon: mtime.mon, mday: mtime.mday, hour: mtime.hour, min: mtime.min) + def format_mode(stat) + stat.mode.to_s(8)[-3..] end end class LsFormatter - def initialize(entries, options = nil) + def initialize(entries) @entries = entries - @options = options - end - - def print - @options.long_format? ? LsLong.new(@entries).print : LsShort.new(@entries).print end end @@ -141,7 +137,7 @@ def justfy_entries end def count_row - (@entries.size.to_f / COLUMN ).ceil + (@entries.size.to_f / COLUMN).ceil end def slice_entries(entries, row) @@ -162,10 +158,10 @@ def print def build_max_size { - nlink: @entries.map { |entry| entry.nlink.size }.max, + nlink: @entries.map { |entry| entry.nlink.to_s.size }.max, username: @entries.map { |entry| entry.username.size }.max, groupname: @entries.map { |entry| entry.groupname.size }.max, - bytesize: @entries.map { |entry| entry.bytesize.size }.max + bytesize: @entries.map { |entry| entry.bytesize.to_s.size }.max } end @@ -177,16 +173,25 @@ def build_total_row def build_body(max_size) @entries.map do |entry| [ - entry.type_and_mode, - entry.nlink.rjust(max_size[:nlink] + 1), + "#{entry.type}#{format_mode(entry)}", + entry.nlink.to_s.rjust(max_size[:nlink] + 1), entry.username.rjust(max_size[:username] + 1), entry.groupname.rjust(max_size[:groupname] + 1), - entry.bytesize.rjust(max_size[:bytesize] + 1), - " #{entry.mtime}", + entry.bytesize.to_s.rjust(max_size[:bytesize] + 1), + " #{format_mtime(entry.mtime)}", " #{entry.name}" ].join end end + + def format_mode(entry) + digits = entry.mode + digits.gsub(/./, MODE_TABLE) + end + + def format_mtime(mtime) + format('%2d %2d %2d:%2d', mon: mtime.mon, mday: mtime.mday, hour: mtime.hour, min: mtime.min) + end end class Ls @@ -194,8 +199,10 @@ def self.run opts = OptionParser.new options = Options.new(opts) paths = Paths.new(options, find_input).parse - entries = paths.map { |path| Entry.new(path) } - LsFormatter.new(entries, options).print + entries = paths.map { |path| Entry.new(path, File::Stat.new(path)) } + LsFormatter.new(entries) + ls = options.long_format? ? LsLong.new(entries) : LsShort.new(entries) + ls.print end def self.find_input From 1593e410a27010d8d8de6513161434832ed0d422 Mon Sep 17 00:00:00 2001 From: Miya096jp Date: Wed, 18 Dec 2024 15:04:51 +0900 Subject: [PATCH 04/24] =?UTF-8?q?=E7=89=B9=E6=AE=8A=E6=A8=A9=E9=99=90?= =?UTF-8?q?=E3=81=AE=E8=A1=A8=E7=A4=BA=E3=81=AB=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/ls.rb | 89 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 77 insertions(+), 12 deletions(-) mode change 100644 => 100755 07.ls_object/ls.rb diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb old mode 100644 new mode 100755 index 35c868705b..958666fe9f --- a/07.ls_object/ls.rb +++ b/07.ls_object/ls.rb @@ -8,17 +8,49 @@ COLUMN = 3 -MODE_TABLE = { - '0' => '___', - '1' => '__x', - '2' => '_w_', - '3' => '_wx', - '4' => 'r__', - '5' => 'r_x', - '6' => 'rw_', +FILETYPE = { + '1' => 'p', + '2' => 'c', + '4' => 'd', + '6' => 'b', + '10' => '-', + '12' => 'l', + '14' => 's' +}.freeze + +REGULAR_MODE = { + '0' => '---', + '1' => '--x', + '2' => '-w-', + '3' => '-wx', + '4' => 'r--', + '5' => 'r-x', + '6' => 'rw-', '7' => 'rwx' }.freeze +SUID_SGID = { + '0' => '---', + '1' => '--s', + '2' => '-wS', + '3' => '-ws', + '4' => 'r-S', + '5' => 'r-s', + '6' => 'rwS', + '7' => 'rws' +}.freeze + +STICKY_BIT = { + '0' => '---', + '1' => '--t', + '2' => '-wT', + '3' => '-wt', + '4' => 'r-T', + '5' => 'r-t', + '6' => 'rwT', + '7' => 'rwt' +}.freeze + COLUMN = 3 class Options @@ -80,6 +112,18 @@ def mode format_mode(@stat) end + def setuid? + @stat.setuid? + end + + def setgid? + @stat.setgid? + end + + def sticky? + @stat.sticky? + end + def nlink @stat.nlink end @@ -107,7 +151,7 @@ def blocks private def format_type(stat) - stat.directory? ? 'd' : '-' + stat.mode.to_s(8)[..-5] end def format_mode(stat) @@ -156,6 +200,8 @@ def print puts build_body(max_size) end + private + def build_max_size { nlink: @entries.map { |entry| entry.nlink.to_s.size }.max, @@ -173,7 +219,7 @@ def build_total_row def build_body(max_size) @entries.map do |entry| [ - "#{entry.type}#{format_mode(entry)}", + "#{format_type(entry)}#{format_mode(entry)}", entry.nlink.to_s.rjust(max_size[:nlink] + 1), entry.username.rjust(max_size[:username] + 1), entry.groupname.rjust(max_size[:groupname] + 1), @@ -184,9 +230,28 @@ def build_body(max_size) end end + def format_type(entry) + digits = entry.type + digits.gsub(/./, FILETYPE) + end + def format_mode(entry) - digits = entry.mode - digits.gsub(/./, MODE_TABLE) + digits = entry.mode.split('') + digits.map.with_index do |digit, index| + table_for_digits(digit, index, entry) + end.join + end + + def table_for_digits(digit, index, entry) + if index.zero? && entry.setuid? + SUID_SGID[digit] + elsif index == 1 && entry.setgid? + SUID_SGID[digit] + elsif index == 2 && entry.sticky? + STICKY_BIT[digit] + else + REGULAR_MODE[digit] + end end def format_mtime(mtime) From c275ef2c91769fab60ec2585682796f45804fe50 Mon Sep 17 00:00:00 2001 From: Miya096jp Date: Thu, 19 Dec 2024 10:59:48 +0900 Subject: [PATCH 05/24] =?UTF-8?q?=E3=82=B3=E3=83=9E=E3=83=B3=E3=83=89?= =?UTF-8?q?=E3=81=AB=E7=9B=B4=E6=8E=A5=E3=83=87=E3=82=A3=E3=83=AC=E3=82=AF?= =?UTF-8?q?=E3=83=88=E3=83=AA=E3=82=92=E6=B8=A1=E3=81=99=E5=87=A6=E7=90=86?= =?UTF-8?q?=E3=82=92=E5=89=8A=E9=99=A4(=E4=BF=AE=E4=BA=86=E8=A6=81?= =?UTF-8?q?=E4=BB=B6=E3=81=AB=E3=81=AA=E3=81=8B=E3=81=A3=E3=81=9F=E3=81=9F?= =?UTF-8?q?=E3=82=81)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/ls.rb | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb index 958666fe9f..d980afadd0 100755 --- a/07.ls_object/ls.rb +++ b/07.ls_object/ls.rb @@ -2,7 +2,6 @@ # frozen_string_literal: true -require 'pathname' require 'optparse' require 'etc' @@ -51,8 +50,6 @@ '7' => 'rwt' }.freeze -COLUMN = 3 - class Options def initialize(opts) opts.on('-l') { |v| @long_format = v } @@ -75,20 +72,17 @@ def dot_match? end class Paths - def initialize(options, input) + def initialize(options) @options = options - @input = input - end - - def create_pathname - Pathname(@input) end def parse - paths = @options.dot_match? ? Dir.glob(create_pathname.join('*'), File::FNM_DOTMATCH).sort : Dir.glob(create_pathname.join('*')) + paths = @options.dot_match? ? Dir.glob('*', File::FNM_DOTMATCH).sort : Dir.glob('*') reverse(paths) end + private + def reverse(paths) @options.reverse? ? paths.reverse : paths end @@ -148,6 +142,18 @@ def blocks @stat.blocks end + def owner + format_mode(@stat).slice(0) + end + + def group + format_mode(@stat).slice(1) + end + + def others + format_mode(@stat).slice(2) + end + private def format_type(stat) @@ -237,17 +243,17 @@ def format_type(entry) def format_mode(entry) digits = entry.mode.split('') - digits.map.with_index do |digit, index| - table_for_digits(digit, index, entry) + digits.map do |digit| + table_for_permissions(digit, entry) end.join end - def table_for_digits(digit, index, entry) - if index.zero? && entry.setuid? + def table_for_permissions(digit, entry) + if entry.owner && entry.setuid? SUID_SGID[digit] - elsif index == 1 && entry.setgid? + elsif entry.group && entry.setgid? SUID_SGID[digit] - elsif index == 2 && entry.sticky? + elsif entry.others && entry.sticky? STICKY_BIT[digit] else REGULAR_MODE[digit] @@ -263,16 +269,12 @@ class Ls def self.run opts = OptionParser.new options = Options.new(opts) - paths = Paths.new(options, find_input).parse + paths = Paths.new(options).parse entries = paths.map { |path| Entry.new(path, File::Stat.new(path)) } LsFormatter.new(entries) ls = options.long_format? ? LsLong.new(entries) : LsShort.new(entries) ls.print end - - def self.find_input - ARGV[0] || '.' - end end Ls.run From 6153cb3021ad116b25623526a0b9040dc5b55c1a Mon Sep 17 00:00:00 2001 From: Miya096jp Date: Thu, 19 Dec 2024 11:43:47 +0900 Subject: [PATCH 06/24] =?UTF-8?q?=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=94?= =?UTF-8?q?=E3=81=A8=E3=81=AB=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB=E3=82=92?= =?UTF-8?q?=E5=88=86=E5=89=B2=E3=81=97=E5=8B=95=E4=BD=9C=E7=A2=BA=E8=AA=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/lib/entry.rb | 80 ++++++++ 07.ls_object/lib/formatter/ls_formatter.rb | 7 + 07.ls_object/lib/formatter/ls_long.rb | 67 +++++++ 07.ls_object/lib/formatter/ls_short.rb | 29 +++ 07.ls_object/lib/options.rb | 24 +++ 07.ls_object/lib/paths.rb | 18 ++ 07.ls_object/ls.rb | 223 +-------------------- 7 files changed, 231 insertions(+), 217 deletions(-) create mode 100644 07.ls_object/lib/entry.rb create mode 100644 07.ls_object/lib/formatter/ls_formatter.rb create mode 100644 07.ls_object/lib/formatter/ls_long.rb create mode 100644 07.ls_object/lib/formatter/ls_short.rb create mode 100644 07.ls_object/lib/options.rb create mode 100644 07.ls_object/lib/paths.rb diff --git a/07.ls_object/lib/entry.rb b/07.ls_object/lib/entry.rb new file mode 100644 index 0000000000..9f368d9fca --- /dev/null +++ b/07.ls_object/lib/entry.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: true + +require 'etc' + +class Entry + def initialize(path, stat) + @path = path + @stat = stat + end + + def name + File.basename(@path) + end + + def type + format_type(@stat) + end + + def mode + format_mode(@stat) + end + + def setuid? + @stat.setuid? + end + + def setgid? + @stat.setgid? + end + + def sticky? + @stat.sticky? + end + + def nlink + @stat.nlink + end + + def username + Etc.getpwuid(@stat.uid).name + end + + def groupname + Etc.getgrgid(@stat.gid).name + end + + def bytesize + @stat.size + end + + def mtime + @stat.mtime + end + + def blocks + @stat.blocks + end + + def owner + format_mode(@stat).slice(0) + end + + def group + format_mode(@stat).slice(1) + end + + def others + format_mode(@stat).slice(2) + end + + private + + def format_type(stat) + stat.mode.to_s(8)[..-5] + end + + def format_mode(stat) + stat.mode.to_s(8)[-3..] + end +end diff --git a/07.ls_object/lib/formatter/ls_formatter.rb b/07.ls_object/lib/formatter/ls_formatter.rb new file mode 100644 index 0000000000..8813d3e4b6 --- /dev/null +++ b/07.ls_object/lib/formatter/ls_formatter.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class LsFormatter + def initialize(entries) + @entries = entries + end +end diff --git a/07.ls_object/lib/formatter/ls_long.rb b/07.ls_object/lib/formatter/ls_long.rb new file mode 100644 index 0000000000..4d7f11024a --- /dev/null +++ b/07.ls_object/lib/formatter/ls_long.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +class LsLong < LsFormatter + def print + max_size = build_max_size + puts build_total_row + puts build_body(max_size) + end + + private + + def build_max_size + { + nlink: @entries.map { |entry| entry.nlink.to_s.size }.max, + username: @entries.map { |entry| entry.username.size }.max, + groupname: @entries.map { |entry| entry.groupname.size }.max, + bytesize: @entries.map { |entry| entry.bytesize.to_s.size }.max + } + end + + def build_total_row + total = @entries.sum { |entry| entry.blocks.to_i } + "total: #{total}" + end + + def build_body(max_size) + @entries.map do |entry| + [ + "#{format_type(entry)}#{format_mode(entry)}", + entry.nlink.to_s.rjust(max_size[:nlink] + 1), + entry.username.rjust(max_size[:username] + 1), + entry.groupname.rjust(max_size[:groupname] + 1), + entry.bytesize.to_s.rjust(max_size[:bytesize] + 1), + " #{format_mtime(entry.mtime)}", + " #{entry.name}" + ].join + end + end + + def format_type(entry) + digits = entry.type + digits.gsub(/./, FILETYPE) + end + + def format_mode(entry) + digits = entry.mode.split('') + digits.map do |digit| + table_for_permissions(digit, entry) + end.join + end + + def table_for_permissions(digit, entry) + if entry.owner && entry.setuid? + SUID_SGID[digit] + elsif entry.group && entry.setgid? + SUID_SGID[digit] + elsif entry.others && entry.sticky? + STICKY_BIT[digit] + else + REGULAR_MODE[digit] + end + end + + def format_mtime(mtime) + format('%2d %2d %2d:%2d', mon: mtime.mon, mday: mtime.mday, hour: mtime.hour, min: mtime.min) + end +end diff --git a/07.ls_object/lib/formatter/ls_short.rb b/07.ls_object/lib/formatter/ls_short.rb new file mode 100644 index 0000000000..2da177b0e8 --- /dev/null +++ b/07.ls_object/lib/formatter/ls_short.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +class LsShort < LsFormatter + def print + entries = justfy_entries + row = count_row + sliced_entries = slice_entries(entries, row) + transpose(sliced_entries).each { |entry| puts entry.join } + end + + private + + def justfy_entries + max_length = @entries.map { |entry| entry.name.size }.max + @entries.map { |entry| entry.name.ljust(max_length + 1) } + end + + def count_row + (@entries.size.to_f / COLUMN).ceil + end + + def slice_entries(entries, row) + entries.each_slice(row).to_a + end + + def transpose(sliced_entries) + sliced_entries[0].zip(*sliced_entries[1..]) + end +end diff --git a/07.ls_object/lib/options.rb b/07.ls_object/lib/options.rb new file mode 100644 index 0000000000..46740c9492 --- /dev/null +++ b/07.ls_object/lib/options.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'optparse' + +class Options + def initialize(opts) + opts.on('-l') { |v| @long_format = v } + opts.on('-r') { |v| @reverse = v } + opts.on('-a') { |v| @dot_match = v } + opts.parse!(ARGV) + end + + def long_format? + @long_format + end + + def reverse? + @reverse + end + + def dot_match? + @dot_match + end +end diff --git a/07.ls_object/lib/paths.rb b/07.ls_object/lib/paths.rb new file mode 100644 index 0000000000..27f3935fc3 --- /dev/null +++ b/07.ls_object/lib/paths.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +class Paths + def initialize(options) + @options = options + end + + def parse + paths = @options.dot_match? ? Dir.glob('*', File::FNM_DOTMATCH).sort : Dir.glob('*') + reverse(paths) + end + + private + + def reverse(paths) + @options.reverse? ? paths.reverse : paths + end +end diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb index d980afadd0..07fabb471a 100755 --- a/07.ls_object/ls.rb +++ b/07.ls_object/ls.rb @@ -2,8 +2,12 @@ # frozen_string_literal: true -require 'optparse' -require 'etc' +require_relative './lib/options' +require_relative './lib/entry' +require_relative './lib/paths' +require_relative './lib/formatter/ls_formatter' +require_relative './lib/formatter/ls_short' +require_relative './lib/formatter/ls_long' COLUMN = 3 @@ -50,221 +54,6 @@ '7' => 'rwt' }.freeze -class Options - def initialize(opts) - opts.on('-l') { |v| @long_format = v } - opts.on('-r') { |v| @reverse = v } - opts.on('-a') { |v| @dot_match = v } - opts.parse!(ARGV) - end - - def long_format? - @long_format - end - - def reverse? - @reverse - end - - def dot_match? - @dot_match - end -end - -class Paths - def initialize(options) - @options = options - end - - def parse - paths = @options.dot_match? ? Dir.glob('*', File::FNM_DOTMATCH).sort : Dir.glob('*') - reverse(paths) - end - - private - - def reverse(paths) - @options.reverse? ? paths.reverse : paths - end -end - -class Entry - def initialize(path, stat) - @path = path - @stat = stat - end - - def name - File.basename(@path) - end - - def type - format_type(@stat) - end - - def mode - format_mode(@stat) - end - - def setuid? - @stat.setuid? - end - - def setgid? - @stat.setgid? - end - - def sticky? - @stat.sticky? - end - - def nlink - @stat.nlink - end - - def username - Etc.getpwuid(@stat.uid).name - end - - def groupname - Etc.getgrgid(@stat.gid).name - end - - def bytesize - @stat.size - end - - def mtime - @stat.mtime - end - - def blocks - @stat.blocks - end - - def owner - format_mode(@stat).slice(0) - end - - def group - format_mode(@stat).slice(1) - end - - def others - format_mode(@stat).slice(2) - end - - private - - def format_type(stat) - stat.mode.to_s(8)[..-5] - end - - def format_mode(stat) - stat.mode.to_s(8)[-3..] - end -end - -class LsFormatter - def initialize(entries) - @entries = entries - end -end - -class LsShort < LsFormatter - def print - entries = justfy_entries - row = count_row - sliced_entries = slice_entries(entries, row) - transpose(sliced_entries).each { |entry| puts entry.join } - end - - private - - def justfy_entries - max_length = @entries.map { |entry| entry.name.size }.max - @entries.map { |entry| entry.name.ljust(max_length) } - end - - def count_row - (@entries.size.to_f / COLUMN).ceil - end - - def slice_entries(entries, row) - entries.each_slice(row).to_a - end - - def transpose(sliced_entries) - sliced_entries[0].zip(*sliced_entries[1..]) - end -end - -class LsLong < LsFormatter - def print - max_size = build_max_size - puts build_total_row - puts build_body(max_size) - end - - private - - def build_max_size - { - nlink: @entries.map { |entry| entry.nlink.to_s.size }.max, - username: @entries.map { |entry| entry.username.size }.max, - groupname: @entries.map { |entry| entry.groupname.size }.max, - bytesize: @entries.map { |entry| entry.bytesize.to_s.size }.max - } - end - - def build_total_row - total = @entries.sum { |entry| entry.blocks.to_i } - "total: #{total}" - end - - def build_body(max_size) - @entries.map do |entry| - [ - "#{format_type(entry)}#{format_mode(entry)}", - entry.nlink.to_s.rjust(max_size[:nlink] + 1), - entry.username.rjust(max_size[:username] + 1), - entry.groupname.rjust(max_size[:groupname] + 1), - entry.bytesize.to_s.rjust(max_size[:bytesize] + 1), - " #{format_mtime(entry.mtime)}", - " #{entry.name}" - ].join - end - end - - def format_type(entry) - digits = entry.type - digits.gsub(/./, FILETYPE) - end - - def format_mode(entry) - digits = entry.mode.split('') - digits.map do |digit| - table_for_permissions(digit, entry) - end.join - end - - def table_for_permissions(digit, entry) - if entry.owner && entry.setuid? - SUID_SGID[digit] - elsif entry.group && entry.setgid? - SUID_SGID[digit] - elsif entry.others && entry.sticky? - STICKY_BIT[digit] - else - REGULAR_MODE[digit] - end - end - - def format_mtime(mtime) - format('%2d %2d %2d:%2d', mon: mtime.mon, mday: mtime.mday, hour: mtime.hour, min: mtime.min) - end -end - class Ls def self.run opts = OptionParser.new From 60bbae74975adada3caccd5ab87dcd5a09fff0af Mon Sep 17 00:00:00 2001 From: Miya096jp Date: Thu, 19 Dec 2024 13:50:40 +0900 Subject: [PATCH 07/24] =?UTF-8?q?Ls=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AEsel?= =?UTF-8?q?f.run=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89=E5=86=85=E3=81=AE?= =?UTF-8?q?=E8=A4=87=E6=95=B0=E3=81=AE=E5=87=A6=E7=90=86=E3=82=92=E3=83=A1?= =?UTF-8?q?=E3=82=BD=E3=83=83=E3=83=89=E3=81=AB=E5=88=86=E5=89=B2/Options?= =?UTF-8?q?=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AE=E5=BC=95=E6=95=B0=E3=81=A8?= =?UTF-8?q?=E3=81=97=E3=81=A6ARGV=E3=82=92=E6=B8=A1=E3=81=99=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB=E5=A4=89=E6=9B=B4=E3=81=97=E4=BE=9D=E5=AD=98?= =?UTF-8?q?=E3=82=92=E8=BB=BD=E6=B8=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/lib/options.rb | 4 ++-- 07.ls_object/ls.rb | 29 ++++++++++++++++++++++------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/07.ls_object/lib/options.rb b/07.ls_object/lib/options.rb index 46740c9492..922cdec995 100644 --- a/07.ls_object/lib/options.rb +++ b/07.ls_object/lib/options.rb @@ -3,11 +3,11 @@ require 'optparse' class Options - def initialize(opts) + def initialize(opts, arguments) opts.on('-l') { |v| @long_format = v } opts.on('-r') { |v| @reverse = v } opts.on('-a') { |v| @dot_match = v } - opts.parse!(ARGV) + opts.parse!(arguments) end def long_format? diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb index 07fabb471a..6503d44169 100755 --- a/07.ls_object/ls.rb +++ b/07.ls_object/ls.rb @@ -55,15 +55,30 @@ }.freeze class Ls - def self.run - opts = OptionParser.new - options = Options.new(opts) - paths = Paths.new(options).parse - entries = paths.map { |path| Entry.new(path, File::Stat.new(path)) } - LsFormatter.new(entries) - ls = options.long_format? ? LsLong.new(entries) : LsShort.new(entries) + def self.run(arguments = ARGV) + options = parse_options(arguments) + paths = parse_paths(options) + entries = parse_entries(paths) + ls = select_formatter(entries, options) ls.print end + + def self.parse_options(arguments) + opts = OptionParser.new + Options.new(opts, arguments) + end + + def self.parse_paths(options) + Paths.new(options).parse + end + + def self.parse_entries(paths) + paths.map { |path| Entry.new(path, File::Stat.new(path)) } + end + + def self.select_formatter(entries, options) + options.long_format? ? LsLong.new(entries) : LsShort.new(entries) + end end Ls.run From b771621ba7d5eeaea1294a2706bcc94c9dd6f8ea Mon Sep 17 00:00:00 2001 From: Miya096jp Date: Thu, 19 Dec 2024 16:11:40 +0900 Subject: [PATCH 08/24] =?UTF-8?q?LsShort=E3=82=AF=E3=83=A9=E3=82=B9,=20LsL?= =?UTF-8?q?ong=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AEprint=E3=83=A1=E3=82=BD?= =?UTF-8?q?=E3=83=83=E3=83=89=E3=82=92parse=E3=83=A1=E3=82=BD=E3=83=83?= =?UTF-8?q?=E3=83=89=E3=81=AB=E4=BF=AE=E6=AD=A3=E3=81=97=E3=80=81=E3=82=BF?= =?UTF-8?q?=E3=83=BC=E3=83=9F=E3=83=8A=E3=83=AB=E3=81=AB=E7=B5=90=E6=9E=9C?= =?UTF-8?q?=E3=82=92=E5=87=BA=E5=8A=9B=E3=81=99=E3=82=8B=E8=B2=AC=E4=BB=BB?= =?UTF-8?q?=E3=82=92ls.rb=E3=81=AE=E3=83=88=E3=83=83=E3=83=97=E3=83=AC?= =?UTF-8?q?=E3=83=99=E3=83=AB=E3=81=AB=E5=88=86=E9=9B=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/lib/formatter/ls_long.rb | 7 +- 07.ls_object/lib/formatter/ls_short.rb | 4 +- 07.ls_object/lib/paths.rb | 9 +- 07.ls_object/ls.rb | 4 +- .../test/test_files_and_directories/app_1.rb | 253 ++++++++++++++++++ .../test/test_files_and_directories/app_2.js | 85 ++++++ .../test_files_and_directories/file_1.txt | 27 ++ .../test_files_and_directories/file_2.txt | 72 +++++ .../test/test_files_and_directories/sgid_A | 0 .../test/test_files_and_directories/sgid_B | 0 .../test/test_files_and_directories/suid_A | 0 .../test/test_files_and_directories/suid_B | 0 07.ls_object/test/test_ls.rb | 19 ++ 13 files changed, 471 insertions(+), 9 deletions(-) create mode 100644 07.ls_object/test/test_files_and_directories/app_1.rb create mode 100644 07.ls_object/test/test_files_and_directories/app_2.js create mode 100644 07.ls_object/test/test_files_and_directories/file_1.txt create mode 100644 07.ls_object/test/test_files_and_directories/file_2.txt create mode 100755 07.ls_object/test/test_files_and_directories/sgid_A create mode 100755 07.ls_object/test/test_files_and_directories/sgid_B create mode 100644 07.ls_object/test/test_files_and_directories/suid_A create mode 100644 07.ls_object/test/test_files_and_directories/suid_B create mode 100644 07.ls_object/test/test_ls.rb diff --git a/07.ls_object/lib/formatter/ls_long.rb b/07.ls_object/lib/formatter/ls_long.rb index 4d7f11024a..2f314decc5 100644 --- a/07.ls_object/lib/formatter/ls_long.rb +++ b/07.ls_object/lib/formatter/ls_long.rb @@ -1,10 +1,9 @@ # frozen_string_literal: true class LsLong < LsFormatter - def print + def parse max_size = build_max_size - puts build_total_row - puts build_body(max_size) + "#{build_total_row}\n#{build_body(max_size)}" end private @@ -34,7 +33,7 @@ def build_body(max_size) " #{format_mtime(entry.mtime)}", " #{entry.name}" ].join - end + end.join("\n") end def format_type(entry) diff --git a/07.ls_object/lib/formatter/ls_short.rb b/07.ls_object/lib/formatter/ls_short.rb index 2da177b0e8..08891de568 100644 --- a/07.ls_object/lib/formatter/ls_short.rb +++ b/07.ls_object/lib/formatter/ls_short.rb @@ -1,11 +1,11 @@ # frozen_string_literal: true class LsShort < LsFormatter - def print + def parse entries = justfy_entries row = count_row sliced_entries = slice_entries(entries, row) - transpose(sliced_entries).each { |entry| puts entry.join } + transpose(sliced_entries).map(&:join) end private diff --git a/07.ls_object/lib/paths.rb b/07.ls_object/lib/paths.rb index 27f3935fc3..38fd1dbe85 100644 --- a/07.ls_object/lib/paths.rb +++ b/07.ls_object/lib/paths.rb @@ -1,12 +1,19 @@ # frozen_string_literal: true +require 'pathname' + class Paths def initialize(options) @options = options end + # def parse + # paths = @options.dot_match? ? Dir.glob('*', File::FNM_DOTMATCH).sort : Dir.glob('*') + # reverse(paths) + # end + def parse - paths = @options.dot_match? ? Dir.glob('*', File::FNM_DOTMATCH).sort : Dir.glob('*') + paths = @options.dot_match? ? Dir.glob(Pathname('./*'), File::FNM_DOTMATCH).sort : Dir.glob(Pathname('./*')) reverse(paths) end diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb index 6503d44169..3d4e9dcb6f 100755 --- a/07.ls_object/ls.rb +++ b/07.ls_object/ls.rb @@ -60,7 +60,7 @@ def self.run(arguments = ARGV) paths = parse_paths(options) entries = parse_entries(paths) ls = select_formatter(entries, options) - ls.print + ls.parse end def self.parse_options(arguments) @@ -81,4 +81,4 @@ def self.select_formatter(entries, options) end end -Ls.run +puts Ls.run diff --git a/07.ls_object/test/test_files_and_directories/app_1.rb b/07.ls_object/test/test_files_and_directories/app_1.rb new file mode 100644 index 0000000000..3e1bb71b93 --- /dev/null +++ b/07.ls_object/test/test_files_and_directories/app_1.rb @@ -0,0 +1,253 @@ + +#!/usr/bin/env ruby +#!/usr/bin/env ruby +#!/usr/bin/env ruby + +# frozen_string_literal: true + +require_relative './lib/options' +require_relative './lib/entry' +require_relative './lib/paths' +require_relative './lib/formatter/ls_formatter' +require_relative './lib/formatter/ls_short' +require_relative './lib/formatter/ls_long' + +COLUMN = 3 + +FILETYPE = { + '1' => 'p', + '2' => 'c', + '4' => 'd', + '6' => 'b', + '10' => '-', + '12' => 'l', + '14' => 's' +}.freeze + +REGULAR_MODE = { + '0' => '---', + '1' => '--x', + '2' => '-w-', + '3' => '-wx', + '4' => 'r--', + '5' => 'r-x', + '6' => 'rw-', + '7' => 'rwx' +}.freeze + +SUID_SGID = { + '0' => '---', + '1' => '--s', + '2' => '-wS', + '3' => '-ws', + '4' => 'r-S', + '5' => 'r-s', + '6' => 'rwS', + '7' => 'rws' +}.freeze + +STICKY_BIT = { + '0' => '---', + '1' => '--t', + '2' => '-wT', + '3' => '-wt', + '4' => 'r-T', + '5' => 'r-t', + '6' => 'rwT', + '7' => 'rwt' +}.freeze + +class Ls + def self.run(arguments = ARGV) + options = parse_options(arguments) + paths = parse_paths(options) + entries = parse_entries(paths) + ls = select_formatter(entries, options) + ls.print + end + + def self.parse_options(arguments) + opts = OptionParser.new + Options.new(opts, arguments) + end + + def self.parse_paths(options) + Paths.new(options).parse + end + + def self.parse_entries(paths) + paths.map { |path| Entry.new(path, File::Stat.new(path)) } + end + + def self.select_formatter(entries, options) + options.long_format? ? LsLong.new(entries) : LsShort.new(entries) + end +end + +Ls.run + +# frozen_string_literal: true + +require_relative './lib/options' +require_relative './lib/entry' +require_relative './lib/paths' +require_relative './lib/formatter/ls_formatter' +require_relative './lib/formatter/ls_short' +require_relative './lib/formatter/ls_long' + +COLUMN = 3 + +FILETYPE = { + '1' => 'p', + '2' => 'c', + '4' => 'd', + '6' => 'b', + '10' => '-', + '12' => 'l', + '14' => 's' +}.freeze + +REGULAR_MODE = { + '0' => '---', + '1' => '--x', + '2' => '-w-', + '3' => '-wx', + '4' => 'r--', + '5' => 'r-x', + '6' => 'rw-', + '7' => 'rwx' +}.freeze + +SUID_SGID = { + '0' => '---', + '1' => '--s', + '2' => '-wS', + '3' => '-ws', + '4' => 'r-S', + '5' => 'r-s', + '6' => 'rwS', + '7' => 'rws' +}.freeze + +STICKY_BIT = { + '0' => '---', + '1' => '--t', + '2' => '-wT', + '3' => '-wt', + '4' => 'r-T', + '5' => 'r-t', + '6' => 'rwT', + '7' => 'rwt' +}.freeze + +class Ls + def self.run(arguments = ARGV) + options = parse_options(arguments) + paths = parse_paths(options) + entries = parse_entries(paths) + ls = select_formatter(entries, options) + ls.print + end + + def self.parse_options(arguments) + opts = OptionParser.new + Options.new(opts, arguments) + end + + def self.parse_paths(options) + Paths.new(options).parse + end + + def self.parse_entries(paths) + paths.map { |path| Entry.new(path, File::Stat.new(path)) } + end + + def self.select_formatter(entries, options) + options.long_format? ? LsLong.new(entries) : LsShort.new(entries) + end +end + +Ls.run + +# frozen_string_literal: true + +require_relative './lib/options' +require_relative './lib/entry' +require_relative './lib/paths' +require_relative './lib/formatter/ls_formatter' +require_relative './lib/formatter/ls_short' +require_relative './lib/formatter/ls_long' + +COLUMN = 3 + +FILETYPE = { + '1' => 'p', + '2' => 'c', + '4' => 'd', + '6' => 'b', + '10' => '-', + '12' => 'l', + '14' => 's' +}.freeze + +REGULAR_MODE = { + '0' => '---', + '1' => '--x', + '2' => '-w-', + '3' => '-wx', + '4' => 'r--', + '5' => 'r-x', + '6' => 'rw-', + '7' => 'rwx' +}.freeze + +SUID_SGID = { + '0' => '---', + '1' => '--s', + '2' => '-wS', + '3' => '-ws', + '4' => 'r-S', + '5' => 'r-s', + '6' => 'rwS', + '7' => 'rws' +}.freeze + +STICKY_BIT = { + '0' => '---', + '1' => '--t', + '2' => '-wT', + '3' => '-wt', + '4' => 'r-T', + '5' => 'r-t', + '6' => 'rwT', + '7' => 'rwt' +}.freeze + +class Ls + def self.run(arguments = ARGV) + options = parse_options(arguments) + paths = parse_paths(options) + entries = parse_entries(paths) + ls = select_formatter(entries, options) + ls.print + end + + def self.parse_options(arguments) + opts = OptionParser.new + Options.new(opts, arguments) + end + + def self.parse_paths(options) + Paths.new(options).parse + end + + def self.parse_entries(paths) + paths.map { |path| Entry.new(path, File::Stat.new(path)) } + end + + def self.select_formatter(entries, options) + options.long_format? ? LsLong.new(entries) : LsShort.new(entries) + end +end + +Ls.run diff --git a/07.ls_object/test/test_files_and_directories/app_2.js b/07.ls_object/test/test_files_and_directories/app_2.js new file mode 100644 index 0000000000..963b35dc62 --- /dev/null +++ b/07.ls_object/test/test_files_and_directories/app_2.js @@ -0,0 +1,85 @@ + +#!/usr/bin/env ruby + +# frozen_string_literal: true + +require_relative './lib/options' +require_relative './lib/entry' +require_relative './lib/paths' +require_relative './lib/formatter/ls_formatter' +require_relative './lib/formatter/ls_short' +require_relative './lib/formatter/ls_long' + +COLUMN = 3 + +FILETYPE = { + '1' => 'p', + '2' => 'c', + '4' => 'd', + '6' => 'b', + '10' => '-', + '12' => 'l', + '14' => 's' +}.freeze + +REGULAR_MODE = { + '0' => '---', + '1' => '--x', + '2' => '-w-', + '3' => '-wx', + '4' => 'r--', + '5' => 'r-x', + '6' => 'rw-', + '7' => 'rwx' +}.freeze + +SUID_SGID = { + '0' => '---', + '1' => '--s', + '2' => '-wS', + '3' => '-ws', + '4' => 'r-S', + '5' => 'r-s', + '6' => 'rwS', + '7' => 'rws' +}.freeze + +STICKY_BIT = { + '0' => '---', + '1' => '--t', + '2' => '-wT', + '3' => '-wt', + '4' => 'r-T', + '5' => 'r-t', + '6' => 'rwT', + '7' => 'rwt' +}.freeze + +class Ls + def self.run(arguments = ARGV) + options = parse_options(arguments) + paths = parse_paths(options) + entries = parse_entries(paths) + ls = select_formatter(entries, options) + ls.print + end + + def self.parse_options(arguments) + opts = OptionParser.new + Options.new(opts, arguments) + end + + def self.parse_paths(options) + Paths.new(options).parse + end + + def self.parse_entries(paths) + paths.map { |path| Entry.new(path, File::Stat.new(path)) } + end + + def self.select_formatter(entries, options) + options.long_format? ? LsLong.new(entries) : LsShort.new(entries) + end +end + +Ls.run diff --git a/07.ls_object/test/test_files_and_directories/file_1.txt b/07.ls_object/test/test_files_and_directories/file_1.txt new file mode 100644 index 0000000000..3bbd3dc85e --- /dev/null +++ b/07.ls_object/test/test_files_and_directories/file_1.txt @@ -0,0 +1,27 @@ + +#!/usr/bin/env ruby + +# frozen_string_literal: true + +require_relative './lib/options' +require_relative './lib/entry' +require_relative './lib/paths' +require_relative './lib/formatter/ls_formatter' +require_relative './lib/formatter/ls_short' +require_relative './lib/formatter/ls_long' + + + def self.parse_paths(options) + Paths.new(options).parse + end + + def self.parse_entries(paths) + paths.map { |path| Entry.new(path, File::Stat.new(path)) } + end + + def self.select_formatter(entries, options) + options.long_format? ? LsLong.new(entries) : LsShort.new(entries) + end +end + +Ls.run diff --git a/07.ls_object/test/test_files_and_directories/file_2.txt b/07.ls_object/test/test_files_and_directories/file_2.txt new file mode 100644 index 0000000000..ad86a2a7ba --- /dev/null +++ b/07.ls_object/test/test_files_and_directories/file_2.txt @@ -0,0 +1,72 @@ + +COLUMN = 3 + +FILETYPE = { + '1' => 'p', + '2' => 'c', + '4' => 'd', + '6' => 'b', + '10' => '-', + '12' => 'l', + '14' => 's' +}.freeze + +REGULAR_MODE = { +COLUMN = 3 + +FILETYPE = { + '1' => 'p', + '2' => 'c', + '4' => 'd', + '6' => 'b', + '10' => '-', + '12' => 'l', + '14' => 's' +}.freeze + +REGULAR_MODE = { + '0' => '---', + '1' => '--x', + '2' => '-w-', + '3' => '-wx', + '4' => 'r--', + '5' => 'r-x', + '6' => 'rw-', + '7' => 'rwx' +}.freeze + +SUID_SGID = { + '0' => '---', + '1' => '--s', + '2' => '-wS', + '3' => '-ws', + '4' => 'r-S', + '5' => 'r-s', + '6' => 'rwS', + '7' => 'rws' +}.freeze + +STICKY_BIT = { + '0' => '---', + '1' => '--t', + '2' => '-wT', + '3' => '-wt', + '4' => 'r-T', + '5' => 'r-t', + '6' => 'rwT', + '7' => 'rwt' +}.freeze + +class Ls + def self.run(arguments = ARGV) + options = parse_options(arguments) + paths = parse_paths(options) + entries = parse_entries(paths) + ls = select_formatter(entries, options) + ls.print + end + + def self.parse_options(arguments) + opts = OptionParser.new + Options.new(opts, arguments) + end diff --git a/07.ls_object/test/test_files_and_directories/sgid_A b/07.ls_object/test/test_files_and_directories/sgid_A new file mode 100755 index 0000000000..e69de29bb2 diff --git a/07.ls_object/test/test_files_and_directories/sgid_B b/07.ls_object/test/test_files_and_directories/sgid_B new file mode 100755 index 0000000000..e69de29bb2 diff --git a/07.ls_object/test/test_files_and_directories/suid_A b/07.ls_object/test/test_files_and_directories/suid_A new file mode 100644 index 0000000000..e69de29bb2 diff --git a/07.ls_object/test/test_files_and_directories/suid_B b/07.ls_object/test/test_files_and_directories/suid_B new file mode 100644 index 0000000000..e69de29bb2 diff --git a/07.ls_object/test/test_ls.rb b/07.ls_object/test/test_ls.rb new file mode 100644 index 0000000000..d163d172d7 --- /dev/null +++ b/07.ls_object/test/test_ls.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'minitest/autorun' +require_relative '../ls' + +class TestLs < Minitest::Test + FIXTURE_PATH = Pathname('test/fixtures/ls') + def test_run + expected = <<~TEXT + app_1.rb app_2.js dir_1 + Dir_2 dir_3 file_1.txt + file_2.txt sgid_A sgid_B + sticky_bit_A sticky_bit_B suid_A + suid_B + TEXT + + assert_equal expected, Ls.run(FIXTURE_PATH) + end +end From 33423f08fa3e2fd74c75f3b0c4a56f79eaa57d5c Mon Sep 17 00:00:00 2001 From: Miya096jp Date: Thu, 19 Dec 2024 20:44:24 +0900 Subject: [PATCH 09/24] =?UTF-8?q?Ls=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AErun?= =?UTF-8?q?=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89=E3=81=AB=E5=AF=BE=E3=81=97?= =?UTF-8?q?=E3=81=A6=E3=83=A6=E3=83=8B=E3=83=83=E3=83=88=E3=83=86=E3=82=B9?= =?UTF-8?q?=E3=83=88=E3=82=92=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/lib/formatter/ls_long.rb | 2 +- 07.ls_object/lib/formatter/ls_short.rb | 2 +- 07.ls_object/lib/options.rb | 3 +- 07.ls_object/lib/paths.rb | 10 +- 07.ls_object/ls.rb | 31 +++--- .../test_ls/.secret_file_1} | 0 .../test_ls/.secret_file_2} | 0 .../test_ls}/app_1.rb | 0 .../test_ls}/app_2.js | 0 .../test_ls}/file_1.txt | 0 .../test_ls}/file_2.txt | 0 .../suid_A => fixtures/test_ls/sgid_A} | 0 .../suid_B => fixtures/test_ls/sgid_B} | 0 07.ls_object/test/fixtures/test_ls/suid_A | 0 07.ls_object/test/fixtures/test_ls/suid_B | 0 07.ls_object/test/test_ls.rb | 101 ++++++++++++++++-- 16 files changed, 118 insertions(+), 31 deletions(-) rename 07.ls_object/test/{test_files_and_directories/sgid_A => fixtures/test_ls/.secret_file_1} (100%) mode change 100755 => 100644 rename 07.ls_object/test/{test_files_and_directories/sgid_B => fixtures/test_ls/.secret_file_2} (100%) mode change 100755 => 100644 rename 07.ls_object/test/{test_files_and_directories => fixtures/test_ls}/app_1.rb (100%) rename 07.ls_object/test/{test_files_and_directories => fixtures/test_ls}/app_2.js (100%) rename 07.ls_object/test/{test_files_and_directories => fixtures/test_ls}/file_1.txt (100%) rename 07.ls_object/test/{test_files_and_directories => fixtures/test_ls}/file_2.txt (100%) rename 07.ls_object/test/{test_files_and_directories/suid_A => fixtures/test_ls/sgid_A} (100%) mode change 100644 => 100755 rename 07.ls_object/test/{test_files_and_directories/suid_B => fixtures/test_ls/sgid_B} (100%) mode change 100644 => 100755 create mode 100644 07.ls_object/test/fixtures/test_ls/suid_A create mode 100644 07.ls_object/test/fixtures/test_ls/suid_B diff --git a/07.ls_object/lib/formatter/ls_long.rb b/07.ls_object/lib/formatter/ls_long.rb index 2f314decc5..cc3ebf3908 100644 --- a/07.ls_object/lib/formatter/ls_long.rb +++ b/07.ls_object/lib/formatter/ls_long.rb @@ -3,7 +3,7 @@ class LsLong < LsFormatter def parse max_size = build_max_size - "#{build_total_row}\n#{build_body(max_size)}" + "#{build_total_row}\n#{build_body(max_size)}\n" end private diff --git a/07.ls_object/lib/formatter/ls_short.rb b/07.ls_object/lib/formatter/ls_short.rb index 08891de568..8dc106c2eb 100644 --- a/07.ls_object/lib/formatter/ls_short.rb +++ b/07.ls_object/lib/formatter/ls_short.rb @@ -5,7 +5,7 @@ def parse entries = justfy_entries row = count_row sliced_entries = slice_entries(entries, row) - transpose(sliced_entries).map(&:join) + "#{transpose(sliced_entries).map { |entry| entry.join.rstrip }.join("\n")}\n" end private diff --git a/07.ls_object/lib/options.rb b/07.ls_object/lib/options.rb index 922cdec995..eba60abcaa 100644 --- a/07.ls_object/lib/options.rb +++ b/07.ls_object/lib/options.rb @@ -3,7 +3,8 @@ require 'optparse' class Options - def initialize(opts, arguments) + def initialize(arguments) + opts = OptionParser.new opts.on('-l') { |v| @long_format = v } opts.on('-r') { |v| @reverse = v } opts.on('-a') { |v| @dot_match = v } diff --git a/07.ls_object/lib/paths.rb b/07.ls_object/lib/paths.rb index 38fd1dbe85..f955924e08 100644 --- a/07.ls_object/lib/paths.rb +++ b/07.ls_object/lib/paths.rb @@ -3,17 +3,13 @@ require 'pathname' class Paths - def initialize(options) + def initialize(pathname, options) + @pathname = pathname @options = options end - # def parse - # paths = @options.dot_match? ? Dir.glob('*', File::FNM_DOTMATCH).sort : Dir.glob('*') - # reverse(paths) - # end - def parse - paths = @options.dot_match? ? Dir.glob(Pathname('./*'), File::FNM_DOTMATCH).sort : Dir.glob(Pathname('./*')) + paths = @options.dot_match? ? Dir.glob(@pathname, File::FNM_DOTMATCH).sort : Dir.glob(@pathname) reverse(paths) end diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb index 3d4e9dcb6f..9daa33aa0f 100755 --- a/07.ls_object/ls.rb +++ b/07.ls_object/ls.rb @@ -8,6 +8,7 @@ require_relative './lib/formatter/ls_formatter' require_relative './lib/formatter/ls_short' require_relative './lib/formatter/ls_long' +require 'pathname' COLUMN = 3 @@ -55,30 +56,34 @@ }.freeze class Ls - def self.run(arguments = ARGV) - options = parse_options(arguments) - paths = parse_paths(options) + def initialize(pathname, options) + @pathname = pathname + @options = options + end + + def run + paths = parse_paths(@pathname, @options) entries = parse_entries(paths) - ls = select_formatter(entries, options) + ls = select_formatter(entries, @options) ls.parse end - def self.parse_options(arguments) - opts = OptionParser.new - Options.new(opts, arguments) - end + private - def self.parse_paths(options) - Paths.new(options).parse + def parse_paths(pathname, options) + Paths.new(pathname, options).parse end - def self.parse_entries(paths) + def parse_entries(paths) paths.map { |path| Entry.new(path, File::Stat.new(path)) } end - def self.select_formatter(entries, options) + def select_formatter(entries, options) options.long_format? ? LsLong.new(entries) : LsShort.new(entries) end end -puts Ls.run +pathname = Pathname('./*') +options = Options.new(ARGV) +ls = Ls.new(pathname, options) +puts ls.run diff --git a/07.ls_object/test/test_files_and_directories/sgid_A b/07.ls_object/test/fixtures/test_ls/.secret_file_1 old mode 100755 new mode 100644 similarity index 100% rename from 07.ls_object/test/test_files_and_directories/sgid_A rename to 07.ls_object/test/fixtures/test_ls/.secret_file_1 diff --git a/07.ls_object/test/test_files_and_directories/sgid_B b/07.ls_object/test/fixtures/test_ls/.secret_file_2 old mode 100755 new mode 100644 similarity index 100% rename from 07.ls_object/test/test_files_and_directories/sgid_B rename to 07.ls_object/test/fixtures/test_ls/.secret_file_2 diff --git a/07.ls_object/test/test_files_and_directories/app_1.rb b/07.ls_object/test/fixtures/test_ls/app_1.rb similarity index 100% rename from 07.ls_object/test/test_files_and_directories/app_1.rb rename to 07.ls_object/test/fixtures/test_ls/app_1.rb diff --git a/07.ls_object/test/test_files_and_directories/app_2.js b/07.ls_object/test/fixtures/test_ls/app_2.js similarity index 100% rename from 07.ls_object/test/test_files_and_directories/app_2.js rename to 07.ls_object/test/fixtures/test_ls/app_2.js diff --git a/07.ls_object/test/test_files_and_directories/file_1.txt b/07.ls_object/test/fixtures/test_ls/file_1.txt similarity index 100% rename from 07.ls_object/test/test_files_and_directories/file_1.txt rename to 07.ls_object/test/fixtures/test_ls/file_1.txt diff --git a/07.ls_object/test/test_files_and_directories/file_2.txt b/07.ls_object/test/fixtures/test_ls/file_2.txt similarity index 100% rename from 07.ls_object/test/test_files_and_directories/file_2.txt rename to 07.ls_object/test/fixtures/test_ls/file_2.txt diff --git a/07.ls_object/test/test_files_and_directories/suid_A b/07.ls_object/test/fixtures/test_ls/sgid_A old mode 100644 new mode 100755 similarity index 100% rename from 07.ls_object/test/test_files_and_directories/suid_A rename to 07.ls_object/test/fixtures/test_ls/sgid_A diff --git a/07.ls_object/test/test_files_and_directories/suid_B b/07.ls_object/test/fixtures/test_ls/sgid_B old mode 100644 new mode 100755 similarity index 100% rename from 07.ls_object/test/test_files_and_directories/suid_B rename to 07.ls_object/test/fixtures/test_ls/sgid_B diff --git a/07.ls_object/test/fixtures/test_ls/suid_A b/07.ls_object/test/fixtures/test_ls/suid_A new file mode 100644 index 0000000000..e69de29bb2 diff --git a/07.ls_object/test/fixtures/test_ls/suid_B b/07.ls_object/test/fixtures/test_ls/suid_B new file mode 100644 index 0000000000..e69de29bb2 diff --git a/07.ls_object/test/test_ls.rb b/07.ls_object/test/test_ls.rb index d163d172d7..76141bf4cb 100644 --- a/07.ls_object/test/test_ls.rb +++ b/07.ls_object/test/test_ls.rb @@ -1,19 +1,104 @@ # frozen_string_literal: true require 'minitest/autorun' +require 'pathname' require_relative '../ls' +require_relative '../lib/options' class TestLs < Minitest::Test - FIXTURE_PATH = Pathname('test/fixtures/ls') - def test_run + def setup + @fixture_path = Pathname('test/fixtures/test_ls') + end + + def test_ls_run + expected = <<~TEXT + app_1.rb file_1.txt sticky_bit_B + app_2.js file_2.txt suid_A + dir_1 sgid_A suid_B + dir_2 sgid_B + dir_3 sticky_bit_A + TEXT + + @options = Options.new([]) + @ls = Ls.new(@fixture_path.join('*'), @options) + assert_equal expected, @ls.run + end + + def test_run_with_reverse + expected = <<~TEXT + suid_B sgid_A dir_1 + suid_A file_2.txt app_2.js + sticky_bit_B file_1.txt app_1.rb + sticky_bit_A dir_3 + sgid_B dir_2 + TEXT + + @options = Options.new(['-r']) + @ls = Ls.new(@fixture_path.join('*'), @options) + assert_equal expected, @ls.run + end + + def test_run_with_dot_match + expected = <<~TEXT + . dir_2 sticky_bit_A + .secret_file_1 dir_3 sticky_bit_B + .secret_file_2 file_1.txt suid_A + app_1.rb file_2.txt suid_B + app_2.js sgid_A + dir_1 sgid_B + TEXT + + @options = Options.new(['-a']) + @ls = Ls.new(@fixture_path.join('*'), @options) + assert_equal expected, @ls.run + end + + def test_run_with_long_option + expected = <<~TEXT + total: 40 + prw-r--r-- 1 miya staff 4489 12 19 14:10 app_1.rb + prw-r--r-- 1 miya staff 1497 12 19 14:11 app_2.js + drwxr-xr-x 2 miya staff 64 12 19 14: 9 dir_1 + drwxr-xr-x 2 miya staff 64 12 19 14: 9 dir_2 + drwxr-xr-x 2 miya staff 64 12 19 14: 9 dir_3 + prw-r--r-- 1 miya staff 589 12 19 14:11 file_1.txt + prw-r--r-- 1 miya staff 1061 12 19 14:11 file_2.txt + prwsrwsrws 1 miya staff 0 12 19 14: 4 sgid_A + prwsrwSrws 1 miya staff 0 12 19 14: 4 sgid_B + drwtrwtrwt 2 miya staff 64 12 19 14: 5 sticky_bit_A + drwtrwtrwT 2 miya staff 64 12 19 14: 5 sticky_bit_B + prwSrwsrws 1 miya staff 0 12 19 14: 5 suid_A + prw-r--r-- 1 miya staff 0 12 19 14: 5 suid_B + TEXT + + @options = Options.new(['-l']) + @ls = Ls.new(@fixture_path.join('*'), @options) + assert_equal expected, @ls.run + end + + def test_run_with_all_options expected = <<~TEXT - app_1.rb app_2.js dir_1 - Dir_2 dir_3 file_1.txt - file_2.txt sgid_A sgid_B - sticky_bit_A sticky_bit_B suid_A - suid_B + total: 40 + prw-r--r-- 1 miya staff 0 12 19 14: 5 suid_B + prwSrwsrws 1 miya staff 0 12 19 14: 5 suid_A + drwtrwtrwT 2 miya staff 64 12 19 14: 5 sticky_bit_B + drwtrwtrwt 2 miya staff 64 12 19 14: 5 sticky_bit_A + prwsrwSrws 1 miya staff 0 12 19 14: 4 sgid_B + prwsrwsrws 1 miya staff 0 12 19 14: 4 sgid_A + prw-r--r-- 1 miya staff 1061 12 19 14:11 file_2.txt + prw-r--r-- 1 miya staff 589 12 19 14:11 file_1.txt + drwxr-xr-x 2 miya staff 64 12 19 14: 9 dir_3 + drwxr-xr-x 2 miya staff 64 12 19 14: 9 dir_2 + drwxr-xr-x 2 miya staff 64 12 19 14: 9 dir_1 + prw-r--r-- 1 miya staff 1497 12 19 14:11 app_2.js + prw-r--r-- 1 miya staff 4489 12 19 14:10 app_1.rb + prw-r--r-- 1 miya staff 0 12 19 18:30 .secret_file_2 + prw-r--r-- 1 miya staff 0 12 19 18:29 .secret_file_1 + drwxr-xr-x 17 miya staff 544 12 19 18:30 . TEXT - assert_equal expected, Ls.run(FIXTURE_PATH) + @options = Options.new(['-arl']) + @ls = Ls.new(@fixture_path.join('*'), @options) + assert_equal expected, @ls.run end end From 9c3fe89ca941757194c90bdc776830a69b6038a8 Mon Sep 17 00:00:00 2001 From: Miya096jp Date: Thu, 19 Dec 2024 21:31:21 +0900 Subject: [PATCH 10/24] =?UTF-8?q?LsLong=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=81=AEformat=5Ftype=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3/test=5Fls.rb=E3=81=AE=E5=90=84?= =?UTF-8?q?=E3=83=A6=E3=83=8B=E3=83=83=E3=83=88=E3=83=86=E3=82=B9=E3=83=88?= =?UTF-8?q?=E3=81=AEHEAR=E3=83=89=E3=82=AD=E3=83=A5=E3=83=A1=E3=83=B3?= =?UTF-8?q?=E3=83=88=E3=81=AE=E3=83=87=E3=83=BC=E3=82=BF=E3=82=92=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=E3=81=97=E3=83=86=E3=82=B9=E3=83=88=E5=AE=9F=E8=A1=8C?= =?UTF-8?q?(=E6=88=90=E5=8A=9F)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/lib/formatter/ls_long.rb | 2 +- 07.ls_object/test/fixtures/test_ls/app_1.rb | 253 ------------------ 07.ls_object/test/fixtures/test_ls/app_2.js | 85 ------ 07.ls_object/test/fixtures/test_ls/file_1.txt | 32 +-- 07.ls_object/test/fixtures/test_ls/file_2.txt | 75 +----- 07.ls_object/test/fixtures/test_ls/file_3.txt | 1 + 07.ls_object/test/fixtures/test_ls/file_4.txt | 5 + 07.ls_object/test/test_ls.rb | 70 ++--- 8 files changed, 50 insertions(+), 473 deletions(-) delete mode 100644 07.ls_object/test/fixtures/test_ls/app_1.rb delete mode 100644 07.ls_object/test/fixtures/test_ls/app_2.js create mode 100644 07.ls_object/test/fixtures/test_ls/file_3.txt create mode 100644 07.ls_object/test/fixtures/test_ls/file_4.txt diff --git a/07.ls_object/lib/formatter/ls_long.rb b/07.ls_object/lib/formatter/ls_long.rb index cc3ebf3908..73f8028023 100644 --- a/07.ls_object/lib/formatter/ls_long.rb +++ b/07.ls_object/lib/formatter/ls_long.rb @@ -38,7 +38,7 @@ def build_body(max_size) def format_type(entry) digits = entry.type - digits.gsub(/./, FILETYPE) + FILETYPE[digits] end def format_mode(entry) diff --git a/07.ls_object/test/fixtures/test_ls/app_1.rb b/07.ls_object/test/fixtures/test_ls/app_1.rb deleted file mode 100644 index 3e1bb71b93..0000000000 --- a/07.ls_object/test/fixtures/test_ls/app_1.rb +++ /dev/null @@ -1,253 +0,0 @@ - -#!/usr/bin/env ruby -#!/usr/bin/env ruby -#!/usr/bin/env ruby - -# frozen_string_literal: true - -require_relative './lib/options' -require_relative './lib/entry' -require_relative './lib/paths' -require_relative './lib/formatter/ls_formatter' -require_relative './lib/formatter/ls_short' -require_relative './lib/formatter/ls_long' - -COLUMN = 3 - -FILETYPE = { - '1' => 'p', - '2' => 'c', - '4' => 'd', - '6' => 'b', - '10' => '-', - '12' => 'l', - '14' => 's' -}.freeze - -REGULAR_MODE = { - '0' => '---', - '1' => '--x', - '2' => '-w-', - '3' => '-wx', - '4' => 'r--', - '5' => 'r-x', - '6' => 'rw-', - '7' => 'rwx' -}.freeze - -SUID_SGID = { - '0' => '---', - '1' => '--s', - '2' => '-wS', - '3' => '-ws', - '4' => 'r-S', - '5' => 'r-s', - '6' => 'rwS', - '7' => 'rws' -}.freeze - -STICKY_BIT = { - '0' => '---', - '1' => '--t', - '2' => '-wT', - '3' => '-wt', - '4' => 'r-T', - '5' => 'r-t', - '6' => 'rwT', - '7' => 'rwt' -}.freeze - -class Ls - def self.run(arguments = ARGV) - options = parse_options(arguments) - paths = parse_paths(options) - entries = parse_entries(paths) - ls = select_formatter(entries, options) - ls.print - end - - def self.parse_options(arguments) - opts = OptionParser.new - Options.new(opts, arguments) - end - - def self.parse_paths(options) - Paths.new(options).parse - end - - def self.parse_entries(paths) - paths.map { |path| Entry.new(path, File::Stat.new(path)) } - end - - def self.select_formatter(entries, options) - options.long_format? ? LsLong.new(entries) : LsShort.new(entries) - end -end - -Ls.run - -# frozen_string_literal: true - -require_relative './lib/options' -require_relative './lib/entry' -require_relative './lib/paths' -require_relative './lib/formatter/ls_formatter' -require_relative './lib/formatter/ls_short' -require_relative './lib/formatter/ls_long' - -COLUMN = 3 - -FILETYPE = { - '1' => 'p', - '2' => 'c', - '4' => 'd', - '6' => 'b', - '10' => '-', - '12' => 'l', - '14' => 's' -}.freeze - -REGULAR_MODE = { - '0' => '---', - '1' => '--x', - '2' => '-w-', - '3' => '-wx', - '4' => 'r--', - '5' => 'r-x', - '6' => 'rw-', - '7' => 'rwx' -}.freeze - -SUID_SGID = { - '0' => '---', - '1' => '--s', - '2' => '-wS', - '3' => '-ws', - '4' => 'r-S', - '5' => 'r-s', - '6' => 'rwS', - '7' => 'rws' -}.freeze - -STICKY_BIT = { - '0' => '---', - '1' => '--t', - '2' => '-wT', - '3' => '-wt', - '4' => 'r-T', - '5' => 'r-t', - '6' => 'rwT', - '7' => 'rwt' -}.freeze - -class Ls - def self.run(arguments = ARGV) - options = parse_options(arguments) - paths = parse_paths(options) - entries = parse_entries(paths) - ls = select_formatter(entries, options) - ls.print - end - - def self.parse_options(arguments) - opts = OptionParser.new - Options.new(opts, arguments) - end - - def self.parse_paths(options) - Paths.new(options).parse - end - - def self.parse_entries(paths) - paths.map { |path| Entry.new(path, File::Stat.new(path)) } - end - - def self.select_formatter(entries, options) - options.long_format? ? LsLong.new(entries) : LsShort.new(entries) - end -end - -Ls.run - -# frozen_string_literal: true - -require_relative './lib/options' -require_relative './lib/entry' -require_relative './lib/paths' -require_relative './lib/formatter/ls_formatter' -require_relative './lib/formatter/ls_short' -require_relative './lib/formatter/ls_long' - -COLUMN = 3 - -FILETYPE = { - '1' => 'p', - '2' => 'c', - '4' => 'd', - '6' => 'b', - '10' => '-', - '12' => 'l', - '14' => 's' -}.freeze - -REGULAR_MODE = { - '0' => '---', - '1' => '--x', - '2' => '-w-', - '3' => '-wx', - '4' => 'r--', - '5' => 'r-x', - '6' => 'rw-', - '7' => 'rwx' -}.freeze - -SUID_SGID = { - '0' => '---', - '1' => '--s', - '2' => '-wS', - '3' => '-ws', - '4' => 'r-S', - '5' => 'r-s', - '6' => 'rwS', - '7' => 'rws' -}.freeze - -STICKY_BIT = { - '0' => '---', - '1' => '--t', - '2' => '-wT', - '3' => '-wt', - '4' => 'r-T', - '5' => 'r-t', - '6' => 'rwT', - '7' => 'rwt' -}.freeze - -class Ls - def self.run(arguments = ARGV) - options = parse_options(arguments) - paths = parse_paths(options) - entries = parse_entries(paths) - ls = select_formatter(entries, options) - ls.print - end - - def self.parse_options(arguments) - opts = OptionParser.new - Options.new(opts, arguments) - end - - def self.parse_paths(options) - Paths.new(options).parse - end - - def self.parse_entries(paths) - paths.map { |path| Entry.new(path, File::Stat.new(path)) } - end - - def self.select_formatter(entries, options) - options.long_format? ? LsLong.new(entries) : LsShort.new(entries) - end -end - -Ls.run diff --git a/07.ls_object/test/fixtures/test_ls/app_2.js b/07.ls_object/test/fixtures/test_ls/app_2.js deleted file mode 100644 index 963b35dc62..0000000000 --- a/07.ls_object/test/fixtures/test_ls/app_2.js +++ /dev/null @@ -1,85 +0,0 @@ - -#!/usr/bin/env ruby - -# frozen_string_literal: true - -require_relative './lib/options' -require_relative './lib/entry' -require_relative './lib/paths' -require_relative './lib/formatter/ls_formatter' -require_relative './lib/formatter/ls_short' -require_relative './lib/formatter/ls_long' - -COLUMN = 3 - -FILETYPE = { - '1' => 'p', - '2' => 'c', - '4' => 'd', - '6' => 'b', - '10' => '-', - '12' => 'l', - '14' => 's' -}.freeze - -REGULAR_MODE = { - '0' => '---', - '1' => '--x', - '2' => '-w-', - '3' => '-wx', - '4' => 'r--', - '5' => 'r-x', - '6' => 'rw-', - '7' => 'rwx' -}.freeze - -SUID_SGID = { - '0' => '---', - '1' => '--s', - '2' => '-wS', - '3' => '-ws', - '4' => 'r-S', - '5' => 'r-s', - '6' => 'rwS', - '7' => 'rws' -}.freeze - -STICKY_BIT = { - '0' => '---', - '1' => '--t', - '2' => '-wT', - '3' => '-wt', - '4' => 'r-T', - '5' => 'r-t', - '6' => 'rwT', - '7' => 'rwt' -}.freeze - -class Ls - def self.run(arguments = ARGV) - options = parse_options(arguments) - paths = parse_paths(options) - entries = parse_entries(paths) - ls = select_formatter(entries, options) - ls.print - end - - def self.parse_options(arguments) - opts = OptionParser.new - Options.new(opts, arguments) - end - - def self.parse_paths(options) - Paths.new(options).parse - end - - def self.parse_entries(paths) - paths.map { |path| Entry.new(path, File::Stat.new(path)) } - end - - def self.select_formatter(entries, options) - options.long_format? ? LsLong.new(entries) : LsShort.new(entries) - end -end - -Ls.run diff --git a/07.ls_object/test/fixtures/test_ls/file_1.txt b/07.ls_object/test/fixtures/test_ls/file_1.txt index 3bbd3dc85e..6f9be27fe8 100644 --- a/07.ls_object/test/fixtures/test_ls/file_1.txt +++ b/07.ls_object/test/fixtures/test_ls/file_1.txt @@ -1,27 +1,5 @@ - -#!/usr/bin/env ruby - -# frozen_string_literal: true - -require_relative './lib/options' -require_relative './lib/entry' -require_relative './lib/paths' -require_relative './lib/formatter/ls_formatter' -require_relative './lib/formatter/ls_short' -require_relative './lib/formatter/ls_long' - - - def self.parse_paths(options) - Paths.new(options).parse - end - - def self.parse_entries(paths) - paths.map { |path| Entry.new(path, File::Stat.new(path)) } - end - - def self.select_formatter(entries, options) - options.long_format? ? LsLong.new(entries) : LsShort.new(entries) - end -end - -Ls.run +るに馬の頭部の近辺に或ある異常な光の現象が起こるというふうに解釈される。 + 次に注意すべきは、この怪異の起こる時の時間的分布である。すなわち「濃州のうしゅうでは四月から七月までで、別して五六月が多いという。七月になりかかると、秋風が立ち初める、とギバの難は影を隠してしまう。武州ぶしゅう常州じょうしゅうあたりでもやはり四月から七月と言っている」。また晴天には現われず「晴れては曇り曇っては晴れる、村雲などが出たりはいったりする日に限って」現われるとある。また一日じゅうの時刻については「朝五つ時前(午前八時)、夕七つ時過ぎ(午後四時)にはかけられない、多くは日盛りであるという」とある。 + またこの出現するのにおのずから場所が定まっている傾向があり、たとえば一里塚いちりづかのような所の例があげられている。 + もう一つ参考になるのは、馬をギバの難から救う方法として、これが襲いかかった時に、半纏はんてんでも風呂敷ふろしきでも莚むしろでも、そういうものを馬の首からかぶせるといいということがある。もちろん、その上に、尾の上の背骨に針を打ち込んだりするそうであるが、このようにものをかぶせる事が「針よりも大切なまじない」だと考えられている。またこれと共通な点のあるのは、平生のギバよけのまじないとして、馬に腹当てをさせるとよい、ただしそれは「大津東町上下仕合」と白く染めぬいたものを用いる。「このアブヨケをした馬がギバにかけられてたおれたのを見た事がないと、言われている」。 + 別の説として美濃みのでは「ギバは白虻しろあぶのような、目にも見えない虫だという説がある、また常陸ひたちではその虫を大津虫と呼んでいる。虫は玉虫色をしていて diff --git a/07.ls_object/test/fixtures/test_ls/file_2.txt b/07.ls_object/test/fixtures/test_ls/file_2.txt index ad86a2a7ba..08836b5e55 100644 --- a/07.ls_object/test/fixtures/test_ls/file_2.txt +++ b/07.ls_object/test/fixtures/test_ls/file_2.txt @@ -1,72 +1,3 @@ - -COLUMN = 3 - -FILETYPE = { - '1' => 'p', - '2' => 'c', - '4' => 'd', - '6' => 'b', - '10' => '-', - '12' => 'l', - '14' => 's' -}.freeze - -REGULAR_MODE = { -COLUMN = 3 - -FILETYPE = { - '1' => 'p', - '2' => 'c', - '4' => 'd', - '6' => 'b', - '10' => '-', - '12' => 'l', - '14' => 's' -}.freeze - -REGULAR_MODE = { - '0' => '---', - '1' => '--x', - '2' => '-w-', - '3' => '-wx', - '4' => 'r--', - '5' => 'r-x', - '6' => 'rw-', - '7' => 'rwx' -}.freeze - -SUID_SGID = { - '0' => '---', - '1' => '--s', - '2' => '-wS', - '3' => '-ws', - '4' => 'r-S', - '5' => 'r-s', - '6' => 'rwS', - '7' => 'rws' -}.freeze - -STICKY_BIT = { - '0' => '---', - '1' => '--t', - '2' => '-wT', - '3' => '-wt', - '4' => 'r-T', - '5' => 'r-t', - '6' => 'rwT', - '7' => 'rwt' -}.freeze - -class Ls - def self.run(arguments = ARGV) - options = parse_options(arguments) - paths = parse_paths(options) - entries = parse_entries(paths) - ls = select_formatter(entries, options) - ls.print - end - - def self.parse_options(arguments) - opts = OptionParser.new - Options.new(opts, arguments) - end + これに反して、ギバがなんらかの空中放電によるものと考えると、たてがみが立ち上がったり、光の線条が見えたり、玉虫色の光が馬の首を包んだりする事が、全部生きた科学的記述としての意味をもって来る。また衣服その他で頭をおおい、また腹部を保護するという事は、つまり電気の半導体で馬の身体の一部を被覆して、放電による電流が直接にその局部の肉体に流れるのを防ぐという意味に解釈されて来るのである。 + またこういう放電現象が夏期に多い事、および日中に多い事は周知の事実であるので、前述の時間分布は、これときわめてよく符合する事になる。 + 場所のおのずから定まる傾向については、自分は何事も具体的のことをいうだけの材料を持ち合わせないが、これも調べてみたら、おそらく放電現象の多い場所と符合するようなことがありはし diff --git a/07.ls_object/test/fixtures/test_ls/file_3.txt b/07.ls_object/test/fixtures/test_ls/file_3.txt new file mode 100644 index 0000000000..1fb7f7233d --- /dev/null +++ b/07.ls_object/test/fixtures/test_ls/file_3.txt @@ -0,0 +1 @@ + 物理学の学徒としての自分は、日常普通に身辺に起こる自然現象に不思議を感ずる事は多いが、古来のいわゆる「怪異」なるものの存在を信ずることはできない。しかし昔からわれわれの祖先が多くの「怪異」に遭遇しそれを「目撃」して来たという人事的現象としての「事実」を否定するものではない。われわれの役目はただそれらの怪異現象の記録を現代科学上の語彙ごいを借りて翻訳するだけの事でなければならない。この仕事はしかしはなはだ困難なものである。錯覚や誇張さらに転訛てんかのレンズによってはなはだしくゆがめられた影像からその本体を言い当てなければならない。それを的確に成効しうるためにはそのレンズに関する方則を正確に知らなければならない、のみならず、またその個々の場合における決定条件として多様の因子を逐一に明らかにしなければならない。この前者の方則については心理学のほうから若干の根拠は供給されるとしても、後者に関する資料はほとんどすべての場合において永久に失われている。従ってほんとうに科学的な推定を下すということはほとんど望み難いことである。ただできうる唯一の方法としては、有るだけの材料から、科学的に合理的な一つの「可能性」を指摘するに過ぎない。もっともこの可能性が非常に多様であれば、その中の二三を指摘してみても、それは結局なんらの価値もない漫談となってしまうであろうが、多くの場合に必ずしもそうとは限らない。ことにある一種の怪異に関する記録が豊富にあればあるほど、この可能性の範囲はかなりまで押しせばめられる。従ってやや「もっともらしい仮説」というまでには漕こぎつけられる見込みがあるのである。そこまで行けば、それはともかくも一つの仮説として存在する価値を認めなければならず、また実際科学者たちにある暗示を提供するだけの効果をもつ事も有りうるであろうと思われる。 diff --git a/07.ls_object/test/fixtures/test_ls/file_4.txt b/07.ls_object/test/fixtures/test_ls/file_4.txt new file mode 100644 index 0000000000..fbb7cd705b --- /dev/null +++ b/07.ls_object/test/fixtures/test_ls/file_4.txt @@ -0,0 +1,5 @@ + その怪異の第一は、自分の郷里高知こうち付近で知られている「孕はらみのジャン」と称するものである。孕は地名で、高知の海岸に並行する山脈が浦戸湾うらどわんに中断されたその両側の突端の地とその海峡とを込めた名前である。この現象については、最近に、土佐とさ郷土史きょうどしの権威として知られた杜山居士とざんこじ寺石正路てらいしまさみち氏が雑誌「土佐史壇」第十七号に「郷土史断片」その三〇として記載されたものがある。「(前略)昔はだいぶ評判の事であったが、このごろは全くその沙汰さたがない、根拠の無き話かと思えば、「土佐今昔物語」という書に、沼澄ぬまずみ(鹿持雅澄かもちまさずみ翁おう)の名をもって左のとおりしるされている。 +孕の海にジャンと唱うる稀有けうのものありけり、たれしの人もいまだその形を見たるものなく、その物は夜半にジャーンと鳴り響きて海上を過ぎ行くなりけり、漁業をして世を渡るどちに、夜半に小舟浮かべて、あるは釣つりをたれ、あるいは網を打ちて幸さち多かるも、このも[#「も」に「原」の注記]海上を行き過ぐればたちまちに魚騒ぎ走りて、時を移すともその夜はまた幸さちなかりけり、高知ほとりの方言に、ものの破談になりたる事をジャンになりたりというも、この海上行き過ぐるものよりいでたることなん語り伝えたりとや。 + この文は鹿持翁の筆なればおおよそ小百年前のことにして孕はらみのジャンはこのほどの昔よりもすでにその伝があったことが知れる(後略)。」寺石氏はこのジャンの意味の転用に関する上記の説の誤謬ごびゅうを指摘している。また終わりに諏訪湖すわこの神渡りの音響の事を引き、孕のジャンは「何か微妙な地の震動に関したことではあるまいか」と述べておられる。 + 私は幼時近所の老人からたびたびこれと同様な話を聞かされた。そしてもし記憶の誤りでなければ、このジャンの音響とともに「水面にさざ波が立つ」という事が上記の記載に付加されていた。 + この話を導き出しそうな音の原因に関する自分のはじめの考えは、もしや昆虫こんちゅうかあるいは鳥類の群れが飛び立つ音ではないかと思ってみたが、しかしそれは夜半の事だというし、また魚が釣つれなくなるという事が確実とすれば単に空中の音波のためとは考えにくいと思われた。ところが先年筑波山つくばさんの北側の柿岡かきおかの盆地へ行った時にかの地には珍しくない「地鳴り」の現象を数回体験した。その時に自分は全く神来的に「孕はらみのジャンはこれだ」と感じた。この地鳴りの音は考え方によってはやはりジャーンとも形容されうる種類の雑音であるし、またその地盤の性質、地表の形状や被覆物の種類によってはいっそうジャーンと聞こえやすくなるであろうと思われうるたちのものである。そして明らかに一方から一方へ「過ぎ行く」音で、それが空中ともなく地中ともなく過ぎ去って行くのは実際他に比較するもののない奇異の感じを起こさせるものである。ちょうど自分が観測室内にいた時に起こった地鳴りの際には、磁力計の頂上に付いている管が共鳴してその頭が少なくも数ミリほど振動するのを明らかに認める事ができたし、また山中で聞いた時は立っている靴くつの底に明らかにきわめて短週期の震動を感じた。これだけの振動があれば、適当な境界条件の下に水面のさざ波を起こしうるはずであるし、また水中の魚類の耳石等にもこれを感じなければならないわけである。もっとも、魚類がこの種の短週期弾性波に対してどう反応するかについて自分はあまりよく知らないが、これだけの振動に全然無感覚であろうとは想像し難い。 diff --git a/07.ls_object/test/test_ls.rb b/07.ls_object/test/test_ls.rb index 76141bf4cb..2f465d630f 100644 --- a/07.ls_object/test/test_ls.rb +++ b/07.ls_object/test/test_ls.rb @@ -12,11 +12,11 @@ def setup def test_ls_run expected = <<~TEXT - app_1.rb file_1.txt sticky_bit_B - app_2.js file_2.txt suid_A - dir_1 sgid_A suid_B - dir_2 sgid_B - dir_3 sticky_bit_A + dir_1 file_3.txt sticky_bit_B + dir_2 file_4.txt suid_A + dir_3 sgid_A suid_B + file_1.txt sgid_B + file_2.txt sticky_bit_A TEXT @options = Options.new([]) @@ -26,11 +26,11 @@ def test_ls_run def test_run_with_reverse expected = <<~TEXT - suid_B sgid_A dir_1 - suid_A file_2.txt app_2.js - sticky_bit_B file_1.txt app_1.rb - sticky_bit_A dir_3 - sgid_B dir_2 + suid_B sgid_A dir_3 + suid_A file_4.txt dir_2 + sticky_bit_B file_3.txt dir_1 + sticky_bit_A file_2.txt + sgid_B file_1.txt TEXT @options = Options.new(['-r']) @@ -40,12 +40,12 @@ def test_run_with_reverse def test_run_with_dot_match expected = <<~TEXT - . dir_2 sticky_bit_A - .secret_file_1 dir_3 sticky_bit_B - .secret_file_2 file_1.txt suid_A - app_1.rb file_2.txt suid_B - app_2.js sgid_A - dir_1 sgid_B + . file_1.txt sticky_bit_A + .secret_file_1 file_2.txt sticky_bit_B + .secret_file_2 file_3.txt suid_A + dir_1 file_4.txt suid_B + dir_2 sgid_A + dir_3 sgid_B TEXT @options = Options.new(['-a']) @@ -56,19 +56,19 @@ def test_run_with_dot_match def test_run_with_long_option expected = <<~TEXT total: 40 - prw-r--r-- 1 miya staff 4489 12 19 14:10 app_1.rb - prw-r--r-- 1 miya staff 1497 12 19 14:11 app_2.js drwxr-xr-x 2 miya staff 64 12 19 14: 9 dir_1 drwxr-xr-x 2 miya staff 64 12 19 14: 9 dir_2 drwxr-xr-x 2 miya staff 64 12 19 14: 9 dir_3 - prw-r--r-- 1 miya staff 589 12 19 14:11 file_1.txt - prw-r--r-- 1 miya staff 1061 12 19 14:11 file_2.txt - prwsrwsrws 1 miya staff 0 12 19 14: 4 sgid_A - prwsrwSrws 1 miya staff 0 12 19 14: 4 sgid_B + -rw-r--r-- 1 miya staff 2135 12 19 20:50 file_1.txt + -rw-r--r-- 1 miya staff 1044 12 19 20:51 file_2.txt + -rw-r--r-- 1 miya staff 2332 12 19 20:49 file_3.txt + -rw-r--r-- 1 miya staff 4439 12 19 20:50 file_4.txt + -rwsrwsrws 1 miya staff 0 12 19 14: 4 sgid_A + -rwsrwSrws 1 miya staff 0 12 19 14: 4 sgid_B drwtrwtrwt 2 miya staff 64 12 19 14: 5 sticky_bit_A drwtrwtrwT 2 miya staff 64 12 19 14: 5 sticky_bit_B - prwSrwsrws 1 miya staff 0 12 19 14: 5 suid_A - prw-r--r-- 1 miya staff 0 12 19 14: 5 suid_B + -rwSrwsrws 1 miya staff 0 12 19 14: 5 suid_A + -rw-r--r-- 1 miya staff 0 12 19 14: 5 suid_B TEXT @options = Options.new(['-l']) @@ -79,22 +79,22 @@ def test_run_with_long_option def test_run_with_all_options expected = <<~TEXT total: 40 - prw-r--r-- 1 miya staff 0 12 19 14: 5 suid_B - prwSrwsrws 1 miya staff 0 12 19 14: 5 suid_A + -rw-r--r-- 1 miya staff 0 12 19 14: 5 suid_B + -rwSrwsrws 1 miya staff 0 12 19 14: 5 suid_A drwtrwtrwT 2 miya staff 64 12 19 14: 5 sticky_bit_B drwtrwtrwt 2 miya staff 64 12 19 14: 5 sticky_bit_A - prwsrwSrws 1 miya staff 0 12 19 14: 4 sgid_B - prwsrwsrws 1 miya staff 0 12 19 14: 4 sgid_A - prw-r--r-- 1 miya staff 1061 12 19 14:11 file_2.txt - prw-r--r-- 1 miya staff 589 12 19 14:11 file_1.txt + -rwsrwSrws 1 miya staff 0 12 19 14: 4 sgid_B + -rwsrwsrws 1 miya staff 0 12 19 14: 4 sgid_A + -rw-r--r-- 1 miya staff 4439 12 19 20:50 file_4.txt + -rw-r--r-- 1 miya staff 2332 12 19 20:49 file_3.txt + -rw-r--r-- 1 miya staff 1044 12 19 20:51 file_2.txt + -rw-r--r-- 1 miya staff 2135 12 19 20:50 file_1.txt drwxr-xr-x 2 miya staff 64 12 19 14: 9 dir_3 drwxr-xr-x 2 miya staff 64 12 19 14: 9 dir_2 drwxr-xr-x 2 miya staff 64 12 19 14: 9 dir_1 - prw-r--r-- 1 miya staff 1497 12 19 14:11 app_2.js - prw-r--r-- 1 miya staff 4489 12 19 14:10 app_1.rb - prw-r--r-- 1 miya staff 0 12 19 18:30 .secret_file_2 - prw-r--r-- 1 miya staff 0 12 19 18:29 .secret_file_1 - drwxr-xr-x 17 miya staff 544 12 19 18:30 . + -rw-r--r-- 1 miya staff 0 12 19 18:30 .secret_file_2 + -rw-r--r-- 1 miya staff 0 12 19 18:29 .secret_file_1 + drwxr-xr-x 17 miya staff 544 12 19 20:50 . TEXT @options = Options.new(['-arl']) From 932b7c4a64ae08fd26b60f88a10a18a66cd8b538 Mon Sep 17 00:00:00 2001 From: Miya096jp Date: Fri, 20 Dec 2024 09:53:37 +0900 Subject: [PATCH 11/24] =?UTF-8?q?LsLong=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=81=AEformat=5Fmode=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89?= =?UTF-8?q?=E3=81=AE=E3=83=AD=E3=82=B8=E3=83=83=E3=82=AF=E3=82=92=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/lib/entry.rb | 2 +- 07.ls_object/lib/formatter/ls_long.rb | 26 ++++++++--------------- 07.ls_object/test/fixtures/test_ls/suid_A | 0 3 files changed, 10 insertions(+), 18 deletions(-) mode change 100644 => 100755 07.ls_object/test/fixtures/test_ls/suid_A diff --git a/07.ls_object/lib/entry.rb b/07.ls_object/lib/entry.rb index 9f368d9fca..f6e38d7c7c 100644 --- a/07.ls_object/lib/entry.rb +++ b/07.ls_object/lib/entry.rb @@ -56,7 +56,7 @@ def blocks @stat.blocks end - def owner + def user format_mode(@stat).slice(0) end diff --git a/07.ls_object/lib/formatter/ls_long.rb b/07.ls_object/lib/formatter/ls_long.rb index 73f8028023..95d1431eb8 100644 --- a/07.ls_object/lib/formatter/ls_long.rb +++ b/07.ls_object/lib/formatter/ls_long.rb @@ -37,27 +37,19 @@ def build_body(max_size) end def format_type(entry) - digits = entry.type - FILETYPE[digits] + FILETYPE[entry.type] end def format_mode(entry) - digits = entry.mode.split('') - digits.map do |digit| - table_for_permissions(digit, entry) - end.join - end - - def table_for_permissions(digit, entry) - if entry.owner && entry.setuid? - SUID_SGID[digit] - elsif entry.group && entry.setgid? - SUID_SGID[digit] - elsif entry.others && entry.sticky? - STICKY_BIT[digit] + if entry.setuid? + [SUID_SGID[entry.user], REGULAR_MODE[entry.group], REGULAR_MODE[entry.others]] + elsif entry.setgid? + [REGULAR_MODE[entry.user], SUID_SGID[entry.group], REGULAR_MODE[entry.others]] + elsif entry.sticky? + [REGULAR_MODE[entry.user], REGULAR_MODE[entry.group], STICKY_BIT[entry.others]] else - REGULAR_MODE[digit] - end + [REGULAR_MODE[entry.user], REGULAR_MODE[entry.group], REGULAR_MODE[entry.others]] + end.join end def format_mtime(mtime) diff --git a/07.ls_object/test/fixtures/test_ls/suid_A b/07.ls_object/test/fixtures/test_ls/suid_A old mode 100644 new mode 100755 From 1e61dffc9c228a56f3eaa670f9ec28cd45965ea5 Mon Sep 17 00:00:00 2001 From: Miya096jp Date: Fri, 20 Dec 2024 09:59:00 +0900 Subject: [PATCH 12/24] =?UTF-8?q?test=5Fls.rb=E3=81=AE-l=E3=82=AA=E3=83=97?= =?UTF-8?q?=E3=82=B7=E3=83=A7=E3=83=B3=E3=80=81-arl=E3=82=AA=E3=83=97?= =?UTF-8?q?=E3=82=B7=E3=83=A7=E3=83=B3=E3=81=AE=E3=83=92=E3=82=A2=E3=83=89?= =?UTF-8?q?=E3=82=AD=E3=83=A5=E3=83=A1=E3=83=B3=E3=83=88=E3=81=AB=E6=B8=A1?= =?UTF-8?q?=E3=81=99=E3=83=87=E3=83=BC=E3=82=BF=E3=82=92=E4=BF=AE=E6=AD=A3?= =?UTF-8?q?,=20=E3=83=86=E3=82=B9=E3=83=88=E6=88=90=E5=8A=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/test/test_ls.rb | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/07.ls_object/test/test_ls.rb b/07.ls_object/test/test_ls.rb index 2f465d630f..1e673b5c94 100644 --- a/07.ls_object/test/test_ls.rb +++ b/07.ls_object/test/test_ls.rb @@ -63,12 +63,12 @@ def test_run_with_long_option -rw-r--r-- 1 miya staff 1044 12 19 20:51 file_2.txt -rw-r--r-- 1 miya staff 2332 12 19 20:49 file_3.txt -rw-r--r-- 1 miya staff 4439 12 19 20:50 file_4.txt - -rwsrwsrws 1 miya staff 0 12 19 14: 4 sgid_A - -rwsrwSrws 1 miya staff 0 12 19 14: 4 sgid_B - drwtrwtrwt 2 miya staff 64 12 19 14: 5 sticky_bit_A - drwtrwtrwT 2 miya staff 64 12 19 14: 5 sticky_bit_B - -rwSrwsrws 1 miya staff 0 12 19 14: 5 suid_A - -rw-r--r-- 1 miya staff 0 12 19 14: 5 suid_B + -rwxrwsrwx 1 miya staff 0 12 19 14: 4 sgid_A + -rwxrwSrwx 1 miya staff 0 12 19 14: 4 sgid_B + drwxrwxrwt 2 miya staff 64 12 19 14: 5 sticky_bit_A + drwxrwxrwT 2 miya staff 64 12 19 14: 5 sticky_bit_B + -rwsrwxrwx 1 miya staff 0 12 19 14: 5 suid_A + -rwSrwxrwx 1 miya staff 0 12 19 14: 5 suid_B TEXT @options = Options.new(['-l']) @@ -79,12 +79,12 @@ def test_run_with_long_option def test_run_with_all_options expected = <<~TEXT total: 40 - -rw-r--r-- 1 miya staff 0 12 19 14: 5 suid_B - -rwSrwsrws 1 miya staff 0 12 19 14: 5 suid_A - drwtrwtrwT 2 miya staff 64 12 19 14: 5 sticky_bit_B - drwtrwtrwt 2 miya staff 64 12 19 14: 5 sticky_bit_A - -rwsrwSrws 1 miya staff 0 12 19 14: 4 sgid_B - -rwsrwsrws 1 miya staff 0 12 19 14: 4 sgid_A + -rwSrwxrwx 1 miya staff 0 12 19 14: 5 suid_B + -rwsrwxrwx 1 miya staff 0 12 19 14: 5 suid_A + drwxrwxrwT 2 miya staff 64 12 19 14: 5 sticky_bit_B + drwxrwxrwt 2 miya staff 64 12 19 14: 5 sticky_bit_A + -rwxrwSrwx 1 miya staff 0 12 19 14: 4 sgid_B + -rwxrwsrwx 1 miya staff 0 12 19 14: 4 sgid_A -rw-r--r-- 1 miya staff 4439 12 19 20:50 file_4.txt -rw-r--r-- 1 miya staff 2332 12 19 20:49 file_3.txt -rw-r--r-- 1 miya staff 1044 12 19 20:51 file_2.txt From ba13f48f05eb351f49c517df92491d8e50781c5e Mon Sep 17 00:00:00 2001 From: Miya096jp Date: Fri, 20 Dec 2024 10:37:08 +0900 Subject: [PATCH 13/24] =?UTF-8?q?LsLong=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=81=AEformat=5Fmode=E3=82=92=E5=86=8D=E5=BA=A6=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=E3=81=97=E3=80=81=E3=81=9D=E3=82=8C=E3=81=AB=E4=BC=B4?= =?UTF-8?q?=E3=81=84Entry=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AEuser,=20group?= =?UTF-8?q?,=20others=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89=E3=82=92?= =?UTF-8?q?=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/lib/entry.rb | 12 ------------ 07.ls_object/lib/formatter/ls_long.rb | 9 +++++---- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/07.ls_object/lib/entry.rb b/07.ls_object/lib/entry.rb index f6e38d7c7c..34f3863a70 100644 --- a/07.ls_object/lib/entry.rb +++ b/07.ls_object/lib/entry.rb @@ -56,18 +56,6 @@ def blocks @stat.blocks end - def user - format_mode(@stat).slice(0) - end - - def group - format_mode(@stat).slice(1) - end - - def others - format_mode(@stat).slice(2) - end - private def format_type(stat) diff --git a/07.ls_object/lib/formatter/ls_long.rb b/07.ls_object/lib/formatter/ls_long.rb index 95d1431eb8..1eccd34e3d 100644 --- a/07.ls_object/lib/formatter/ls_long.rb +++ b/07.ls_object/lib/formatter/ls_long.rb @@ -41,14 +41,15 @@ def format_type(entry) end def format_mode(entry) + user, group, others = entry.mode.split('') if entry.setuid? - [SUID_SGID[entry.user], REGULAR_MODE[entry.group], REGULAR_MODE[entry.others]] + [SUID_SGID[user], REGULAR_MODE[group], REGULAR_MODE[others]] elsif entry.setgid? - [REGULAR_MODE[entry.user], SUID_SGID[entry.group], REGULAR_MODE[entry.others]] + [REGULAR_MODE[user], SUID_SGID[group], REGULAR_MODE[others]] elsif entry.sticky? - [REGULAR_MODE[entry.user], REGULAR_MODE[entry.group], STICKY_BIT[entry.others]] + [REGULAR_MODE[user], REGULAR_MODE[group], STICKY_BIT[others]] else - [REGULAR_MODE[entry.user], REGULAR_MODE[entry.group], REGULAR_MODE[entry.others]] + [REGULAR_MODE[user], REGULAR_MODE[group], REGULAR_MODE[others]] end.join end From 3d5be9b7db4c03ed2ca1845ab3d05cb7b31a2adf Mon Sep 17 00:00:00 2001 From: Miya096jp Date: Fri, 27 Dec 2024 11:22:07 +0900 Subject: [PATCH 14/24] =?UTF-8?q?ls.rb=E3=81=AE=E5=AE=9A=E6=95=B0FILETYPE?= =?UTF-8?q?=E3=82=92ls=5Flong.rb=E3=81=AELsLong=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=81=AB=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/lib/formatter/ls_long.rb | 12 ++++++++++++ 07.ls_object/ls.rb | 10 ---------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/07.ls_object/lib/formatter/ls_long.rb b/07.ls_object/lib/formatter/ls_long.rb index 1eccd34e3d..7647e181a1 100644 --- a/07.ls_object/lib/formatter/ls_long.rb +++ b/07.ls_object/lib/formatter/ls_long.rb @@ -1,6 +1,18 @@ # frozen_string_literal: true class LsLong < LsFormatter + FILETYPE = { + '1' => 'p', + '2' => 'c', + '4' => 'd', + '6' => 'b', + '10' => '-', + '12' => 'l', + '14' => 's' + }.freeze + + private_constant :FILETYPE + def parse max_size = build_max_size "#{build_total_row}\n#{build_body(max_size)}\n" diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb index 9daa33aa0f..9681c4bb78 100755 --- a/07.ls_object/ls.rb +++ b/07.ls_object/ls.rb @@ -12,16 +12,6 @@ COLUMN = 3 -FILETYPE = { - '1' => 'p', - '2' => 'c', - '4' => 'd', - '6' => 'b', - '10' => '-', - '12' => 'l', - '14' => 's' -}.freeze - REGULAR_MODE = { '0' => '---', '1' => '--x', From 35241526da1f12a57d3cc39a80c369a60b26de5e Mon Sep 17 00:00:00 2001 From: Miya096jp Date: Fri, 27 Dec 2024 11:39:38 +0900 Subject: [PATCH 15/24] =?UTF-8?q?ls=5Fshort.rb=E3=81=AELsShort=E3=82=AF?= =?UTF-8?q?=E3=83=A9=E3=82=B9=E3=82=92ShortFormatter=E3=81=AB=E3=80=81ls?= =?UTF-8?q?=5Flong.rb=E3=81=AELsLong=E3=82=AF=E3=83=A9=E3=82=B9=E3=82=92Lo?= =?UTF-8?q?ngFormatter=E3=81=AB=E5=A4=89=E6=9B=B4=E3=80=82=E8=A6=AA?= =?UTF-8?q?=E3=82=AF=E3=83=A9=E3=82=B9LsFormatter=E3=82=92=E5=89=8A?= =?UTF-8?q?=E9=99=A4=E3=81=97=E3=81=9D=E3=82=8C=E3=81=9E=E3=82=8C=E7=8B=AC?= =?UTF-8?q?=E7=AB=8B=E3=81=97=E3=81=9F=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AB?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E3=80=82=E3=81=9D=E3=82=8C=E3=81=AB=E5=90=88?= =?UTF-8?q?=E3=82=8F=E3=81=9B=E3=81=A6ls.rb=E3=81=AE=E3=82=AF=E3=83=A9?= =?UTF-8?q?=E3=82=B9=E5=91=BC=E3=81=B3=E5=87=BA=E3=81=97=E5=81=B4=E3=82=82?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/formatter/{ls_long.rb => long_formatter.rb} | 6 +++++- 07.ls_object/lib/formatter/ls_formatter.rb | 7 ------- .../lib/formatter/{ls_short.rb => short_formatter.rb} | 6 +++++- 07.ls_object/ls.rb | 11 +++++------ 4 files changed, 15 insertions(+), 15 deletions(-) rename 07.ls_object/lib/formatter/{ls_long.rb => long_formatter.rb} (96%) delete mode 100644 07.ls_object/lib/formatter/ls_formatter.rb rename 07.ls_object/lib/formatter/{ls_short.rb => short_formatter.rb} (88%) diff --git a/07.ls_object/lib/formatter/ls_long.rb b/07.ls_object/lib/formatter/long_formatter.rb similarity index 96% rename from 07.ls_object/lib/formatter/ls_long.rb rename to 07.ls_object/lib/formatter/long_formatter.rb index 7647e181a1..55fca7f5dd 100644 --- a/07.ls_object/lib/formatter/ls_long.rb +++ b/07.ls_object/lib/formatter/long_formatter.rb @@ -1,6 +1,10 @@ # frozen_string_literal: true -class LsLong < LsFormatter +class LongFormatter + def initialize(entries) + @entries = entries + end + FILETYPE = { '1' => 'p', '2' => 'c', diff --git a/07.ls_object/lib/formatter/ls_formatter.rb b/07.ls_object/lib/formatter/ls_formatter.rb deleted file mode 100644 index 8813d3e4b6..0000000000 --- a/07.ls_object/lib/formatter/ls_formatter.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -class LsFormatter - def initialize(entries) - @entries = entries - end -end diff --git a/07.ls_object/lib/formatter/ls_short.rb b/07.ls_object/lib/formatter/short_formatter.rb similarity index 88% rename from 07.ls_object/lib/formatter/ls_short.rb rename to 07.ls_object/lib/formatter/short_formatter.rb index 8dc106c2eb..cbf4e395e1 100644 --- a/07.ls_object/lib/formatter/ls_short.rb +++ b/07.ls_object/lib/formatter/short_formatter.rb @@ -1,6 +1,10 @@ # frozen_string_literal: true -class LsShort < LsFormatter +class ShortFormatter + def initialize(entries) + @entries = entries + end + def parse entries = justfy_entries row = count_row diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb index 9681c4bb78..cfafcb924b 100755 --- a/07.ls_object/ls.rb +++ b/07.ls_object/ls.rb @@ -5,9 +5,8 @@ require_relative './lib/options' require_relative './lib/entry' require_relative './lib/paths' -require_relative './lib/formatter/ls_formatter' -require_relative './lib/formatter/ls_short' -require_relative './lib/formatter/ls_long' +require_relative './lib/formatter/short_formatter' +require_relative './lib/formatter/long_formatter' require 'pathname' COLUMN = 3 @@ -54,8 +53,8 @@ def initialize(pathname, options) def run paths = parse_paths(@pathname, @options) entries = parse_entries(paths) - ls = select_formatter(entries, @options) - ls.parse + formatter = select_formatter(entries, @options) + formatter.parse end private @@ -69,7 +68,7 @@ def parse_entries(paths) end def select_formatter(entries, options) - options.long_format? ? LsLong.new(entries) : LsShort.new(entries) + options.long_format? ? LongFormatter.new(entries) : ShortFormatter.new(entries) end end From ac9342a63d46a33604c5394a09dde4723b7a9780 Mon Sep 17 00:00:00 2001 From: Miya096jp Date: Fri, 27 Dec 2024 13:35:52 +0900 Subject: [PATCH 16/24] =?UTF-8?q?Entry=E3=82=AF=E3=83=A9=E3=82=B9=E3=82=92?= =?UTF-8?q?FileMetadata=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AB=E5=A4=89?= =?UTF-8?q?=E6=9B=B4=E3=81=97=E3=80=81=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB?= =?UTF-8?q?=E5=90=8D=E3=82=92file=5Fmetadate.rb=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/lib/{entry.rb => file_metadata.rb} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename 07.ls_object/lib/{entry.rb => file_metadata.rb} (97%) diff --git a/07.ls_object/lib/entry.rb b/07.ls_object/lib/file_metadata.rb similarity index 97% rename from 07.ls_object/lib/entry.rb rename to 07.ls_object/lib/file_metadata.rb index 34f3863a70..46e2a3602f 100644 --- a/07.ls_object/lib/entry.rb +++ b/07.ls_object/lib/file_metadata.rb @@ -2,7 +2,7 @@ require 'etc' -class Entry +class FileMetadata def initialize(path, stat) @path = path @stat = stat From 227ebc3be7fc9a36fe27bbe48c0adfa9498273d3 Mon Sep 17 00:00:00 2001 From: Miya096jp Date: Fri, 27 Dec 2024 13:47:25 +0900 Subject: [PATCH 17/24] =?UTF-8?q?FileMetadata=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=81=B8=E3=81=AE=E3=82=AF=E3=83=A9=E3=82=B9=E5=90=8D=E5=A4=89?= =?UTF-8?q?=E6=9B=B4=E3=81=AB=E4=BC=B4=E3=81=84=E3=80=81ls.rb=E3=81=AEpars?= =?UTF-8?q?e=5Fentries=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89=E3=82=92build?= =?UTF-8?q?=5Ffile=5Fmetadata=5Flist=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89?= =?UTF-8?q?=E3=81=AB=E5=90=8D=E7=A7=B0=E5=A4=89=E6=9B=B4=E3=81=97=E3=81=9F?= =?UTF-8?q?=E4=BB=96=E3=80=81=E5=A4=89=E6=95=B0=E5=90=8D=E3=80=81=E4=BB=96?= =?UTF-8?q?=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89=E3=81=AE=E5=BC=95=E6=95=B0?= =?UTF-8?q?=E5=90=8D=E3=82=92=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/ls.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb index cfafcb924b..a7854ae006 100755 --- a/07.ls_object/ls.rb +++ b/07.ls_object/ls.rb @@ -3,7 +3,7 @@ # frozen_string_literal: true require_relative './lib/options' -require_relative './lib/entry' +require_relative './lib/file_metadata' require_relative './lib/paths' require_relative './lib/formatter/short_formatter' require_relative './lib/formatter/long_formatter' @@ -52,8 +52,8 @@ def initialize(pathname, options) def run paths = parse_paths(@pathname, @options) - entries = parse_entries(paths) - formatter = select_formatter(entries, @options) + file_metadata_list = build_file_metadata_list(paths) + formatter = select_formatter(file_metadata_list, @options) formatter.parse end @@ -63,12 +63,12 @@ def parse_paths(pathname, options) Paths.new(pathname, options).parse end - def parse_entries(paths) - paths.map { |path| Entry.new(path, File::Stat.new(path)) } + def build_file_metadata_list(paths) + paths.map { |path| FileMetadata.new(path, File::Stat.new(path)) } end - def select_formatter(entries, options) - options.long_format? ? LongFormatter.new(entries) : ShortFormatter.new(entries) + def select_formatter(file_metadata_list, options) + options.long_format? ? LongFormatter.new(file_metadata_list) : ShortFormatter.new(file_metadata_list) end end From 78f437710735e81fb9a3366f1fb4b64b80d574bb Mon Sep 17 00:00:00 2001 From: Miya096jp Date: Fri, 27 Dec 2024 13:53:44 +0900 Subject: [PATCH 18/24] =?UTF-8?q?ShortFormatter=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=81=AE=E3=82=A4=E3=83=B3=E3=82=B9=E3=82=BF=E3=83=B3=E3=82=B9?= =?UTF-8?q?=E5=A4=89=E6=95=B0=E3=82=92@entries=E3=81=8B=E3=82=89@file=5Fme?= =?UTF-8?q?tadata=5Flist=E3=81=AB=E5=A4=89=E6=9B=B4/count=5Frow=E3=83=A1?= =?UTF-8?q?=E3=82=BD=E3=83=83=E3=83=89=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/lib/formatter/short_formatter.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/07.ls_object/lib/formatter/short_formatter.rb b/07.ls_object/lib/formatter/short_formatter.rb index cbf4e395e1..eabf89b5ef 100644 --- a/07.ls_object/lib/formatter/short_formatter.rb +++ b/07.ls_object/lib/formatter/short_formatter.rb @@ -1,13 +1,13 @@ # frozen_string_literal: true class ShortFormatter - def initialize(entries) - @entries = entries + def initialize(file_metadata_list) + @file_metadata_list = file_metadata_list end def parse entries = justfy_entries - row = count_row + row = count_row(entries) sliced_entries = slice_entries(entries, row) "#{transpose(sliced_entries).map { |entry| entry.join.rstrip }.join("\n")}\n" end @@ -15,12 +15,12 @@ def parse private def justfy_entries - max_length = @entries.map { |entry| entry.name.size }.max - @entries.map { |entry| entry.name.ljust(max_length + 1) } + max_length = @file_metadata_list.map { |file_metadata| file_metadata.name.size }.max + @file_metadata_list.map { |file_metadata| file_metadata.name.ljust(max_length + 1) } end - def count_row - (@entries.size.to_f / COLUMN).ceil + def count_row(entries) + (entries.size.to_f / COLUMN).ceil end def slice_entries(entries, row) From 297004baf89711b4f3250e92bb3f11abd6e5776a Mon Sep 17 00:00:00 2001 From: Miya096jp Date: Fri, 27 Dec 2024 13:59:17 +0900 Subject: [PATCH 19/24] =?UTF-8?q?LongFormatter=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=81=AE=E3=82=A4=E3=83=B3=E3=82=B9=E3=82=BF=E3=83=B3=E3=82=B9?= =?UTF-8?q?=E5=A4=89=E6=95=B0=E3=82=92@entries=E3=81=8B=E3=82=89@file=5Fme?= =?UTF-8?q?tadata=5Flist=E3=81=AB=E5=A4=89=E6=9B=B4=E3=80=82=E3=81=9D?= =?UTF-8?q?=E3=82=8C=E3=81=AB=E4=BC=B4=E3=81=84=E5=90=84=E3=83=A1=E3=82=BD?= =?UTF-8?q?=E3=83=83=E3=83=89=E3=81=AE=E3=83=91=E3=83=A9=E3=83=A1=E3=83=BC?= =?UTF-8?q?=E3=82=BF=E3=83=BC=E5=90=8D=E3=82=82=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/lib/formatter/long_formatter.rb | 44 ++++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/07.ls_object/lib/formatter/long_formatter.rb b/07.ls_object/lib/formatter/long_formatter.rb index 55fca7f5dd..02cdc4eff2 100644 --- a/07.ls_object/lib/formatter/long_formatter.rb +++ b/07.ls_object/lib/formatter/long_formatter.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true class LongFormatter - def initialize(entries) - @entries = entries + def initialize(file_metadata_list) + @file_metadata_list = file_metadata_list end FILETYPE = { @@ -26,43 +26,43 @@ def parse def build_max_size { - nlink: @entries.map { |entry| entry.nlink.to_s.size }.max, - username: @entries.map { |entry| entry.username.size }.max, - groupname: @entries.map { |entry| entry.groupname.size }.max, - bytesize: @entries.map { |entry| entry.bytesize.to_s.size }.max + nlink: @file_metadata_list.map { |file_metadata| file_metadata.nlink.to_s.size }.max, + username: @file_metadata_list.map { |file_metadata| file_metadata.username.size }.max, + groupname: @file_metadata_list.map { |file_metadata| file_metadata.groupname.size }.max, + bytesize: @file_metadata_list.map { |file_metadata| file_metadata.bytesize.to_s.size }.max } end def build_total_row - total = @entries.sum { |entry| entry.blocks.to_i } + total = @file_metadata_list.sum { |file_metadata| file_metadata.blocks.to_i } "total: #{total}" end def build_body(max_size) - @entries.map do |entry| + @file_metadata_list.map do |file_metadata| [ - "#{format_type(entry)}#{format_mode(entry)}", - entry.nlink.to_s.rjust(max_size[:nlink] + 1), - entry.username.rjust(max_size[:username] + 1), - entry.groupname.rjust(max_size[:groupname] + 1), - entry.bytesize.to_s.rjust(max_size[:bytesize] + 1), - " #{format_mtime(entry.mtime)}", - " #{entry.name}" + "#{format_type(file_metadata)}#{format_mode(file_metadata)}", + file_metadata.nlink.to_s.rjust(max_size[:nlink] + 1), + file_metadata.username.rjust(max_size[:username] + 1), + file_metadata.groupname.rjust(max_size[:groupname] + 1), + file_metadata.bytesize.to_s.rjust(max_size[:bytesize] + 1), + " #{format_mtime(file_metadata.mtime)}", + " #{file_metadata.name}" ].join end.join("\n") end - def format_type(entry) - FILETYPE[entry.type] + def format_type(file_metadata) + FILETYPE[file_metadata.type] end - def format_mode(entry) - user, group, others = entry.mode.split('') - if entry.setuid? + def format_mode(file_metadata) + user, group, others = file_metadata.mode.split('') + if file_metadata.setuid? [SUID_SGID[user], REGULAR_MODE[group], REGULAR_MODE[others]] - elsif entry.setgid? + elsif file_metadata.setgid? [REGULAR_MODE[user], SUID_SGID[group], REGULAR_MODE[others]] - elsif entry.sticky? + elsif file_metadata.sticky? [REGULAR_MODE[user], REGULAR_MODE[group], STICKY_BIT[others]] else [REGULAR_MODE[user], REGULAR_MODE[group], REGULAR_MODE[others]] From a51fe518a10acdf4395bb3afb23f217222f04391 Mon Sep 17 00:00:00 2001 From: Miya096jp Date: Fri, 27 Dec 2024 14:16:19 +0900 Subject: [PATCH 20/24] =?UTF-8?q?ShortFormatter=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=81=A8LongFormatter=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AEparse?= =?UTF-8?q?=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89=E3=82=92format=E3=83=A1?= =?UTF-8?q?=E3=82=BD=E3=83=83=E3=83=89=E3=81=AB=E5=A4=89=E6=9B=B4=E3=81=97?= =?UTF-8?q?=E3=80=81ls.rb=E3=81=AE=E5=91=BC=E3=81=B3=E5=87=BA=E3=81=97?= =?UTF-8?q?=E5=81=B4=E3=82=82=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/lib/formatter/long_formatter.rb | 2 +- 07.ls_object/lib/formatter/short_formatter.rb | 2 +- 07.ls_object/ls.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/07.ls_object/lib/formatter/long_formatter.rb b/07.ls_object/lib/formatter/long_formatter.rb index 02cdc4eff2..2e36fa83a1 100644 --- a/07.ls_object/lib/formatter/long_formatter.rb +++ b/07.ls_object/lib/formatter/long_formatter.rb @@ -17,7 +17,7 @@ def initialize(file_metadata_list) private_constant :FILETYPE - def parse + def format max_size = build_max_size "#{build_total_row}\n#{build_body(max_size)}\n" end diff --git a/07.ls_object/lib/formatter/short_formatter.rb b/07.ls_object/lib/formatter/short_formatter.rb index eabf89b5ef..652cef6f8a 100644 --- a/07.ls_object/lib/formatter/short_formatter.rb +++ b/07.ls_object/lib/formatter/short_formatter.rb @@ -5,7 +5,7 @@ def initialize(file_metadata_list) @file_metadata_list = file_metadata_list end - def parse + def format entries = justfy_entries row = count_row(entries) sliced_entries = slice_entries(entries, row) diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb index a7854ae006..df6f4a9585 100755 --- a/07.ls_object/ls.rb +++ b/07.ls_object/ls.rb @@ -54,7 +54,7 @@ def run paths = parse_paths(@pathname, @options) file_metadata_list = build_file_metadata_list(paths) formatter = select_formatter(file_metadata_list, @options) - formatter.parse + formatter.format end private From 20962101d01498f2a915d491f8f9b9d8c5a46345 Mon Sep 17 00:00:00 2001 From: Miya096jp Date: Fri, 27 Dec 2024 16:31:02 +0900 Subject: [PATCH 21/24] =?UTF-8?q?LongFormatter=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=81=A8ShortFormatter=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AEpars?= =?UTF-8?q?e=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89=E3=82=92format=5Foutput?= =?UTF-8?q?=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89=E3=81=AB=E5=90=8D=E7=A7=B0?= =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/lib/formatter/long_formatter.rb | 2 +- 07.ls_object/lib/formatter/short_formatter.rb | 2 +- 07.ls_object/lib/paths.rb | 9 ++++++--- 07.ls_object/ls.rb | 8 ++++---- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/07.ls_object/lib/formatter/long_formatter.rb b/07.ls_object/lib/formatter/long_formatter.rb index 2e36fa83a1..01e9b558ad 100644 --- a/07.ls_object/lib/formatter/long_formatter.rb +++ b/07.ls_object/lib/formatter/long_formatter.rb @@ -17,7 +17,7 @@ def initialize(file_metadata_list) private_constant :FILETYPE - def format + def format_output max_size = build_max_size "#{build_total_row}\n#{build_body(max_size)}\n" end diff --git a/07.ls_object/lib/formatter/short_formatter.rb b/07.ls_object/lib/formatter/short_formatter.rb index 652cef6f8a..391148b092 100644 --- a/07.ls_object/lib/formatter/short_formatter.rb +++ b/07.ls_object/lib/formatter/short_formatter.rb @@ -5,7 +5,7 @@ def initialize(file_metadata_list) @file_metadata_list = file_metadata_list end - def format + def format_output entries = justfy_entries row = count_row(entries) sliced_entries = slice_entries(entries, row) diff --git a/07.ls_object/lib/paths.rb b/07.ls_object/lib/paths.rb index f955924e08..46595debf5 100644 --- a/07.ls_object/lib/paths.rb +++ b/07.ls_object/lib/paths.rb @@ -3,18 +3,21 @@ require 'pathname' class Paths + attr_reader :paths + def initialize(pathname, options) @pathname = pathname @options = options + @paths = collect_paths end - def parse + private + + def collect_paths paths = @options.dot_match? ? Dir.glob(@pathname, File::FNM_DOTMATCH).sort : Dir.glob(@pathname) reverse(paths) end - private - def reverse(paths) @options.reverse? ? paths.reverse : paths end diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb index df6f4a9585..dd8a7234ee 100755 --- a/07.ls_object/ls.rb +++ b/07.ls_object/ls.rb @@ -51,16 +51,16 @@ def initialize(pathname, options) end def run - paths = parse_paths(@pathname, @options) + paths = collect_paths(@pathname, @options) file_metadata_list = build_file_metadata_list(paths) formatter = select_formatter(file_metadata_list, @options) - formatter.format + formatter.format_output end private - def parse_paths(pathname, options) - Paths.new(pathname, options).parse + def collect_paths(pathname, options) + Paths.new(pathname, options).paths end def build_file_metadata_list(paths) From 44049e68003e3b1fa01f4b6cddd5696f6475c0ba Mon Sep 17 00:00:00 2001 From: Miya096jp Date: Fri, 27 Dec 2024 17:54:59 +0900 Subject: [PATCH 22/24] =?UTF-8?q?=E5=AE=9A=E6=95=B0REGULAR=5FMODE,=20SUID?= =?UTF-8?q?=5FSGID,=20STICKY=5FBIT=E3=82=92LongFormatter=E3=82=AF=E3=83=A9?= =?UTF-8?q?=E3=82=B9=E3=81=B8=E7=A7=BB=E5=8B=95,=20=E5=AE=9A=E6=95=B0COLUM?= =?UTF-8?q?N=E3=82=92ShortFormatter=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=B8?= =?UTF-8?q?=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/lib/formatter/long_formatter.rb | 35 ++++++++++++++++++- 07.ls_object/lib/formatter/short_formatter.rb | 4 +++ 07.ls_object/ls.rb | 35 ------------------- 3 files changed, 38 insertions(+), 36 deletions(-) diff --git a/07.ls_object/lib/formatter/long_formatter.rb b/07.ls_object/lib/formatter/long_formatter.rb index 01e9b558ad..10c33d7a31 100644 --- a/07.ls_object/lib/formatter/long_formatter.rb +++ b/07.ls_object/lib/formatter/long_formatter.rb @@ -15,7 +15,40 @@ def initialize(file_metadata_list) '14' => 's' }.freeze - private_constant :FILETYPE + REGULAR_MODE = { + '0' => '---', + '1' => '--x', + '2' => '-w-', + '3' => '-wx', + '4' => 'r--', + '5' => 'r-x', + '6' => 'rw-', + '7' => 'rwx' + }.freeze + + SUID_SGID = { + '0' => '---', + '1' => '--s', + '2' => '-wS', + '3' => '-ws', + '4' => 'r-S', + '5' => 'r-s', + '6' => 'rwS', + '7' => 'rws' + }.freeze + + STICKY_BIT = { + '0' => '---', + '1' => '--t', + '2' => '-wT', + '3' => '-wt', + '4' => 'r-T', + '5' => 'r-t', + '6' => 'rwT', + '7' => 'rwt' + }.freeze + + private_constant :FILETYPE, :REGULAR_MODE, :SUID_SGID, :STICKY_BIT def format_output max_size = build_max_size diff --git a/07.ls_object/lib/formatter/short_formatter.rb b/07.ls_object/lib/formatter/short_formatter.rb index 391148b092..59fb6836db 100644 --- a/07.ls_object/lib/formatter/short_formatter.rb +++ b/07.ls_object/lib/formatter/short_formatter.rb @@ -5,6 +5,10 @@ def initialize(file_metadata_list) @file_metadata_list = file_metadata_list end + COLUMN = 3 + + private_constant :COLUMN + def format_output entries = justfy_entries row = count_row(entries) diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb index dd8a7234ee..b1655cc0ea 100755 --- a/07.ls_object/ls.rb +++ b/07.ls_object/ls.rb @@ -9,41 +9,6 @@ require_relative './lib/formatter/long_formatter' require 'pathname' -COLUMN = 3 - -REGULAR_MODE = { - '0' => '---', - '1' => '--x', - '2' => '-w-', - '3' => '-wx', - '4' => 'r--', - '5' => 'r-x', - '6' => 'rw-', - '7' => 'rwx' -}.freeze - -SUID_SGID = { - '0' => '---', - '1' => '--s', - '2' => '-wS', - '3' => '-ws', - '4' => 'r-S', - '5' => 'r-s', - '6' => 'rwS', - '7' => 'rws' -}.freeze - -STICKY_BIT = { - '0' => '---', - '1' => '--t', - '2' => '-wT', - '3' => '-wt', - '4' => 'r-T', - '5' => 'r-t', - '6' => 'rwT', - '7' => 'rwt' -}.freeze - class Ls def initialize(pathname, options) @pathname = pathname From b8ff95cb90317dcfc17c0fb8ad164a69205ddb65 Mon Sep 17 00:00:00 2001 From: Miya096jp Date: Sun, 29 Dec 2024 13:04:13 +0900 Subject: [PATCH 23/24] =?UTF-8?q?LongFormatter=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=81=AEformat=5Fmode=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89?= =?UTF-8?q?=E3=81=AB=E3=81=8A=E3=81=91=E3=82=8B=E7=89=B9=E6=AE=8A=E6=A8=A9?= =?UTF-8?q?=E9=99=90=E8=A8=AD=E5=AE=9A=E3=81=AE=E3=83=AD=E3=82=B8=E3=83=83?= =?UTF-8?q?=E3=82=AF=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/lib/formatter/long_formatter.rb | 13 ++++--------- .../fixtures/test_ls/suid_sgid_and_sticky_bit_A | 0 .../fixtures/test_ls/suid_sgid_and_sticky_bit_B | 0 3 files changed, 4 insertions(+), 9 deletions(-) create mode 100755 07.ls_object/test/fixtures/test_ls/suid_sgid_and_sticky_bit_A create mode 100644 07.ls_object/test/fixtures/test_ls/suid_sgid_and_sticky_bit_B diff --git a/07.ls_object/lib/formatter/long_formatter.rb b/07.ls_object/lib/formatter/long_formatter.rb index 10c33d7a31..aca475d6f5 100644 --- a/07.ls_object/lib/formatter/long_formatter.rb +++ b/07.ls_object/lib/formatter/long_formatter.rb @@ -91,15 +91,10 @@ def format_type(file_metadata) def format_mode(file_metadata) user, group, others = file_metadata.mode.split('') - if file_metadata.setuid? - [SUID_SGID[user], REGULAR_MODE[group], REGULAR_MODE[others]] - elsif file_metadata.setgid? - [REGULAR_MODE[user], SUID_SGID[group], REGULAR_MODE[others]] - elsif file_metadata.sticky? - [REGULAR_MODE[user], REGULAR_MODE[group], STICKY_BIT[others]] - else - [REGULAR_MODE[user], REGULAR_MODE[group], REGULAR_MODE[others]] - end.join + user_permission = file_metadata.setuid? ? SUID_SGID : REGULAR_MODE + group_permission = file_metadata.setgid? ? SUID_SGID : REGULAR_MODE + others_permission = file_metadata.sticky? ? STICKY_BIT : REGULAR_MODE + [user_permission[user], group_permission[group], others_permission[others]].join end def format_mtime(mtime) diff --git a/07.ls_object/test/fixtures/test_ls/suid_sgid_and_sticky_bit_A b/07.ls_object/test/fixtures/test_ls/suid_sgid_and_sticky_bit_A new file mode 100755 index 0000000000..e69de29bb2 diff --git a/07.ls_object/test/fixtures/test_ls/suid_sgid_and_sticky_bit_B b/07.ls_object/test/fixtures/test_ls/suid_sgid_and_sticky_bit_B new file mode 100644 index 0000000000..e69de29bb2 From 3a05d94fed5036d14348fb577f348d0cb1e0fad6 Mon Sep 17 00:00:00 2001 From: Miya096jp Date: Sun, 29 Dec 2024 14:06:27 +0900 Subject: [PATCH 24/24] =?UTF-8?q?Path=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AE?= =?UTF-8?q?=E5=BC=95=E6=95=B0options=E3=82=92=E3=80=81dot=5Fmatch=E3=81=A8?= =?UTF-8?q?reverse=E3=81=AB=E5=88=86=E5=89=B2=E3=81=97=E3=82=B9=E3=82=BF?= =?UTF-8?q?=E3=83=B3=E3=83=97=E7=B5=90=E5=90=88=E3=82=92=E8=A7=A3=E6=B6=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 07.ls_object/lib/paths.rb | 9 +++++---- 07.ls_object/ls.rb | 12 ++++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/07.ls_object/lib/paths.rb b/07.ls_object/lib/paths.rb index 46595debf5..7fa6ed5edc 100644 --- a/07.ls_object/lib/paths.rb +++ b/07.ls_object/lib/paths.rb @@ -5,20 +5,21 @@ class Paths attr_reader :paths - def initialize(pathname, options) + def initialize(pathname, dot_match, reverse) @pathname = pathname - @options = options + @dot_match = dot_match + @reverse = reverse @paths = collect_paths end private def collect_paths - paths = @options.dot_match? ? Dir.glob(@pathname, File::FNM_DOTMATCH).sort : Dir.glob(@pathname) + paths = @dot_match ? Dir.glob(@pathname, File::FNM_DOTMATCH).sort : Dir.glob(@pathname) reverse(paths) end def reverse(paths) - @options.reverse? ? paths.reverse : paths + @reverse ? paths.reverse : paths end end diff --git a/07.ls_object/ls.rb b/07.ls_object/ls.rb index b1655cc0ea..f2949d052c 100755 --- a/07.ls_object/ls.rb +++ b/07.ls_object/ls.rb @@ -16,24 +16,24 @@ def initialize(pathname, options) end def run - paths = collect_paths(@pathname, @options) + paths = collect_paths(@pathname, @options.dot_match?, @options.reverse?) file_metadata_list = build_file_metadata_list(paths) - formatter = select_formatter(file_metadata_list, @options) + formatter = select_formatter(file_metadata_list, @options.long_format?) formatter.format_output end private - def collect_paths(pathname, options) - Paths.new(pathname, options).paths + def collect_paths(pathname, dot_match, reverse) + Paths.new(pathname, dot_match, reverse).paths end def build_file_metadata_list(paths) paths.map { |path| FileMetadata.new(path, File::Stat.new(path)) } end - def select_formatter(file_metadata_list, options) - options.long_format? ? LongFormatter.new(file_metadata_list) : ShortFormatter.new(file_metadata_list) + def select_formatter(file_metadata_list, long_format) + long_format ? LongFormatter.new(file_metadata_list) : ShortFormatter.new(file_metadata_list) end end