Rakefile 14.6 KB
Newer Older
D
Initial  
David Heinemeier Hansson 已提交
1 2 3 4 5 6 7
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'
require 'rake/gempackagetask'
require 'rake/contrib/rubyforgepublisher'

require 'date'
8
require 'rbconfig'
D
Initial  
David Heinemeier Hansson 已提交
9

10
require File.join(File.dirname(__FILE__), 'lib', 'rails_version')
11

D
Initial  
David Heinemeier Hansson 已提交
12 13
PKG_BUILD       = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
PKG_NAME        = 'rails'
14
PKG_VERSION     = Rails::Version::STRING + PKG_BUILD
D
Initial  
David Heinemeier Hansson 已提交
15 16 17
PKG_FILE_NAME   = "#{PKG_NAME}-#{PKG_VERSION}"
PKG_DESTINATION = ENV["RAILS_PKG_DESTINATION"] || "../#{PKG_NAME}"

18 19 20 21 22
RELEASE_NAME  = "REL #{PKG_VERSION}"

RUBY_FORGE_PROJECT = "rails"
RUBY_FORGE_USER    = "webster132"

D
David Heinemeier Hansson 已提交
23

24 25 26 27 28
# Rake::TestTask.new("test") do |t|
#   t.libs << 'test'
#   t.pattern = 'test/*_test.rb'
#   t.verbose = true
# end
29 30


31
BASE_DIRS   = %w( app config/environments components db doc log lib lib/tasks public script script/performance script/process test vendor vendor/plugins )
32
APP_DIRS    = %w( apis models controllers helpers services views views/layouts )
33
PUBLIC_DIRS = %w( images javascripts stylesheets )
34
TEST_DIRS   = %w( fixtures unit functional mocks mocks/development mocks/test )
D
David Heinemeier Hansson 已提交
35

36
LOG_FILES    = %w( server.log development.log test.log production.log )
37 38 39
HTML_FILES   = %w( 404.html 500.html index.html robots.txt favicon.ico 
                   javascripts/prototype.js javascripts/scriptaculous.js
                   javascripts/effects.js javascripts/dragdrop.js javascripts/controls.js
40
                   javascripts/slider.js )
41
BIN_FILES    = %w( breakpointer console destroy generate performance/benchmarker performance/profiler process/reaper process/spawner process/spinner runner server lighttpd plugin )
D
David Heinemeier Hansson 已提交
42

43
VENDOR_LIBS = %w( actionpack activerecord actionmailer activesupport actionwebservice railties )
D
David Heinemeier Hansson 已提交
44 45


D
Initial  
David Heinemeier Hansson 已提交
46
desc "Generates a fresh Rails package with documentation"
D
David Heinemeier Hansson 已提交
47
task :fresh_rails => [ :clean, :make_dir_structure, :initialize_file_stubs, :copy_vendor_libraries, :copy_ties_content, :generate_documentation ]
D
Initial  
David Heinemeier Hansson 已提交
48 49

desc "Generates a fresh Rails package using GEMs with documentation"
D
David Heinemeier Hansson 已提交
50
task :fresh_gem_rails => [ :clean, :make_dir_structure, :initialize_file_stubs, :copy_ties_content, :copy_gem_environment ]
D
Initial  
David Heinemeier Hansson 已提交
51 52

desc "Generates a fresh Rails package without documentation (faster)"
D
David Heinemeier Hansson 已提交
53
task :fresh_rails_without_docs => [ :clean, :make_dir_structure, :initialize_file_stubs, :copy_vendor_libraries, :copy_ties_content ]
D
Initial  
David Heinemeier Hansson 已提交
54

55 56 57
desc "Generates a fresh Rails package without documentation (faster)"
task :fresh_rails_without_docs_using_links => [ :clean, :make_dir_structure, :initialize_file_stubs, :link_vendor_libraries, :copy_ties_content ]

58 59 60
desc "Generates minimal Rails package using symlinks"
task :dev => [ :clean, :make_dir_structure, :initialize_file_stubs, :link_vendor_libraries, :copy_ties_content ]

D
Initial  
David Heinemeier Hansson 已提交
61 62 63 64 65 66 67
desc "Packages the fresh Rails package with documentation"
task :package => [ :clean, :fresh_rails ] do
  system %{cd ..; tar -czvf #{PKG_NAME}-#{PKG_VERSION}.tgz #{PKG_NAME}}
  system %{cd ..; zip -r #{PKG_NAME}-#{PKG_VERSION}.zip #{PKG_NAME}}
end

task :clean do
D
David Heinemeier Hansson 已提交
68
  rm_rf PKG_DESTINATION
D
Initial  
David Heinemeier Hansson 已提交
69 70
end

71 72 73
# Get external spinoffs -------------------------------------------------------------------

desc "Updates railties to the latest version of the javascript spinoffs"
D
David Heinemeier Hansson 已提交
74
task :update_js do
75
  for js in %w( prototype controls dragdrop effects slider )
D
David Heinemeier Hansson 已提交
76 77 78 79
    rm "html/javascripts/#{js}.js"
    cp "./../actionpack/lib/action_view/helpers/javascripts/#{js}.js", "html/javascripts"
  end
end
D
Initial  
David Heinemeier Hansson 已提交
80 81 82

# Make directory structure ----------------------------------------------------------------

D
David Heinemeier Hansson 已提交
83 84
def make_dest_dirs(dirs, path = nil)
  mkdir_p dirs.map { |dir| File.join(PKG_DESTINATION, path, dir) }
D
Initial  
David Heinemeier Hansson 已提交
85 86
end

D
David Heinemeier Hansson 已提交
87 88
desc "Make the directory structure for the new Rails application"
task :make_dir_structure => [ :make_base_dirs, :make_app_dirs, :make_public_dirs, :make_test_dirs ]
D
Initial  
David Heinemeier Hansson 已提交
89

D
David Heinemeier Hansson 已提交
90 91 92 93
task(:make_base_dirs)   { make_dest_dirs BASE_DIRS              }
task(:make_app_dirs)    { make_dest_dirs APP_DIRS,    'app'     }
task(:make_public_dirs) { make_dest_dirs PUBLIC_DIRS, 'public'  }
task(:make_test_dirs)   { make_dest_dirs TEST_DIRS,   'test'    }
D
Initial  
David Heinemeier Hansson 已提交
94 95 96 97 98


# Initialize file stubs -------------------------------------------------------------------

desc "Initialize empty file stubs (such as for logging)"
D
David Heinemeier Hansson 已提交
99
task :initialize_file_stubs => [ :initialize_log_files ]
D
Initial  
David Heinemeier Hansson 已提交
100 101

task :initialize_log_files do
D
David Heinemeier Hansson 已提交
102 103 104 105 106
  log_dir = File.join(PKG_DESTINATION, 'log')
  chmod 0777, log_dir
  LOG_FILES.each do |log_file|
    log_path = File.join(log_dir, log_file)
    touch log_path
107
    chmod 0666, log_path
D
David Heinemeier Hansson 已提交
108
  end
D
Initial  
David Heinemeier Hansson 已提交
109 110 111 112 113 114
end


# Copy Vendors ----------------------------------------------------------------------------

desc "Copy in all the Rails packages to vendor"
D
David Heinemeier Hansson 已提交
115
task :copy_vendor_libraries do
116
  mkdir File.join(PKG_DESTINATION, 'vendor', 'rails')
117
  VENDOR_LIBS.each { |dir| cp_r File.join('..', dir), File.join(PKG_DESTINATION, 'vendor', 'rails', dir) }
D
Initial  
David Heinemeier Hansson 已提交
118 119
end

120 121
desc "Link in all the Rails packages to vendor"
task :link_vendor_libraries do
122 123
  mkdir File.join(PKG_DESTINATION, 'vendor', 'rails')
  VENDOR_LIBS.each { |dir| ln_s File.join('..', '..', '..', dir), File.join(PKG_DESTINATION, 'vendor', 'rails', dir) }
124 125
end

D
Initial  
David Heinemeier Hansson 已提交
126 127 128 129 130 131

# Copy Ties Content -----------------------------------------------------------------------

# :link_apache_config
desc "Make copies of all the default content of ties"
task :copy_ties_content => [ 
132
  :copy_rootfiles, :copy_dispatches, :copy_html_files, :copy_application,
133
  :copy_configs, :copy_binfiles, :copy_test_helpers, :copy_app_doc_readme ]
D
Initial  
David Heinemeier Hansson 已提交
134 135

task :copy_dispatches do
136
  copy_with_rewritten_ruby_path("dispatches/dispatch.rb", "#{PKG_DESTINATION}/public/dispatch.rb")
D
Initial  
David Heinemeier Hansson 已提交
137 138
  chmod 0755, "#{PKG_DESTINATION}/public/dispatch.rb"

139
  copy_with_rewritten_ruby_path("dispatches/dispatch.rb", "#{PKG_DESTINATION}/public/dispatch.cgi")
D
Initial  
David Heinemeier Hansson 已提交
140 141
  chmod 0755, "#{PKG_DESTINATION}/public/dispatch.cgi"

142
  copy_with_rewritten_ruby_path("dispatches/dispatch.fcgi", "#{PKG_DESTINATION}/public/dispatch.fcgi")
D
Initial  
David Heinemeier Hansson 已提交
143
  chmod 0755, "#{PKG_DESTINATION}/public/dispatch.fcgi"
144

145 146
  # copy_with_rewritten_ruby_path("dispatches/gateway.cgi", "#{PKG_DESTINATION}/public/gateway.cgi")
  # chmod 0755, "#{PKG_DESTINATION}/public/gateway.cgi"
D
Initial  
David Heinemeier Hansson 已提交
147 148 149
end

task :copy_html_files do
150
  HTML_FILES.each { |file| cp File.join('html', file), File.join(PKG_DESTINATION, 'public', file) }
D
Initial  
David Heinemeier Hansson 已提交
151 152
end

153 154
task :copy_application do
  cp "helpers/application.rb", "#{PKG_DESTINATION}/app/controllers/application.rb"
D
David Heinemeier Hansson 已提交
155
  cp "helpers/application_helper.rb", "#{PKG_DESTINATION}/app/helpers/application_helper.rb"
D
Initial  
David Heinemeier Hansson 已提交
156 157 158
end

task :copy_configs do
159 160 161 162 163
  app_name = "rails"
  socket = nil
  require 'erb'
  File.open("#{PKG_DESTINATION}/config/database.yml", 'w') {|f| f.write ERB.new(IO.read("configs/database.yml")).result(binding)}
  
164
  cp "configs/routes.rb", "#{PKG_DESTINATION}/config/routes.rb"
D
Initial  
David Heinemeier Hansson 已提交
165

D
David Heinemeier Hansson 已提交
166
  cp "configs/apache.conf", "#{PKG_DESTINATION}/public/.htaccess"
167
  cp "configs/lighttpd.conf", "#{PKG_DESTINATION}/config/lighttpd.conf"
D
Initial  
David Heinemeier Hansson 已提交
168

169
  cp "environments/boot.rb", "#{PKG_DESTINATION}/config/boot.rb"
170
  cp "environments/environment.rb", "#{PKG_DESTINATION}/config/environment.rb"
D
David Heinemeier Hansson 已提交
171 172 173
  cp "environments/production.rb", "#{PKG_DESTINATION}/config/environments/production.rb"
  cp "environments/development.rb", "#{PKG_DESTINATION}/config/environments/development.rb"
  cp "environments/test.rb", "#{PKG_DESTINATION}/config/environments/test.rb"
D
Initial  
David Heinemeier Hansson 已提交
174 175
end

176 177 178
task :copy_binfiles do
  BIN_FILES.each do |file|
    dest_file = File.join(PKG_DESTINATION, 'script', file)
179
    copy_with_rewritten_ruby_path(File.join('bin', file), dest_file)
180 181 182 183
    chmod 0755, dest_file
  end
end

D
Initial  
David Heinemeier Hansson 已提交
184
task :copy_rootfiles do
D
David Heinemeier Hansson 已提交
185 186
  cp "fresh_rakefile", "#{PKG_DESTINATION}/Rakefile"
  cp "README", "#{PKG_DESTINATION}/README"
D
 
David Heinemeier Hansson 已提交
187
  cp "CHANGELOG", "#{PKG_DESTINATION}/CHANGELOG"
D
Initial  
David Heinemeier Hansson 已提交
188 189 190
end

task :copy_test_helpers do
D
David Heinemeier Hansson 已提交
191
  cp "helpers/test_helper.rb", "#{PKG_DESTINATION}/test/test_helper.rb"
D
Initial  
David Heinemeier Hansson 已提交
192 193 194
end

task :copy_app_doc_readme do
D
David Heinemeier Hansson 已提交
195
  cp "doc/README_FOR_APP", "#{PKG_DESTINATION}/doc/README_FOR_APP"
D
Initial  
David Heinemeier Hansson 已提交
196 197 198
end

task :link_apache_config do
D
David Heinemeier Hansson 已提交
199 200 201
  chdir(File.join(PKG_DESTINATION, 'config')) {
    ln_s "../public/.htaccess", "apache.conf"
  }
D
Initial  
David Heinemeier Hansson 已提交
202 203
end

204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
def copy_with_rewritten_ruby_path(src_file, dest_file)
  ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])

  File.open(dest_file, 'w') do |df|
    File.open(src_file) do |sf|
      line = sf.gets
      if (line =~ /#!.+ruby\s*/) != nil
        df.puts("#!#{ruby}")
      else
        df.puts(line)
      end
      df.write(sf.read)
    end
  end
end

D
Initial  
David Heinemeier Hansson 已提交
220 221 222 223

# Generate documentation ------------------------------------------------------------------

desc "Generate documentation for the framework and for the empty application"
D
David Heinemeier Hansson 已提交
224
task :generate_documentation => [ :generate_app_doc, :generate_rails_framework_doc ]
D
Initial  
David Heinemeier Hansson 已提交
225 226 227 228 229 230 231 232 233 234

task :generate_rails_framework_doc do
  system %{cd #{PKG_DESTINATION}; rake apidoc}
end

task :generate_app_doc do
  File.cp "doc/README_FOR_APP", "#{PKG_DESTINATION}/doc/README_FOR_APP"
  system %{cd #{PKG_DESTINATION}; rake appdoc}
end

235 236 237 238 239 240 241 242 243 244
Rake::RDocTask.new { |rdoc|
  rdoc.rdoc_dir = 'doc'
  rdoc.title    = "Railties -- Gluing the Engine to the Rails"
  rdoc.options << '--line-numbers --inline-source --accessor cattr_accessor=object'
  rdoc.template = "#{ENV['template']}.rb" if ENV['template']
  rdoc.rdoc_files.include('README', 'CHANGELOG')
  rdoc.rdoc_files.include('lib/*.rb')
  rdoc.rdoc_files.include('lib/rails_generator/*.rb')
  rdoc.rdoc_files.include('lib/commands/**/*.rb')
}
D
Initial  
David Heinemeier Hansson 已提交
245 246 247 248

# Generate GEM ----------------------------------------------------------------------------

task :copy_gem_environment do
249
  cp "environments/environment.rb", "#{PKG_DESTINATION}/config/environment.rb"
250
  chmod 0755, dest_file
D
Initial  
David Heinemeier Hansson 已提交
251 252 253 254 255 256 257 258 259 260 261
end


PKG_FILES = FileList[
  '[a-zA-Z]*',
  'bin/**/*', 
  'configs/**/*', 
  'doc/**/*', 
  'dispatches/**/*', 
  'environments/**/*', 
  'helpers/**/*', 
262
  'generators/**/*', 
D
Initial  
David Heinemeier Hansson 已提交
263 264 265 266 267 268 269 270 271 272
  'html/**/*', 
  'lib/**/*'
]

spec = Gem::Specification.new do |s|
  s.name = 'rails'
  s.version = PKG_VERSION
  s.summary = "Web-application framework with template engine, control-flow layer, and ORM."
  s.description = <<-EOF
    Rails is a framework for building web-application using CGI, FCGI, mod_ruby, or WEBrick
273
    on top of either MySQL, PostgreSQL, SQLite, DB2, SQL Server, or Oracle with eRuby- or Builder-based templates.
D
Initial  
David Heinemeier Hansson 已提交
274 275
  EOF

276
  s.add_dependency('rake', '>= 0.6.2')
277 278 279 280 281
  s.add_dependency('activesupport',    '= 1.2.2' + PKG_BUILD)
  s.add_dependency('activerecord',     '= 1.12.2' + PKG_BUILD)
  s.add_dependency('actionpack',       '= 1.10.2' + PKG_BUILD)
  s.add_dependency('actionmailer',     '= 1.1.2' + PKG_BUILD)
  s.add_dependency('actionwebservice', '= 0.9.2' + PKG_BUILD)
D
Initial  
David Heinemeier Hansson 已提交
282

283
  s.rdoc_options << '--exclude' << '.'
D
David Heinemeier Hansson 已提交
284 285
  s.has_rdoc = false

286
  s.files = PKG_FILES.to_a.delete_if {|f| f.include?('.svn')}
D
Initial  
David Heinemeier Hansson 已提交
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
  s.require_path = 'lib'

  s.bindir = "bin"                               # Use these for applications.
  s.executables = ["rails"]
  s.default_executable = "rails"

  s.author = "David Heinemeier Hansson"
  s.email = "david@loudthinking.com"
  s.homepage = "http://www.rubyonrails.org"
  s.rubyforge_project = "rails"
end

Rake::GemPackageTask.new(spec) do |pkg|
end

302 303

# Publishing -------------------------------------------------------
D
Initial  
David Heinemeier Hansson 已提交
304 305
desc "Publish the API documentation"
task :pgem => [:gem] do 
D
David Heinemeier Hansson 已提交
306 307
  Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
  `ssh davidhh@wrath.rubyonrails.org './gemupdate.sh'`
308 309 310
end

desc "Publish the release files to RubyForge."
D
David Heinemeier Hansson 已提交
311
task :release => [:gem] do
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422
  files = ["gem"].map { |ext| "pkg/#{PKG_FILE_NAME}.#{ext}" }

  if RUBY_FORGE_PROJECT then
    require 'net/http'
    require 'open-uri'

    project_uri = "http://rubyforge.org/projects/#{RUBY_FORGE_PROJECT}/"
    project_data = open(project_uri) { |data| data.read }
    group_id = project_data[/[?&]group_id=(\d+)/, 1]
    raise "Couldn't get group id" unless group_id

    # This echos password to shell which is a bit sucky
    if ENV["RUBY_FORGE_PASSWORD"]
      password = ENV["RUBY_FORGE_PASSWORD"]
    else
      print "#{RUBY_FORGE_USER}@rubyforge.org's password: "
      password = STDIN.gets.chomp
    end

    login_response = Net::HTTP.start("rubyforge.org", 80) do |http|
      data = [
        "login=1",
        "form_loginname=#{RUBY_FORGE_USER}",
        "form_pw=#{password}"
      ].join("&")
      http.post("/account/login.php", data)
    end

    cookie = login_response["set-cookie"]
    raise "Login failed" unless cookie
    headers = { "Cookie" => cookie }

    release_uri = "http://rubyforge.org/frs/admin/?group_id=#{group_id}"
    release_data = open(release_uri, headers) { |data| data.read }
    package_id = release_data[/[?&]package_id=(\d+)/, 1]
    raise "Couldn't get package id" unless package_id

    first_file = true
    release_id = ""

    files.each do |filename|
      basename  = File.basename(filename)
      file_ext  = File.extname(filename)
      file_data = File.open(filename, "rb") { |file| file.read }

      puts "Releasing #{basename}..."

      release_response = Net::HTTP.start("rubyforge.org", 80) do |http|
        release_date = Time.now.strftime("%Y-%m-%d %H:%M")
        type_map = {
          ".zip"    => "3000",
          ".tgz"    => "3110",
          ".gz"     => "3110",
          ".gem"    => "1400"
        }; type_map.default = "9999"
        type = type_map[file_ext]
        boundary = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor"

        query_hash = if first_file then
          {
            "group_id" => group_id,
            "package_id" => package_id,
            "release_name" => RELEASE_NAME,
            "release_date" => release_date,
            "type_id" => type,
            "processor_id" => "8000", # Any
            "release_notes" => "",
            "release_changes" => "",
            "preformatted" => "1",
            "submit" => "1"
          }
        else
          {
            "group_id" => group_id,
            "release_id" => release_id,
            "package_id" => package_id,
            "step2" => "1",
            "type_id" => type,
            "processor_id" => "8000", # Any
            "submit" => "Add This File"
          }
        end

        query = "?" + query_hash.map do |(name, value)|
          [name, URI.encode(value)].join("=")
        end.join("&")

        data = [
          "--" + boundary,
          "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{basename}\"",
          "Content-Type: application/octet-stream",
          "Content-Transfer-Encoding: binary",
          "", file_data, ""
          ].join("\x0D\x0A")

        release_headers = headers.merge(
          "Content-Type" => "multipart/form-data; boundary=#{boundary}"
        )

        target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php"
        http.post(target + query, data, release_headers)
      end

      if first_file then
        release_id = release_response.body[/release_id=(\d+)/, 1]
        raise("Couldn't get release id") unless release_id
      end

      first_file = false
    end
  end
423
end