Skip to content

Commit

Permalink
Add -R option
Browse files Browse the repository at this point in the history
  • Loading branch information
buty4649 committed Nov 4, 2023
1 parent f908615 commit b446fa6
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 12 deletions.
3 changes: 2 additions & 1 deletion mrblib/rf/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ module Rf
class Cli
attr_reader :config

def run(argv)
def run(argv) # rubocop:disable Metrics/AbcSize
@config = Config.parse(argv)
Runner.run({
command: config.command,
files: config.files,
filter: config.filter,
slurp: config.slurp,
quiet: config.quiet,
recursive: config.recursive,
with_filename: config.with_filename
})
rescue NotFound => e
Expand Down
6 changes: 4 additions & 2 deletions mrblib/rf/config.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module Rf
class Config
attr_accessor :command, :files, :filter, :slurp, :script_file, :quiet, :with_filename
attr_accessor :command, :files, :filter, :slurp, :script_file, :quiet,
:recursive, :with_filename

def self.parse(argv)
Parser.new.parse(argv)
Expand Down Expand Up @@ -85,9 +86,10 @@ def banner_and_filter_options
end
end

def global_options
def global_options # rubocop:disable Metrics/AbcSize
@global_options ||= OptionMap.new do |opt|
opt.on('-H', '--with-filename', 'print filename with output lines') { @config.with_filename = true }
opt.on('-R', '--recursive', 'read all files under each directory recursively') { @config.recursive = true }
opt.on('-f', '--file=program_file', 'executed the contents of program_file') { |f| @config.script_file = f }
opt.on('-n', '--quiet', 'suppress automatic priting') { @config.quiet = true }
opt.on('-s', '--slurp', 'read all reacords into an array') { @config.slurp = true }
Expand Down
63 changes: 63 additions & 0 deletions mrblib/rf/directory.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
module Rf
class Directory
class Node
attr_reader :path

def initialize(path)
@path = path
@dir = Dir.open(path)
end

def next
child = loop do
child = @dir.read
return unless child
break child unless %w[. ..].include?(child)
end

File.join(@path, child)
end
end

def initialize(root)
@nodes = [Node.new(root)]
end

def next
loop do
path = @nodes.last.next
unless path
@nodes.pop
break if @nodes.empty?

next
end

break path unless File.directory?(path)

@nodes << Node.new(path)
end
end

def self.open(paths)
Enumerator.new do |y|
paths.each do |path|
if path == '-'
y << path
next
end

stat = File::Stat.new(path)
if stat.directory?
dir = Directory.new(path)
while path = dir.next
y << path
end
else
y << path
end
end
end
end
end
end
27 changes: 18 additions & 9 deletions mrblib/rf/runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,32 @@ def self.run(...)
new(...).run
end

attr_reader :container, :bind, :command, :filter, :files, :with_filename
attr_reader :container, :bind, :command, :filter, :inputs, :with_filename

# @param [Hash<String>] opts
# :command => String
# :files => Array<String>
# :filter => Rf::Filter
# :slurp => Boolean
# :recursive => Boolean
# :quiet => Boolean
# :with_filename => Boolean
def initialize(opts)
def initialize(opts) # rubocop:disable Metrics/AbcSize
@command = opts[:command]
@files = opts[:files] || %w[-]
@filter = opts[:filter]
@slurp = true & opts[:slurp]
@quiet = true & opts[:quiet]
@slurp = opts[:slurp]
@quiet = opts[:quiet]

setup_container
@container.with_filename = opts[:with_filename] || (files.size > 1 && filter == Filter::Text)
files = opts[:files] || %w[-]
recursive = opts[:recursive]
@inputs = recursive ? Directory.open(files) : files

with_filename = opts[:with_filename]
with_filename ||= filter == Filter::Text && (
files.size > 1 || (recursive && File.directory?(files.first))
)

setup_container(with_filename)
end

def slurp?
Expand All @@ -33,15 +41,16 @@ def quiet?
end

# enclose the scope of binding
def setup_container
def setup_container(with_filename)
@container = Container.new
@bind = container.instance_eval { binding }
@container.with_filename = with_filename
end

def run # rubocop:disable Metrics/AbcSize
Rf.add_features

files.each do |filename|
inputs.each do |filename|
@container.filename = filename
records = Record.read(filter.new(self.open(filename)))
if slurp?
Expand Down
22 changes: 22 additions & 0 deletions spec/glonal_options_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
describe 'Global options' do
context 'with -R option' do
let(:output) do
<<~OUTPUT
./foo/bar: foobar
./a/b/c: abc
OUTPUT
end

before do
FileUtils.mkdir_p(expand_path('foo'))
write_file('foo/bar', 'foobar')
FileUtils.mkdir_p(expand_path('a/b'))
write_file('a/b/c', 'abc')

run_rf('-R _ .')
end

it { expect(last_command_started).to be_successfully_executed }
it { expect(last_command_started).to have_output output_string_eq output }
end
end
1 change: 1 addition & 0 deletions spec/help_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
global options:
-H, --with-filename print filename with output lines
-R, --recursive read all files under each directory recursively
-f, --file=program_file executed the contents of program_file
-n, --quiet suppress automatic priting
-s, --slurp read all reacords into an array
Expand Down

0 comments on commit b446fa6

Please sign in to comment.