Skip to content

Commit

Permalink
Allow pass the content via stdin
Browse files Browse the repository at this point in the history
For example:

```
cat test/fixtures/merge.yml | flatito
```
  • Loading branch information
ceritium committed Mar 24, 2024
1 parent 6b47d9a commit 6066ada
Show file tree
Hide file tree
Showing 13 changed files with 177 additions and 75 deletions.
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

0 comments on commit 6066ada

Please sign in to comment.