| 31 | | EXT = "ferret_ext.so" |
| 32 | | EXT_SRC = FileList["../c/src/*.[c]", "../c/include/*.h", |
| 33 | | "../c/lib/libstemmer_c/src_c/*.[ch]", |
| 34 | | "../c/lib/libstemmer_c/runtime/*.[ch]", |
| 35 | | "../c/lib/libstemmer_c/libstemmer/*.[ch]", |
| 36 | | "../c/lib/libstemmer_c/include/libstemmer.h"] |
| 37 | | EXT_SRC.exclude('../**/ind.[ch]') |
| 38 | | |
| 39 | | EXT_SRC_DEST = EXT_SRC.map {|fn| File.join("ext", File.basename(fn))} |
| 40 | | SRC = (FileList["ext/*.[ch]"] + EXT_SRC_DEST).uniq |
| 41 | | |
| 42 | | CLEAN.include(FileList['**/*.o', '**/*.obj', 'InstalledFiles', |
| 43 | | '.config', 'ext/cferret.c']) |
| 44 | | CLOBBER.include(FileList['ext/*.so'], 'ext/Makefile', EXT_SRC_DEST) |
| 45 | | POLISH = Rake::FileList.new.include(FileList['**/*.so'], 'ext/Makefile') |
| 46 | | |
| 47 | | desc "Clean specifically for the release." |
| 48 | | task :polish => [:clean] do |
| 49 | | POLISH.each { |fn| rm_r fn rescue nil } |
| 50 | | end |
| 51 | | |
| 52 | | desc "Run tests with Valgrind" |
| 53 | | task :valgrind do |
| 54 | | sh "valgrind --gen-suppressions=yes --suppressions=ferret_valgrind.supp " + |
| 55 | | "--leak-check=yes --show-reachable=yes -v ruby test/test_all.rb" |
| 56 | | #sh "valgrind --suppressions=ferret_valgrind.supp " + |
| 57 | | # "--leak-check=yes --show-reachable=yes -v ruby test/unit/index/tc_index_reader.rb" |
| 58 | | #valgrind --gen-suppressions=yes --suppressions=ferret_valgrind.supp --leak-check=yes --show-reachable=yes -v ruby test/test_all.rb |
| 59 | | end |
| 60 | | |
| 61 | | task :default => :test_all |
| 62 | | #task :default => :ext do |
| | 15 | def prompt(msg) |
| | 16 | STDERR.print "#{msg} [Yna]: " |
| | 17 | while true |
| | 18 | case STDIN.gets.chomp! |
| | 19 | when /^(y(es)?)?$/i: return true |
| | 20 | when /^no?$/i: return false |
| | 21 | when /^a(bort)?$/i: fail('aborted') |
| | 22 | else |
| | 23 | STDERR.print "Sorry, I don't understand. Please type y, n or a: " |
| | 24 | end |
| | 25 | end |
| | 26 | end |
| | 27 | |
| | 28 | windows = (RUBY_PLATFORM =~ /win/) rescue nil |
| | 29 | SUDO = windows ? "" : "sudo " |
| | 30 | |
| | 31 | |
| | 32 | task :default => 'test:unit' |
| | 33 | #task :default => :build do |
| 66 | | desc "Run all tests" |
| 67 | | task :test_all => [ :test_units ] |
| | 37 | BZLIB_SRC = FileList["../c/lib/bzlib/*.h"] + |
| | 38 | FileList["../c/lib/bzlib/*.c"].map do |fn| |
| | 39 | fn.gsub(%r{/([^/]*.c)}, '/BZ_\1') |
| | 40 | end |
| | 41 | ############################################################################## |
| | 42 | # Building |
| | 43 | ############################################################################## |
| | 44 | |
| | 45 | task :build => 'build:compile' |
| | 46 | namespace :build do |
| | 47 | EXT = "ferret_ext.so" |
| | 48 | # Note: libstemmer.[h] is necessary so that the file isn't included when it |
| | 49 | # doesn't exist. It needs to have one regular expression element. |
| | 50 | EXT_SRC = FileList["../c/src/*.[ch]", "../c/include/*.h", |
| | 51 | "../c/lib/bzlib/*.[ch]", |
| | 52 | "../c/lib/libstemmer_c/src_c/*.[ch]", |
| | 53 | "../c/lib/libstemmer_c/runtime/*.[ch]", |
| | 54 | "../c/lib/libstemmer_c/libstemmer/*.[ch]", |
| | 55 | "../c/lib/libstemmer_c/include/libstemmer.[h]"] |
| | 56 | EXT_SRC.exclude('../c/**/ind.[ch]', |
| | 57 | '../c/**/symbol.[ch]', |
| | 58 | '../c/include/threading.h', |
| | 59 | '../c/include/scanner.h', |
| | 60 | '../c/include/internal.h', |
| | 61 | '../c/src/lang.c', |
| | 62 | '../c/include/lang.h') |
| | 63 | |
| | 64 | EXT_SRC_MAP = {} |
| | 65 | EXT_SRC_DEST = EXT_SRC.map do |fn| |
| | 66 | ext_fn = File.join("ext", File.basename(fn)) |
| | 67 | if fn =~ /.c$/ and fn =~ /(bzlib|stemmer)/ |
| | 68 | prefix = $1.upcase |
| | 69 | ext_fn.gsub!(/ext\//, "ext/#{prefix}_") |
| | 70 | end |
| | 71 | EXT_SRC_MAP[fn] = ext_fn |
| | 72 | end |
| | 73 | SRC = FileList["ext/*.[ch]", EXT_SRC_DEST, 'ext/internal.h'].uniq |
| | 74 | |
| | 75 | CLEAN.include ['**/*.o', '**/*.obj', '.config', 'ext/cferret.c'] |
| | 76 | CLOBBER.include ['doc/api', 'ext/*.so', 'ext/Makefile', |
| | 77 | 'ext/internal.h', EXT_SRC_DEST] |
| | 78 | |
| | 79 | # The following block creates file tasks for all of the c files. They |
| | 80 | # belong in the ../c directory in source the working copy and they need |
| | 81 | # to be linked to in the ext directory |
| | 82 | EXT_SRC.each do |fn| |
| | 83 | dest_fn = EXT_SRC_MAP[fn] |
| | 84 | # prepend lib files to avoid conflicts |
| | 85 | file dest_fn => fn do |t| |
| | 86 | ln fn, dest_fn |
| | 87 | |
| | 88 | if fn =~ /stemmer/ |
| | 89 | # flatten the directory structure for lib_stemmer |
| | 90 | open(dest_fn) do |in_f| |
| | 91 | open(dest_fn + ".out", "w") do |out_f| |
| | 92 | in_f.each do |line| |
| | 93 | out_f.write(line.sub(/(#include ["<])[.a-z_\/]*\//, '\1')) |
| | 94 | end |
| | 95 | end |
| | 96 | end |
| | 97 | mv dest_fn + ".out", dest_fn |
| | 98 | end |
| | 99 | end |
| | 100 | end if File.exists?("../c") |
| | 101 | |
| | 102 | file 'ext/internal.h' => '../c/include/internal.h' do |
| | 103 | File.open('ext/internal.h', 'w') do |f| |
| | 104 | File.readlines('../c/include/internal.h').each do |l| |
| | 105 | next if l =~ /ALLOC/ and l !~ /ZERO|MP_/ |
| | 106 | f.puts(l) |
| | 107 | end |
| | 108 | end |
| | 109 | end |
| | 110 | |
| | 111 | desc "Build the extension (ferret_ext.so). You'll need a C compiler and Make." |
| | 112 | task :compile => ["ext/#{EXT}"] + SRC |
| | 113 | |
| | 114 | file "ext/#{EXT}" => "ext/Makefile" do |
| | 115 | cd "ext" |
| | 116 | if windows and ENV['make'].nil? |
| | 117 | begin |
| | 118 | sh "nmake" |
| | 119 | rescue Exception => e |
| | 120 | path = ':\Program Files\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT' |
| | 121 | if File.exists? "f#{path}" |
| | 122 | sh "f#{path}" |
| | 123 | elsif File.exists? "c#{path}" |
| | 124 | sh "c#{path}" |
| | 125 | else |
| | 126 | say |
| | 127 | say "***************************************************************" |
| | 128 | say "You need to have Visual C++ 6 to build Ferret on Windows." |
| | 129 | say "If you have it installed, you may need to run;" |
| | 130 | say ' C:\Program Files\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT' |
| | 131 | say "***************************************************************" |
| | 132 | say |
| | 133 | raise e |
| | 134 | end |
| | 135 | sh "nmake" |
| | 136 | end |
| | 137 | else |
| | 138 | sh "make" |
| | 139 | end |
| | 140 | cd ".." |
| | 141 | end |
| | 142 | |
| | 143 | file "ext/Makefile" => SRC do |
| | 144 | cd "ext" |
| | 145 | `ruby extconf.rb` |
| | 146 | cd ".." |
| | 147 | end |
| | 148 | end |
| | 149 | |
| | 150 | ############################################################################## |
| | 151 | # Testing |
| | 152 | ############################################################################## |
| | 153 | |
| | 154 | task :test => 'test:units' |
| | 155 | namespace :test do |
| | 156 | desc "Run tests with Valgrind" |
| | 157 | task :valgrind do |
| | 158 | sh "valgrind --suppressions=ferret_valgrind.supp " + |
| | 159 | "--leak-check=yes --show-reachable=yes " + |
| | 160 | "-v ruby test/unit/index/tc_index_reader.rb" |
| | 161 | end |
| | 162 | |
| | 163 | desc "Run all tests" |
| | 164 | task :all => [ :units ] |
| | 165 | |
| | 166 | desc "run unit tests in test/unit" |
| | 167 | Rake::TestTask.new("units" => :build) do |t| |
| | 168 | t.libs << "test/unit" |
| | 169 | t.pattern = 'test/unit/t[cs]_*.rb' |
| | 170 | t.verbose = true |
| | 171 | end |
| | 172 | task :unit => :units |
| | 173 | |
| | 174 | desc "run tests using locally installed gem" |
| | 175 | Rake::TestTask.new("installed") do |t| |
| | 176 | t.libs << "test/unit" |
| | 177 | t.ruby_opts << '-rtest/test_installed' |
| | 178 | t.pattern = 'test/unit/t[cs]_*.rb' |
| | 179 | t.verbose = true |
| | 180 | end |
| | 181 | end |
| | 182 | |
| | 183 | ############################################################################## |
| | 184 | # Documentation |
| | 185 | ############################################################################## |
| 70 | | task :doc => [ :appdoc ] |
| 71 | | |
| 72 | | desc "run unit tests in test/unit" |
| 73 | | Rake::TestTask.new("test_units" => :ext) do |t| |
| 74 | | t.libs << "test/unit" |
| 75 | | t.pattern = 'test/unit/t[cs]_*.rb' |
| 76 | | #t.pattern = 'test/unit/search/tc_index_searcher.rb' |
| 77 | | t.verbose = true |
| 78 | | end |
| 79 | | |
| 80 | | desc "Generate documentation for the application" |
| 81 | | rd = Rake::RDocTask.new("appdoc") do |rdoc| |
| 82 | | rdoc.rdoc_dir = 'doc/api' |
| 83 | | rdoc.title = "Ferret Search Library Documentation" |
| 84 | | rdoc.options << '--line-numbers' |
| 85 | | rdoc.options << '--inline-source' |
| 86 | | rdoc.options << '--charset=utf-8' |
| 87 | | rdoc.rdoc_files.include('README') |
| 88 | | rdoc.rdoc_files.include('TODO') |
| 89 | | rdoc.rdoc_files.include('TUTORIAL') |
| 90 | | rdoc.rdoc_files.include('MIT-LICENSE') |
| 91 | | rdoc.rdoc_files.include('lib/**/*.rb') |
| 92 | | rdoc.rdoc_files.include('ext/r_*.c') |
| 93 | | rdoc.rdoc_files.include('ext/ferret.c') |
| 94 | | end |
| 95 | | |
| 96 | | EXT_SRC.each do |fn| |
| 97 | | dest_fn = File.join("ext", File.basename(fn)) |
| 98 | | file dest_fn => fn do |t| |
| 99 | | begin |
| 100 | | raise "copy for release" if ENV["REL"] |
| 101 | | ln_s File.join("..", fn), dest_fn |
| 102 | | rescue Exception => e |
| 103 | | cp File.expand_path(fn), dest_fn |
| 104 | | end |
| 105 | | |
| 106 | | if fn =~ /stemmer/ |
| 107 | | # flatten the directory structure for lib_stemmer |
| 108 | | open(dest_fn) do |in_f| |
| 109 | | open(dest_fn + ".out", "w") do |out_f| |
| 110 | | in_f.each {|line| out_f.write(line.sub(/(#include ["<])[.a-z_\/]*\//) {"#{$1}"})} |
| 111 | | end |
| 112 | | end |
| 113 | | mv dest_fn + ".out", dest_fn |
| 114 | | end |
| 115 | | end |
| 116 | | end if File.exists?("../c") |
| 117 | | |
| 118 | | desc "Build the extension" |
| 119 | | task :ext => ["ext/#{EXT}"] + SRC do |
| 120 | | rm_f 'ext/mem_pool.*' |
| 121 | | rm_f 'ext/defines.h' |
| 122 | | end |
| 123 | | |
| 124 | | file "ext/#{EXT}" => ["ext/Makefile"] do |
| 125 | | cp "ext/inc/lang.h", "ext/lang.h" |
| 126 | | cp "ext/inc/threading.h", "ext/threading.h" |
| 127 | | cd "ext" |
| 128 | | if (/mswin/ =~ RUBY_PLATFORM) and ENV['make'].nil? |
| 129 | | begin |
| 130 | | sh "nmake" |
| 131 | | rescue Exception => e |
| 132 | | puts |
| 133 | | puts "**********************************************************************" |
| 134 | | puts "You may need to call VCVARS32.BAT to set the environment variables." |
| 135 | | puts ' "f:\Program Files\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT"' |
| 136 | | puts "**********************************************************************" |
| 137 | | puts |
| 138 | | raise e |
| 139 | | end |
| 140 | | else |
| 141 | | sh "make" |
| 142 | | end |
| 143 | | cd ".." |
| 144 | | end |
| 145 | | |
| 146 | | file "ext/lang.h" => ["ext/inc/lang.h"] do |
| 147 | | rm_f "ext/lang.h" |
| 148 | | cp "ext/inc/lang.h", "ext/lang.h" |
| 149 | | end |
| 150 | | |
| 151 | | file "ext/threading.h" => ["ext/inc/threading.h"] do |
| 152 | | rm_f "ext/threading.h" |
| 153 | | cp "ext/inc/threading.h", "ext/threading.h" |
| 154 | | end |
| 155 | | |
| 156 | | file "ext/Makefile" => SRC do |
| 157 | | cd "ext" |
| 158 | | `ruby extconf.rb` |
| 159 | | cd ".." |
| 160 | | end |
| 161 | | |
| 162 | | # Make Parsers --------------------------------------------------------------- |
| 163 | | |
| 164 | | RACC_SRC = FileList["lib/**/*.y"] |
| 165 | | RACC_OUT = RACC_SRC.collect { |fn| fn.sub(/\.y$/, '.tab.rb') } |
| 166 | | |
| 167 | | task :parsers => RACC_OUT |
| 168 | | rule(/\.tab\.rb$/ => [proc {|tn| tn.sub(/\.tab\.rb$/, '.y')}]) do |t| |
| 169 | | sh "racc #{t.source}" |
| 170 | | end |
| 171 | | |
| 172 | | # Create Packages ------------------------------------------------------------ |
| | 188 | task :doc => 'doc:rdoc' |
| | 189 | namespace :doc do |
| | 190 | if allison = Gem.cache.search('allison').last |
| | 191 | allison_template = File.join(allison.full_gem_path, 'lib/allison.rb') |
| | 192 | end |
| | 193 | desc "Generate documentation for the application" |
| | 194 | $rd = Rake::RDocTask.new do |rdoc| |
| | 195 | rdoc.rdoc_dir = 'doc/api' |
| | 196 | rdoc.title = "Ferret Search Library Documentation" |
| | 197 | rdoc.options << '--line-numbers' |
| | 198 | rdoc.options << '--inline-source' |
| | 199 | rdoc.options << '--charset=utf-8' |
| | 200 | rdoc.template = allison_template if allison_template |
| | 201 | rdoc.rdoc_files.include('README') |
| | 202 | rdoc.rdoc_files.include('TODO') |
| | 203 | rdoc.rdoc_files.include('TUTORIAL') |
| | 204 | rdoc.rdoc_files.include('MIT-LICENSE') |
| | 205 | rdoc.rdoc_files.include('lib/**/*.rb') |
| | 206 | rdoc.rdoc_files.include('ext/r_*.c') |
| | 207 | rdoc.rdoc_files.include('ext/ferret.c') |
| | 208 | end |
| | 209 | |
| | 210 | desc "Look for TODO and FIXME tags in the code" |
| | 211 | task :todo do |
| | 212 | FileList['**/*.rb', 'ext/*.[ch]'].egrep /[#*].*(FIXME|TODO|TBD)/i |
| | 213 | end |
| | 214 | end |
| | 215 | |
| | 216 | ############################################################################## |
| | 217 | # Packaging and Installing |
| | 218 | ############################################################################## |
| 187 | | PKG_FILES.exclude('**/*.o') |
| 188 | | PKG_FILES.exclude('**/Makefile') |
| 189 | | PKG_FILES.exclude('ext/ferret_ext.so') |
| 190 | | |
| 191 | | |
| 192 | | if ! defined?(Gem) |
| 193 | | puts "Package Target requires RubyGEMs" |
| 194 | | else |
| 195 | | spec = Gem::Specification.new do |s| |
| 196 | | |
| 197 | | #### Basic information. |
| 198 | | s.name = 'ferret' |
| 199 | | s.version = PKG_VERSION |
| 200 | | s.summary = "Ruby indexing library." |
| 201 | | s.description = <<-EOF |
| 202 | | Ferret is a port of the Java Lucene project. It is a powerful |
| 203 | | indexing and search library. |
| | 233 | |
| | 234 | spec = Gem::Specification.new do |s| |
| | 235 | |
| | 236 | #### Basic information. |
| | 237 | s.name = 'ferret' |
| | 238 | s.version = Ferret::VERSION |
| | 239 | s.summary = "Ruby indexing library." |
| | 240 | s.description = "Ferret is a super fast, highly configurable search library." |
| | 241 | |
| | 242 | #### Dependencies and requirements. |
| | 243 | s.add_dependency('rake') |
| | 244 | s.files = PKG_FILES.to_a |
| | 245 | s.extensions << "ext/extconf.rb" |
| | 246 | s.require_path = 'lib' |
| | 247 | s.bindir = 'bin' |
| | 248 | s.executables = ['ferret-browser'] |
| | 249 | s.default_executable = 'ferret-browser' |
| | 250 | |
| | 251 | #### Author and project details. |
| | 252 | s.author = "David Balmain" |
| | 253 | s.email = "dbalmain@gmail.com" |
| | 254 | s.homepage = "http://ferret.davebalmain.com/trac" |
| | 255 | s.rubyforge_project = "ferret" |
| | 256 | |
| | 257 | s.has_rdoc = true |
| | 258 | s.extra_rdoc_files = $rd.rdoc_files.reject { |fn| fn =~ /\.rb$/ }.to_a |
| | 259 | s.rdoc_options << |
| | 260 | '--title' << 'Ferret -- Ruby Search Library' << |
| | 261 | '--main' << 'README' << '--line-numbers' << |
| | 262 | 'TUTORIAL' << 'TODO' |
| | 263 | |
| | 264 | key_file = File.expand_path('~/.gem/gem-private_key.pem') |
| | 265 | key_file = nil unless File.exists?(key_file) |
| | 266 | cert_file = File.expand_path('~/.gem/gem-public_cert.pem') |
| | 267 | cert_file = nil unless File.exists?(cert_file) |
| | 268 | if key_file and cert_file |
| | 269 | s.signing_key = key_file |
| | 270 | s.cert_chain = cert_file |
| | 271 | end |
| | 272 | |
| | 273 | if windows |
| | 274 | s.files = PKG_FILES.to_a + ["ext/#{EXT}"] |
| | 275 | s.extensions.clear |
| | 276 | s.platform = Gem::Platform::WIN32 |
| | 277 | else |
| | 278 | s.platform = Gem::Platform::RUBY |
| | 279 | end |
| | 280 | end |
| | 281 | |
| | 282 | package_task = Rake::GemPackageTask.new(spec) do |pkg| |
| | 283 | unless windows |
| | 284 | pkg.need_zip = true |
| | 285 | pkg.need_tar = true |
| | 286 | end |
| | 287 | end |
| | 288 | |
| | 289 | desc "Run :gem and install the resulting gem" |
| | 290 | task :install => :gem do |
| | 291 | sh "#{SUDO}gem install pkg/ferret-#{Ferret::VERSION}.gem --no-rdoc --no-ri -l" |
| | 292 | end |
| | 293 | |
| | 294 | desc "Run :clobber and uninstall the .gem" |
| | 295 | task :uninstall => :clobber do |
| | 296 | sh "#{SUDO}gem uninstall ferret" |
| | 297 | end |
| | 298 | |
| | 299 | desc "Same as :install but you must be rootgem" |
| | 300 | task :root_install => :gem do |
| | 301 | sh "gem install pkg/ferret-#{Ferret::VERSION}.gem --no-rdoc --no-ri -l" |
| | 302 | end |
| | 303 | |
| | 304 | desc "Same as :uninstall but you must be root" |
| | 305 | task :root_uninstall => :clobber do |
| | 306 | sh "gem uninstall ferret" |
| | 307 | end |
| | 308 | |
| | 309 | def list_changes_since_last_release |
| | 310 | tag_listing = `svn list svn://davebalmain.com/ferret/tags` |
| | 311 | last_tag = tag_listing.split("\n").last |
| | 312 | log = `svn log --stop-on-copy svn://davebalmain.com/ferret/tags/#{last_tag}` |
| | 313 | first_log = log.split(/-------+/)[-2] |
| | 314 | last_revision = /^r(\d+)\s+\|/.match(first_log)[1] |
| | 315 | `svn log .. -rHEAD:#{last_revision}` |
| | 316 | end |
| | 317 | |
| | 318 | desc "List changes since last release" |
| | 319 | task :changes do |
| | 320 | puts list_changes_since_last_release |
| | 321 | end |
| | 322 | |
| | 323 | if ENV['FERRET_DEV'] |
| | 324 | ############################################################################## |
| | 325 | # Releasing |
| | 326 | ############################################################################## |
| | 327 | |
| | 328 | desc "Generate and upload a new release" |
| | 329 | task :release => 'release:release' |
| | 330 | namespace :release do |
| | 331 | task :release => [:status_check, 'test:all', :package, :tag] do |
| | 332 | say |
| | 333 | say "**************************************************************" |
| | 334 | say "* Release #{Ferret::VERSION} Complete." |
| | 335 | say "* Packages ready to upload." |
| | 336 | say "**************************************************************" |
| | 337 | say |
| | 338 | reversion("lib/ferret/version.rb") |
| | 339 | end |
| | 340 | |
| | 341 | # Validate that everything is ready to go for a release. |
| | 342 | task :status_check do |
| | 343 | # Are all source files checked in? |
| | 344 | unless `svn -q --ignore-externals status` =~ /^$/ |
| | 345 | fail "'svn -q status' is not clean ... do you have unchecked-in files?" |
| | 346 | end |
| | 347 | |
| | 348 | say "No outstanding checkins found ... OK" |
| | 349 | end |
| | 350 | |
| | 351 | def reversion(fn) |
| | 352 | new_version = nil |
| | 353 | begin |
| | 354 | print "Ferret is currently at #{Ferret::VERSION}. What version now? " |
| | 355 | new_version = STDIN.gets.chomp! |
| | 356 | end until prompt("Change to version #{new_version}?") |
| | 357 | |
| | 358 | if ENV['RELTEST'] |
| | 359 | say "Would change the version in lib/ferret/version.rb from" |
| | 360 | say " #{Ferret::VERSION} => #{new_version}" |
| | 361 | say "and then commit the changes with the command" |
| | 362 | say " svn ci -m \"Updated to version #{new_version}\" " + |
| | 363 | "lib/ferret/version.rb" |
| | 364 | else |
| | 365 | open(fn) do |ferret_in| |
| | 366 | open(fn + ".new", "w") do |ferret_out| |
| | 367 | ferret_in.each do |line| |
| | 368 | if line =~ /^ VERSION\s*=\s*/ |
| | 369 | ferret_out.puts " VERSION = '#{new_version}'" |
| | 370 | else |
| | 371 | ferret_out.puts line |
| | 372 | end |
| | 373 | end |
| | 374 | end |
| | 375 | end |
| | 376 | mv fn + ".new", fn |
| | 377 | sh %{svn ci -m "Updated to version #{new_version}" lib/ferret/version.rb} |
| | 378 | end |
| | 379 | end |
| | 380 | |
| | 381 | # Tag all the SVN files with the latest release number |
| | 382 | task :tag => :status_check do |
| | 383 | reltag = "REL-#{Ferret::VERSION}" |
| | 384 | say "Tagging SVN with [#{reltag}]" |
| | 385 | if ENV['RELTEST'] |
| | 386 | say "Release Task Testing, skipping SVN tagging. Would do;" |
| | 387 | say %{svn copy -m "creating release #{reltag}" svn://www.davebalmain.com/ferret/trunk svn://www.davebalmain.com/ferret/tags/#{reltag}} |
| | 388 | else |
| | 389 | sh %{svn copy -m "creating release #{reltag}" svn://www.davebalmain.com/ferret/trunk svn://www.davebalmain.com/ferret/tags/#{reltag}} |
| | 390 | end |
| | 391 | end |
| | 392 | |
| | 393 | end |
| | 394 | |
| | 395 | ############################################################################## |
| | 396 | # Publishing |
| | 397 | ############################################################################## |
| | 398 | |
| | 399 | namespace :publish do |
| | 400 | PUBLISH_PROMPT = <<-EOF |
| | 401 | Make sure you updated RELEASE_NOTES and RELEASE_CHANGES and that the |
| | 402 | package exists. Are you sure you want to continue? |
| 205 | | |
| 206 | | #### Dependencies and requirements. |
| 207 | | s.add_dependency('rake') |
| 208 | | s.files = PKG_FILES.to_a |
| 209 | | s.extensions << "ext/extconf.rb" |
| 210 | | s.require_path = 'lib' |
| 211 | | s.autorequire = 'ferret' |
| 212 | | s.bindir = 'bin' |
| 213 | | s.executables = ['ferret-browser'] |
| 214 | | s.default_executable = 'ferret-browser' |
| 215 | | |
| 216 | | #### Author and project details. |
| 217 | | s.author = "David Balmain" |
| 218 | | s.email = "dbalmain@gmail.com" |
| 219 | | s.homepage = "http://ferret.davebalmain.com/trac" |
| 220 | | s.rubyforge_project = "ferret" |
| 221 | | |
| 222 | | s.has_rdoc = true |
| 223 | | s.extra_rdoc_files = rd.rdoc_files.reject { |fn| fn =~ /\.rb$/ }.to_a |
| 224 | | s.rdoc_options << |
| 225 | | '--title' << 'Ferret -- Ruby Indexer' << |
| 226 | | '--main' << 'README' << '--line-numbers' << |
| 227 | | 'TUTORIAL' << 'TODO' |
| 228 | | |
| 229 | | if RUBY_PLATFORM =~ /mswin/ |
| 230 | | s.files = PKG_FILES.to_a + ["ext/#{EXT}"] |
| 231 | | s.extensions.clear |
| 232 | | s.platform = Gem::Platform::WIN32 |
| 233 | | end |
| 234 | | end |
| 235 | | |
| 236 | | package_task = Rake::GemPackageTask.new(spec) do |pkg| |
| 237 | | unless RUBY_PLATFORM =~ /mswin/ |
| 238 | | pkg.need_zip = true |
| 239 | | pkg.need_tar = true |
| 240 | | end |
| 241 | | end |
| 242 | | end |
| 243 | | |
| 244 | | # Support Tasks ------------------------------------------------------ |
| 245 | | |
| 246 | | desc "Look for TODO and FIXME tags in the code" |
| 247 | | task :todo do |
| 248 | | FileList['**/*.rb'].egrep /#.*(FIXME|TODO|TBD)/ |
| 249 | | end |
| 250 | | # -------------------------------------------------------------------- |
| 251 | | # Creating a release |
| 252 | | |
| 253 | | desc "Make a new release" |
| 254 | | task :release => [ |
| 255 | | :prerelease, |
| 256 | | :polish, |
| 257 | | :test_all, |
| 258 | | :update_version, |
| 259 | | :package, |
| 260 | | :tag] do |
| 261 | | announce |
| 262 | | announce "**************************************************************" |
| 263 | | announce "* Release #{PKG_VERSION} Complete." |
| 264 | | announce "* Packages ready to upload." |
| 265 | | announce "**************************************************************" |
| 266 | | announce |
| 267 | | end |
| 268 | | |
| 269 | | # Validate that everything is ready to go for a release. |
| 270 | | task :prerelease do |
| 271 | | announce |
| 272 | | announce "**************************************************************" |
| 273 | | announce "* Making RubyGem Release #{PKG_VERSION}" |
| 274 | | announce "* (current version #{CURRENT_VERSION})" |
| 275 | | announce "**************************************************************" |
| 276 | | announce |
| 277 | | |
| 278 | | # Is a release number supplied? |
| 279 | | unless ENV['REL'] |
| 280 | | fail "Usage: rake release REL=x.y.z [REUSE=tag_suffix]" |
| 281 | | end |
| 282 | | |
| 283 | | # Is the release different than the current release. |
| 284 | | # (or is REUSE set?) |
| 285 | | if PKG_VERSION == CURRENT_VERSION && ! ENV['REUSE'] |
| 286 | | fail "Current version is #{PKG_VERSION}, must specify REUSE=tag_suffix to reuse version" |
| 287 | | end |
| 288 | | |
| 289 | | # Are all source files checked in? |
| 290 | | data = `svn -q --ignore-externals status` |
| 291 | | unless data =~ /^$/ |
| 292 | | fail "'svn -q status' is not clean ... do you have unchecked-in files?" |
| 293 | | end |
| 294 | | |
| 295 | | announce "No outstanding checkins found ... OK" |
| 296 | | end |
| 297 | | |
| 298 | | def reversion(fn) |
| 299 | | open(fn) do |ferret_in| |
| 300 | | open(fn + ".new", "w") do |ferret_out| |
| 301 | | ferret_in.each do |line| |
| 302 | | if line =~ /^ VERSION\s*=\s*/ |
| 303 | | ferret_out.puts " VERSION = '#{PKG_VERSION}'" |
| 304 | | else |
| 305 | | ferret_out.puts line |
| 306 | | end |
| 307 | | end |
| 308 | | end |
| 309 | | end |
| 310 | | mv fn + ".new", fn |
| 311 | | end |
| 312 | | |
| 313 | | task :update_version => [:prerelease] do |
| 314 | | if PKG_VERSION == CURRENT_VERSION |
| 315 | | announce "No version change ... skipping version update" |
| 316 | | else |
| 317 | | announce "Updating Ferret version to #{PKG_VERSION}" |
| 318 | | reversion("lib/ferret_version.rb") |
| 319 | | if ENV['RELTEST'] |
| 320 | | announce "Release Task Testing, skipping commiting of new version" |
| 321 | | else |
| 322 | | sh %{svn ci -m "Updated to version #{PKG_VERSION}" lib/ferret_version.rb} |
| 323 | | end |
| 324 | | end |
| 325 | | end |
| 326 | | |
| 327 | | desc "Tag all the SVN files with the latest release number (REL=x.y.z)" |
| 328 | | task :tag => [:prerelease] do |
| 329 | | reltag = "REL-#{PKG_VERSION}" |
| 330 | | reltag << ENV['REUSE'] if ENV['REUSE'] |
| 331 | | announce "Tagging SVN with [#{reltag}]" |
| 332 | | if ENV['RELTEST'] |
| 333 | | announce "Release Task Testing, skipping SVN tagging. Would do the following;" |
| 334 | | announce %{svn copy -m "creating release #{reltag}" svn://www.davebalmain.com/ferret/trunk svn://www.davebalmain.com/ferret/tags/#{reltag}} |
| 335 | | else |
| 336 | | sh %{svn copy -m "creating release #{reltag}" svn://www.davebalmain.com/ferret/trunk svn://www.davebalmain.com/ferret/tags/#{reltag}} |
| 337 | | end |
| 338 | | end |
| | 404 | desc "Publish gem on rubyforge for download. Will only do the linux version" |
| | 405 | task :release do |
| | 406 | exit unless prompt(PUBLISH_PROMPT) |
| | 407 | require 'rubyforge' |
| | 408 | require 'rake/contrib/rubyforgepublisher' |
| | 409 | version = Ferret::VERSION |
| | 410 | |
| | 411 | packages = %w(gem tgz zip).map {|ext| "pkg/ferret-#{version}.#{ext}"} |
| | 412 | |
| | 413 | rubyforge = RubyForge.new |
| | 414 | rubyforge.login |
| | 415 | rubyforge.add_release('ferret', 'ferret', |
| | 416 | "ferret-#{version}", *packages) |
| | 417 | end |
| | 418 | |
| | 419 | desc "Publish the documentation" |
| | 420 | task :docs => 'doc:rdoc' do |
| | 421 | sh %{rsync -rzv --delete doc/api/ www@davebalmain.com:/var/www/ferret/api} |
| | 422 | end |
| | 423 | |
| | 424 | desc "Publish the documentation and release" |
| | 425 | task :all => [:doc, :release] |
| | 426 | end |
| | 427 | end |
| | 428 | |
| | 429 | |
| | 430 | |
| | 431 | |
| | 432 | # |
| | 433 | # In case I ever need to add another racc parser, here's how |
| | 434 | # |
| | 435 | # # Make Parsers --------------------------------------------------------------- |
| | 436 | # |
| | 437 | # RACC_SRC = FileList["lib/**/*.y"] |
| | 438 | # |
| | 439 | # task :parsers => RACC_OUT |
| | 440 | # rule(/\.tab\.rb$/ => [proc {|tn| tn.sub(/\.tab\.rb$/, '.y')}]) do |t| |
| | 441 | # sh "racc #{t.source}" |
| | 442 | # end |