Skip to content

Commit

Permalink
Refactor with renderer
Browse files Browse the repository at this point in the history
  • Loading branch information
ceritium committed Mar 14, 2024
1 parent 87d197c commit c82c00a
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 88 deletions.
2 changes: 2 additions & 0 deletions lib/flatito.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
require_relative "flatito/flatten_yaml"
require_relative "flatito/finder"
require_relative "flatito/yaml_with_line_number"
require_relative "flatito/renderer"
require_relative "flatito/regex_from_search"

module Flatito
def self.search(paths, options)
Expand Down
101 changes: 20 additions & 81 deletions lib/flatito/finder.rb
Original file line number Diff line number Diff line change
@@ -1,58 +1,49 @@
# frozen_string_literal: true

require "io/console"
require_relative "regex_from_search"

module Flatito
class Finder
include RegexFromSearch

DEFAULT_EXTENSIONS = %w[json yml yaml].freeze

attr_reader :paths, :search, :extensions
attr_reader :paths, :search, :extensions, :options, :renderer

def initialize(paths, options = {})
@paths = paths
@search = options[:search]
@extensions = prepare_extensions(options[:extensions] || DEFAULT_EXTENSIONS)
@no_color = options[:no_color] || false
@skip_hidden = options[:skip_hidden] || true
@options = options
@renderer = Renderer.build(options)
end

def call
listen_for_stdout_width_change
renderer.prepare

paths.each do |path|
TreeIterator.new(path, skip_hidden: @skip_hidden).each do |pathname|
print "\r #{truncate(pathname.to_s, stdout_width - 4)}#{erase_line}" if tty?
TreeIterator.new(path, options).each do |pathname|
renderer.print_file_progress(pathname)

if extensions.include?(pathname.extname)
items = FlattenYaml.new(pathname).flatten
items = filter_by_search(items) if search

next unless items.any?

line_number_padding = items.map(&:line).max.to_s.length

print erase_line if tty?
puts colorize(pathname.to_s, :light_blue)

# TODO: allow sorting by line number or key
# items.sort_by(&:line).each do |item|
items.each do |item|
print_item(item, line_number_padding)
end
puts
flat_and_filter(pathname)
end

$stdout.flush
end
end

print erase_line if tty?
puts
renderer.ending
end

private

def no_color?
ENV["TERM"] == "dumb" || ENV["NO_COLOR"] == "true" || @no_color == true
def flat_and_filter(pathname)
items = FlattenYaml.new(pathname).items
items = filter_by_search(items) if search

return unless items.any?

renderer.print_pathname(pathname)
renderer.print_items(items)
end

def prepare_extensions(extensions)
Expand All @@ -61,62 +52,10 @@ def prepare_extensions(extensions)
end
end

def truncate(string, max = 50)
string.length > max ? "#{string[0...max]}..." : string
end

def tty?
$stdout.tty?
end

def stdout_width
@stdout_width ||= $stdout.winsize[1]
rescue StandardError
80
end

def listen_for_stdout_width_change
Signal.trap(:WINCH) do
@stdout_width = $stdout.winsize[1]
end
end

def erase_line
"\e[K\e[0G"
end

def print_item(item, line_number_padding)
line_number = colorize("#{item.line.to_s.rjust(line_number_padding)}: ", :light_yellow)
value = if item.value.length.positive?
colorize("=> #{item.value}", :gray)
else
""
end

puts "#{line_number} #{matched_string(item.key)} #{value}\n"
end

def filter_by_search(items)
items.select do |item|
regex.match?(item.key)
end
end

def colorize(string, color)
no_color? ? string : string.colorize(color)
end

def matched_string(string)
return string if search.nil? || no_color?

regex.match(string).to_a&.each do |match|
string = string.gsub(/#{match}/, match.colorize(:light_red))
end
string
end

def regex
@regex ||= Regexp.new(search)
end
end
end
6 changes: 1 addition & 5 deletions lib/flatito/flatten_yaml.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@ def initialize(pathname)
@pathname = pathname
end

def entries
flatten
end

def flatten
def items
with_line_numbers.compact.flat_map do |line|
flatten_hash(line) if line.is_a?(Hash)
end.compact
Expand Down
9 changes: 9 additions & 0 deletions lib/flatito/regex_from_search.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

module Flatito
module RegexFromSearch
def regex
@regex ||= Regexp.new(search)
end
end
end
144 changes: 144 additions & 0 deletions lib/flatito/renderer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# frozen_string_literal: true

require "io/console"
require_relative "regex_from_search"

module Flatito
class Renderer
include RegexFromSearch

def self.build(options)
if tty?
Renderer::TTY.new(options)
else
Renderer::Plain.new(options)
end
end

def self.tty?
$stdout.tty?
end
end

class Base
attr_reader :search, :no_color

def initialize(options)
@no_color = options[:no_color] || false
@search = options[:search]
end

def prepare; end
def print_file_progress(pathname); end
def ending; end

def print_pathname(pathname)
puts colorize(pathname.to_s, :light_blue)
end

def print_items(items)
line_number_padding = items.map(&:line).max.to_s.length

items.each do |item|
print_item(item, line_number_padding)
end
puts
flush
end

def print_item(item, line_number_padding)
line_number = colorize("#{item.line.to_s.rjust(line_number_padding)}: ", :light_yellow)
value = if item.value.length.positive?
colorize("=> #{item.value}", :gray)
else
""
end

puts "#{line_number} #{matched_string(item.key)} #{value}\n"
end

private

def flush
stdout.flush
end

def regex
@regex ||= Regexp.new(search)
end

def matched_string(string)
return string if search.nil? || no_color?

regex.match(string).to_a&.each do |match|
string = string.gsub(/#{match}/, match.colorize(:light_red))
end
string
end

def no_color?
ENV["TERM"] == "dumb" || ENV["NO_COLOR"] == "true" || no_color == true
end

def truncate(string, max = 50)
string.length > max ? "#{string[0...max]}..." : string
end

def stdout
$stdout
end

def colorize(string, color)
no_color? ? string : string.colorize(color)
end
end

class Renderer::Plain < Base
def ending
puts
end
end

class Renderer::TTY < Base
def initialize(options)
super
require "io/console"
end

def prepare
listen_for_stdout_width_change
end

def print_file_progress(pathname)
print "\r #{truncate(pathname.to_s, stdout_width - 4)}#{erase_line}"
end

def print_pathname(pathname)
print erase_line
super
end

def ending
print erase_line
puts
end

private

def erase_line
"\e[K\e[0G"
end

def stdout_width
@stdout_width ||= stdout.winsize[1]
rescue StandardError
80
end

def listen_for_stdout_width_change
Signal.trap(:WINCH) do
@stdout_width = stdout.winsize[1]
end
end
end
end
4 changes: 2 additions & 2 deletions lib/flatito/tree_iterator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ class TreeIterator

attr_reader :base_path, :skip_hidden

def initialize(base_path, skip_hidden: true)
def initialize(base_path, options = {})
@base_path = base_path
@skip_hidden = skip_hidden
@skip_hidden = options[:skip_hidden] || true
end

def each(&block)
Expand Down

0 comments on commit c82c00a

Please sign in to comment.