Class: FormatStaged
- Inherits:
-
Object
- Object
- FormatStaged
- Defined in:
- lib/format-staged.rb,
lib/format-staged/io.rb,
lib/format-staged/entry.rb,
lib/format-staged/version.rb
Defined Under Namespace
Classes: Entry
Constant Summary collapse
- VERSION =
"0.0.1"
Instance Attribute Summary collapse
-
#formatter ⇒ Object
readonly
Returns the value of attribute formatter.
-
#patterns ⇒ Object
readonly
Returns the value of attribute patterns.
-
#update ⇒ Object
readonly
Returns the value of attribute update.
-
#verbose ⇒ Object
readonly
Returns the value of attribute verbose.
-
#write ⇒ Object
readonly
Returns the value of attribute write.
Instance Method Summary collapse
- #format_file(file) ⇒ Object
- #format_object(file) ⇒ Object
- #get_output(*args, lines: true) ⇒ Object
-
#initialize(formatter:, patterns:, update: true, write: true, verbose: true) ⇒ FormatStaged
constructor
A new instance of FormatStaged.
- #object_is_empty(hash) ⇒ Object
- #patch_working_file(file, new_hash) ⇒ Object
- #pipe_command(*args, source: nil) ⇒ Object
- #replace_file_in_index(file, new_hash) ⇒ Object
- #run ⇒ Object
Constructor Details
#initialize(formatter:, patterns:, update: true, write: true, verbose: true) ⇒ FormatStaged
Returns a new instance of FormatStaged.
9 10 11 12 13 14 15 |
# File 'lib/format-staged.rb', line 9 def initialize(formatter:, patterns:, update: true, write: true, verbose: true) @formatter = formatter @patterns = patterns @update = update @write = write @verbose = verbose end |
Instance Attribute Details
#formatter ⇒ Object (readonly)
Returns the value of attribute formatter.
7 8 9 |
# File 'lib/format-staged.rb', line 7 def formatter @formatter end |
#patterns ⇒ Object (readonly)
Returns the value of attribute patterns.
7 8 9 |
# File 'lib/format-staged.rb', line 7 def patterns @patterns end |
#update ⇒ Object (readonly)
Returns the value of attribute update.
7 8 9 |
# File 'lib/format-staged.rb', line 7 def update @update end |
#verbose ⇒ Object (readonly)
Returns the value of attribute verbose.
7 8 9 |
# File 'lib/format-staged.rb', line 7 def verbose @verbose end |
#write ⇒ Object (readonly)
Returns the value of attribute write.
7 8 9 |
# File 'lib/format-staged.rb', line 7 def write @write end |
Instance Method Details
#format_file(file) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/format-staged.rb', line 30 def format_file(file) new_hash = format_object file return true if not write if new_hash == file.dst_hash puts "Unchanged #{file.src_path}" return false end if object_is_empty new_hash puts "Skipping #{file.src_path}, formatted file is empty" return false end replace_file_in_index file, new_hash if update begin patch_working_file file, new_hash rescue => error puts "Warning: failed updating #{file.src_path} in working copy: #{error}" end end true end |
#format_object(file) ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/format-staged.rb', line 58 def format_object(file) puts "Formatting #{file.src_path}" format_command = formatter.sub("{}", file.src_path.shellescape) pid1, r = pipe_command "git", "cat-file", "-p", file.dst_hash pid2, r = pipe_command format_command, source: r pid3, r = pipe_command "git", "hash-object", "-w", "--stdin", source: r result = r.readlines.map { |it| it.chomp } if @verbose result.each do |line| puts "< #{line}" end end Process.wait pid1 raise "Cannot read #{file.dst_hash} from object database" unless $?.success? Process.wait pid2 raise "Error formatting #{file.src_path}" unless $?.success? Process.wait pid3 raise "Error writing formatted file back to object database" unless $?.success? && !result.empty? result.first end |
#get_output(*args, lines: true) ⇒ Object
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/format-staged/io.rb', line 2 def get_output(*args, lines: true) puts '> ' + args.join(' ') if @verbose output = IO.popen(args, err: :err) do |io| if lines io.readlines.map { |l| l.chomp } else io.read end end if @verbose and lines output.each do |line| puts "< #{line}" end end raise "Failed to run command" unless $?.success? output end |
#object_is_empty(hash) ⇒ Object
86 87 88 89 |
# File 'lib/format-staged.rb', line 86 def object_is_empty(hash) size = get_output("git", "cat-file", "-s", hash).first.to_i size == 0 end |
#patch_working_file(file, new_hash) ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/format-staged.rb', line 91 def patch_working_file(file, new_hash) patch = get_output "git", "diff", file.dst_hash, new_hash, lines: false patch.gsub! "a/#{file.dst_hash}", "a/#{file.src_path}" patch.gsub! "b/#{new_hash}", "b/#{file.src_path}" input, patch_out = IO.pipe pid, r = pipe_command "git", "apply", "-", source: input patch_out.write patch patch_out.close Process.wait pid raise "Error applying patch" unless $?.success? end |
#pipe_command(*args, source: nil) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/format-staged/io.rb', line 24 def pipe_command(*args, source: nil) puts (source.nil? ? '> ' : '| ') + args.join(' ') if @verbose r, w = IO.pipe opts = {} opts[:in] = source unless source.nil? opts[:out] = w opts[:err] = :err pid = spawn(*args, **opts) w.close source &.close return [pid, r] end |
#replace_file_in_index(file, new_hash) ⇒ Object
106 107 108 |
# File 'lib/format-staged.rb', line 106 def replace_file_in_index(file, new_hash) get_output "git", "update-index", "--cacheinfo", "#{file.dst_mode},#{new_hash},#{file.src_path}" end |
#run ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/format-staged.rb', line 17 def run() root = get_output('git', 'rev-parse', '--show-toplevel').first files = get_output('git', 'diff-index', '--cached', '--diff-filter=AM', '--no-renames', 'HEAD') .map { |line| Entry.new(line, root: root) } .reject { |entry| entry.symlink? } .filter { |entry| entry.matches?(@patterns) } files.each do |file| format_file(file) end end |