require 'rubygems' require 'rake/clean' require 'rake/rdoctask' require 'spec/rake/spectask' require 'spec/rake/verify_rcov' require 'rcov' require 'rake/gempackagetask' PKG_VERSION = "0.0.21" for rakefile in Dir['lib/rake/*.rake'] load rakefile end $: << 'lib' # verbose false RUBY = ENV.fetch 'ruby', 'ruby' def ruby command params = if RUBY == 'rbx' '-I/usr/local/lib/ruby/1.8' else '-w' end cmd = "#{RUBY} #{params} #{command}" puts cmd if verbose system cmd end task '19' do RUBY.replace 'ruby19' end task '18' do RUBY.replace 'ruby18' end task '187' do RUBY.replace 'ruby187' end task 'jruby' do RUBY.replace 'jruby' end task 'rubinius' do RUBY.replace 'rbx' end task 'ee' do RUBY.replace 'rubyee' end task 'macruby' do RUBY.replace 'macruby' end spec = Gem::Specification.new do |s| s.name = "AmberVM" s.version = PKG_VERSION s.author = "Heinz N. Gies" s.email = "heinz@licenser.net" s.homepage = "http://code.licenser.net/projects/show/amber" s.platform = Gem::Platform::RUBY s.summary = "A ruby based VM that lets one add secure scripting to ruby applications." s.rubyforge_project = 'rvm' s.files = FileList['lib/amber.rb', 'lib/amber/{.,**}/*', 'bin/*'].to_a s.require_path = "lib" s.test_files = FileList["{spec}/**/*spec.rb"].to_a s.bindir = 'bin' s.has_rdoc = true s.executables = 'ambervm' s.rdoc_options << '--title' << 'Amber VM' << '--main' << 'README' << '--line-numbers' s.extra_rdoc_files = ["README"] end CLEAN.include "doc" CLEAN.include "coverage" CLEAN.include "pkg" #CLEAN.include "benchmarks/*/.history.yaml" Spec::Rake::SpecTask.new do |t| #t.warning = true t.libs << ['lib'] end task :racc_spec => [:racc, :spec] task :default => :racc_spec namespace :spec do desc "Run all specs with rcov and store coverage report in doc/output/coverage" Spec::Rake::SpecTask.new(:rcov) do |t| t.rcov = true t.libs << ['lib'] t.rcov_dir = 'coverage' t.rcov_opts = ['--exclude', 'spec,gems'] end desc "Verify that coverage is 100%" RCov::VerifyTask.new(:verify => :rcov) do |t| t.threshold = 100 end desc "Heckle each module and class in turn" task :heckle => :verify do root_module = "RMush" spec_files = FileList['spec/**/*_spec.rb'] current_module, current_method = nil, nil heckle_caught_modules = Hash.new { |hash, key| hash[key] = [] } unhandled_mutations = 0 IO.popen("spec --heckle #{root_module} #{spec_files}") do |pipe| while line = pipe.gets line = line.chomp if line =~ /^\*\*\* ((?:\w+(?:::)?)+)#(\w+)/ current_module, current_method = $1, $2 elsif line == "The following mutations didn't cause test failures:" heckle_caught_modules[current_module] << current_method elsif line == "+++ mutation" unhandled_mutations += 1 end puts line end end if unhandled_mutations > 0 error_message_lines = ["*************\n"] error_message_lines << "Heckle found #{unhandled_mutations} " + "mutation#{"s" unless unhandled_mutations == 1} " + "that didn't cause spec violations\n" heckle_caught_modules.each do |mod, methods| error_message_lines << "#{mod} contains the following poorly-specified methods:" methods.each do |m| error_message_lines << " - #{m}" end error_message_lines << "" end error_message_lines << "Get your act together and come back " + "when your specs are doing their job!" puts "*************" raise error_message_lines.join("\n") else puts "Well done! Your code withstood a heckling." end end task :autotest do require './spec/rspec_autotest' RspecAutotest.run end end Rake::RDocTask.new do |rd| rd.main = "README" rd.rdoc_dir = "doc" rd.rdoc_files.include("README") rd.rdoc_files.include(Dir['lib/*.rb']) rd.rdoc_files.include(Dir['lib/**/*.rb']) end Rake::GemPackageTask.new(spec) do |pkg| pkg.need_tar = true end task :tgz do `if [ ! -d pkg ]; then mkdir pkg; fi;` `if [ -d pkg/amber ]; then rm -r pkg/amber; fi;` `svn export http://code.licenser.net/rvm/trunk pkg/amber` `cd pkg && tar zcf ambervm-#{PKG_VERSION}.tar.gz amber` end LANGUAGES = Dir["racc/*.y"].map { |f| File.basename(f).chomp(".y") } LANGUAGES.each do |language| # need closure rule "lib/amber/languages/#{language}/compiler.rb" => "racc/#{language}.y" do |t| racc_file = t.prerequisites.first compiler = t.name puts "#{racc_file}..." sh "racc -o#{compiler} #{racc_file}" # This is due to RACC's incompetence. fixed_code = File.read(compiler).sub(/^ module(?= (?i:#{language}))/, ' class') File.open(compiler, 'w') { |f| f.write fixed_code } end end desc 'Compile the compilers with RACC.' task :compilers => LANGUAGES.map { |language| "lib/amber/languages/#{language}/compiler.rb" } task :racc => :compilers # old name desc 'Report code statistics (LOC) from the application' task :stats do require 'rake/helpers/code_statistics' CodeStatistics.new( ['rVM', 'lib'], [' Core', 'lib/amber'], [' Classes', 'lib/amber/classes/**'], [' Functions', 'lib/amber/functions/**'], [' Language definitions', 'racc', /\.y$/], [' Languages, generated', 'lib/amber/languages/{ecma}', /compiler.rb$/, :ignore], [' Languages, handcrafted', 'lib/amber/languages/**'], [' Binaries', 'bin/**'], ['Specs', 'spec'], [' Core specs', 'spec/amber/**'], [' Classes specs', 'spec/classes/**'], [' Languages specs', 'spec/languages/**'] ).print end namespace :benchmark do desc "Performs a benchmark for ECMA" task :ecma => :racc do name = "'" + (ENV['name']||'-').to_s + "'" ruby "-Ilib -rrake/helpers/benchmark -e \"VMBenchmark.go(:ecma, Dir[\'benchmarks/ecma/*.js\'], [\'amber/functions/math\'], #{name})\"" end desc "Performs a benchmark for Fukubukuro" task :ecma_fuku => :racc do name = "'" + (ENV['name']||'-').to_s + "'" ruby "-Ilib -rrake/helpers/benchmark -e \"VMBenchmark.go(:ecma_fuku, Dir[\'benchmarks/ecma/*.js\'], [], #{name})\"" end task :all => [:ecma] end task :release => [:racc, :tgz, :gem]