Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Input via stdin #5

Merged
merged 1 commit into from
Mar 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ If bundler is not being used to manage dependencies, install the gem by executin

```sh
Usage: flatito PATH [options]
Example: flatito . -k hello
Example: flatito . -k "search string" -e "json,yaml"
Example: cat file.yaml | flatito -k "search string"

-h, --help Prints this help
-V, --version Show version
Expand Down
15 changes: 9 additions & 6 deletions exe/flatito
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ require "flatito"
require "optparse"

# If no arguments are given, print help
ARGV << "-h" if ARGV.empty?
stdin = $stdin.read unless $stdin.tty?
ARGV << "-h" if ARGV.empty? && !stdin

options = {}
OptionParser.new do |opts|
opts.banner = <<~HEREDOC
Usage: flatito PATH [options]
Example: flatito . -k hello

Example: flatito . -k "search string" -e "json,yaml"
Example: cat file.yaml | flatito -k "search string"
HEREDOC

opts.on("-h", "--help", "Prints this help") do
Expand Down Expand Up @@ -43,8 +44,10 @@ OptionParser.new do |opts|
end
end.parse!

begin
Flatito::Config.prepare_with_options(options)

if stdin
Flatito.flat_content(stdin, options)
else
Flatito.search(ARGV, options)
rescue Interrupt
warn "\nInterrupted"
end
15 changes: 13 additions & 2 deletions lib/flatito.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,20 @@
require_relative "flatito/yaml_with_line_number"
require_relative "flatito/renderer"
require_relative "flatito/regex_from_search"
require_relative "flatito/print_items"
require_relative "flatito/config"

module Flatito
def self.search(paths, options)
Finder.new(paths, options).call
class << self
def search(paths, options = {})
Finder.new(paths, options).call
rescue Interrupt
warn "\nInterrupted"
end

def flat_content(content, options = {})
items = FlattenYaml.items_from_content(content)
PrintItems.new(options[:search]).print(items)
end
end
end
17 changes: 17 additions & 0 deletions lib/flatito/config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

module Flatito
module Config
@stdout = $stdout
@stderr = $stderr
@stdin = $stdin

class << self
attr_accessor :renderer, :stdout, :stder, :stdin

def prepare_with_options(options)
self.renderer = Renderer.build(options)
end
end
end
end
23 changes: 8 additions & 15 deletions lib/flatito/finder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ class Finder

DEFAULT_EXTENSIONS = %w[json yml yaml].freeze

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

def initialize(paths, options = {})
@paths = paths
@search = options[:search]
@extensions = prepare_extensions(options[:extensions] || DEFAULT_EXTENSIONS)
@options = options
@renderer = Renderer.build(options)
@print_items = PrintItems.new(search)
end

def call
Expand All @@ -36,26 +36,19 @@ def call

private

def flat_and_filter(pathname)
items = FlattenYaml.new(pathname).items
items = filter_by_search(items) if search

return unless items.any?
def renderer
Config.renderer
end

renderer.print_pathname(pathname)
renderer.print_items(items)
def flat_and_filter(pathname)
items = FlattenYaml.items_from_path(pathname)
print_items.print(items, pathname)
end

def prepare_extensions(extensions)
extensions.map do |ext|
ext.start_with?(".") ? ext : ".#{ext}"
end
end

def filter_by_search(items)
items.select do |item|
regex.match?(item.key)
end
end
end
end
35 changes: 22 additions & 13 deletions lib/flatito/flatten_yaml.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
# frozen_string_literal: true

require_relative "utils"
module Flatito
class FlattenYaml
include Utils

Item = Struct.new(:key, :value, :line, keyword_init: true)
def initialize(pathname)
class << self
def items_from_path(pathname)
content = File.read(pathname)
new(content, pathname: pathname).items
end

def items_from_content(content)
new(content).items
end
end

attr_reader :content, :pathname

def initialize(content, pathname: nil)
@content = content
@pathname = pathname
end

Expand All @@ -23,28 +40,20 @@ def flatten_hash(hash, prefix = nil)
end
end
end
rescue StandardError => e
warn "Error parsing #{@pathname}, #{e.message}"
end

def with_line_numbers
handler = YAMLWithLineNumber::TreeBuilder.new
handler.parser = Psych::Parser.new(handler)

handler.parser.parse(File.read(@pathname))
handler.parser.parse(content)
YAMLWithLineNumber::VisitorsToRuby.create.accept(handler.root)
rescue Psych::SyntaxError
warn "Invalid YAML #{@pathname}"

warn "Invalid format #{pathname}"
[]
rescue StandardError => e
warn "Error parsing #{@pathname}, #{e.message}"

rescue StandardError
warn "Error parsing #{pathname}"
[]
end

def truncate(string, max = 50)
string.length > max ? "#{string[0...max]}..." : string
end
end
end
30 changes: 30 additions & 0 deletions lib/flatito/print_items.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# frozen_string_literal: true

module Flatito
class PrintItems
include RegexFromSearch
attr_reader :search

def initialize(search)
@search = search
end

def print(items, pathname = nil)
items = filter_by_search(items) if search
return unless items.any?

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

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

def renderer
Config.renderer
end
end
end
44 changes: 15 additions & 29 deletions lib/flatito/renderer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,23 @@

require "io/console"
require_relative "regex_from_search"
require_relative "utils"

module Flatito
class Renderer
include RegexFromSearch

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

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

class Base
include Utils
include RegexFromSearch

attr_reader :search, :no_color

def initialize(options)
Expand All @@ -33,7 +31,7 @@ def print_file_progress(pathname); end
def ending; end

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

def print_items(items)
Expand All @@ -42,8 +40,8 @@ def print_items(items)
items.each do |item|
print_item(item, line_number_padding)
end
puts
flush
stdout.puts
stdout.flush
end

def print_item(item, line_number_padding)
Expand All @@ -54,19 +52,11 @@ def print_item(item, line_number_padding)
""
end

puts "#{line_number} #{matched_string(item.key)} #{value}"
stdout.puts "#{line_number} #{matched_string(item.key)} #{value}"
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?

Expand All @@ -80,12 +70,8 @@ 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
Config.stdout
end

def colorize(string, color)
Expand All @@ -95,7 +81,7 @@ def colorize(string, color)

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

Expand Down Expand Up @@ -128,19 +114,19 @@ def print_pathname(pathname)
def ending
clear_line
show_cursor
puts
stdout.puts
end

def hide_cursor
print HIDE_CURSOR
stdout.print HIDE_CURSOR
end

def show_cursor
print SHOW_CURSOR
stdout.print SHOW_CURSOR
end

def clear_line
print CLEAR_LINE
stdout.print CLEAR_LINE
end

private
Expand Down
9 changes: 9 additions & 0 deletions lib/flatito/utils.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

module Flatito
module Utils
def truncate(string, max = 50)
string.length > max ? "#{string[0...max]}..." : string
end
end
end
2 changes: 0 additions & 2 deletions lib/flatito/yaml_with_line_number.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ def respond_to_missing?(*)

class ClassLoader < Psych::ClassLoader
def find(klassname)
@cache[klassname] ||= resolve(klassname)
rescue ArgumentError
Whatever.new(klassname)
end
end
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/with_ruby_objects.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ two: !ruby/object:OpenStruct
table:
one: One
two: Two
three: !ruby/object:UnknowClass
three: !ruby/object:UnknownClass
one: One
two: Two
Loading