require "rake" Dir.chdir __dir__ status_file = "ext/inc/status_codes.h" version_file = "ext/inc/version.inc" makefile = "ext/Makefile" extconf = "ext/extconf.rb" desc "code generate" task :gen => [version_file] desc "generate #{status_file}" file status_file => __FILE__ do puts "generating: #{status_file}" require "nokogiri" require "open-uri" f = File.open status_file, 'w' f.puts "#define HTTP_STATUS_CODES(XX)\\" Nokogiri::XML(open("http://www.iana.org/assignments/http-status-codes/http-status-codes.xml")).css("record").each do |r| value = r.css('value').text next if value.index '-' description = r.css('description').text f.puts %Q| XX(#{value}, "#{description}");\\| end f.puts "// end define" f.close end desc "generate #{version_file}" file version_file => ['nyara.gemspec', __FILE__] do puts "generating: #{version_file}" lines = File.readlines('nyara.gemspec') version = nil lines.each do |line| if line =~ /s\.version =/ version = line[/\d+(\.\d+)*(\.pre\d+)?/] break end end abort 'version not found' unless version File.open version_file, 'w' do |f| f.puts %Q{#define NYARA_VERSION "#{version}"} end end desc "generate makefile" file makefile => extconf do Dir.chdir 'ext' do sh 'make clean' if File.exist?('Makefile') sh 'ruby extconf.rb' end end desc "build ext" task :build => makefile do Dir.chdir 'ext' do sh 'make' end end desc "test" task :test => :build do sh 'rspec', '-c' end desc "build and test" task :default => :test desc "build and install gem" task :gem => 'gen' do Dir.glob('*.gem') do |f| sh 'rm', f end sh 'gem', 'build', 'nyara.gemspec' gem_package = Dir.glob('*.gem').first sh 'gem', 'install', '--no-rdoc', '--no-ri', gem_package end desc "clean" task :clean do sh 'rm', '-f', '*.gem' Dir.chdir 'ext' do sh 'make', 'clean' sh 'rm', '-f', 'Makefile' end end # -- utils -- desc "collect line stat" task :lines do rb_c = 0 Dir.glob('**/*.rb') do |f| rb_c += (File.read(f).count "\n") end c_c = 0 Dir.glob('ext/*.{c,cc,h}') do |f| c_c += (File.read(f).count "\n") end spec_c = 0 Dir.glob('spec/**/*.rb') do |f| spec_c += (File.read(f).count "\n") end puts "c: #{c_c} lines" puts "rb: #{rb_c - spec_c} lines" puts "spec: #{spec_c} lines" end desc "list Nyara::Ext methods" task :list_ext do require_relative "lib/nyara/nyara" puts_methods = lambda{|methods| methods.each do |m| puts "#{m} /#{Nyara::Ext.method(m).arity}" end } methods = (Nyara::Ext.methods - Module.methods).sort [/queue/, /route/, /parse/, /request/].each do |r| group = methods.grep r puts_methods[group] puts methods -= group end puts_methods[methods] end def term_color n print "\e[38;5;#{n}m" end def reset_color print "\e[00m" end desc "audit arity of rb_define_method/rb_define_singleton_method" task :audit_arity do Dir.glob 'ext/*.{c,cc}' do |f| puts "validatign #{f}" arities = {} data = File.read f data.scan /^(?:static )?VALUE (\w+)\((.+)\)/ do |func, params| arities[func] = params.count(',') puts " scan: #{func}/#{arities[func]}" end data.scan /rb_define(?:_singleton)?_method\(.*?(\w+)\s*\,\s*(\d+)\)/ do |func, arity| print " check: #{func}/#{arity} " if arities[func].nil? term_color 5 print "UNSCANNED" reset_color puts elsif arities[func] != arity.to_i term_color 9 print "MISMATCH #{arities[func]}" reset_color puts else puts "OK" end end end end desc "audit http_parser / multipart_parser struct size, they should be dividable by 8 so that Request fields are aligned" task :audit_sizeof_parsers do require "mkmf" $CFLAGS << " -Iext/http-parser -Iext/multipart-parser-c" { 'http_parser' => 'http_parser.h', 'multipart_parser*' => 'multipart_parser.h' # multipart_parser is opaque -_- }.each do |struct, header| have_header header res = check_sizeof(struct, header) if res and res % 8 == 0 puts "OK" else term_color 9 print "Need padding" reset_color puts end puts end sh 'rm', 'mkmf.log' end