Skip to content

Instantly share code, notes, and snippets.

@bibstha
Created April 7, 2019 22:00
Show Gist options
  • Save bibstha/72fedb9bf4dd204ade4cd2da2e46b9db to your computer and use it in GitHub Desktop.
Save bibstha/72fedb9bf4dd204ade4cd2da2e46b9db to your computer and use it in GitHub Desktop.
Multiprocess threaded ctags generation with ripper-tags
#!/usr/bin/env ruby
require 'etc'
require 'shell'
def ruby_files
@ruby_files ||= %x{git ls-files | grep 'rb$'}.lines.map!(&:chomp)
end
dir = %x{git rev-parse --git-dir}.chomp
processors = Etc.nprocessors
puts "Number of processors: #{processors}"
total_processes = [processors.size, ruby_files.size].min
files_per_process = (ruby_files.size.to_f / total_processes).ceil.to_i
files_split = ruby_files.each_slice(files_per_process).to_a
threads = total_processes.times.map do |i|
Thread.new do
puts "Process #{i}"
tag_file = "#{dir}/#{i}.tags"
sh = Shell.new
sh.debug = false
sh.transact do
echo(files_split[i].join("\n")) |
system("ripper-tags --exclude \"vendor\" --tag-relative -L - -f#{tag_file}")
end
end
end
threads.each(&:join)
# Merge and sort
abs_dir = File.absolute_path(dir)
src_tag_files = total_processes.times.map { |i| "#{abs_dir}/#{i}.tags" }
dst_tag_file = "#{abs_dir}/tags"
command = "cat #{src_tag_files.join(' ')} | sort -u > #{dst_tag_file}"
sh = Shell.new
sh.transact do
sh.system(command)
end
# Cleanup
src_tag_files.each { |f| File.unlink(f) }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment