Rakefile 14.5 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 32 33 34 35
BASE_DIRS   = %w( 
  app config/environments components db doc log lib lib/tasks public script script/performance script/process test vendor vendor/plugins
  tmp/sessions tmp/cache tmp/sockets
)

36
APP_DIRS    = %w( models controllers helpers views views/layouts )
37
PUBLIC_DIRS = %w( images javascripts stylesheets )
38
TEST_DIRS   = %w( fixtures unit functional mocks mocks/development mocks/test )
D
David Heinemeier Hansson 已提交
39

40
LOG_FILES    = %w( server.log development.log test.log production.log )
41
HTML_FILES   = %w( 404.html 500.html index.html robots.txt favicon.ico images/rails.png
42 43
                   javascripts/prototype.js
                   javascripts/effects.js javascripts/dragdrop.js javascripts/controls.js )
44
BIN_FILES    = %w( about breakpointer console destroy generate performance/benchmarker performance/profiler process/reaper process/spawner runner server plugin )
D
David Heinemeier Hansson 已提交
45

46
VENDOR_LIBS = %w( actionpack activerecord actionmailer activesupport actionwebservice railties )
D
David Heinemeier Hansson 已提交
47 48


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

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

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

58 59 60
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 ]

61 62 63
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 已提交
64 65 66 67 68 69 70
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 已提交
71
  rm_rf PKG_DESTINATION
D
Initial  
David Heinemeier Hansson 已提交
72 73
end

74 75 76
# Get external spinoffs -------------------------------------------------------------------

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

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

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

D
David Heinemeier Hansson 已提交
90 91
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 已提交
92

D
David Heinemeier Hansson 已提交
93 94 95 96
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 已提交
97 98 99 100 101


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

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

task :initialize_log_files do
D
David Heinemeier Hansson 已提交
105 106 107 108 109
  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
110
    chmod 0666, log_path
D
David Heinemeier Hansson 已提交
111
  end
D
Initial  
David Heinemeier Hansson 已提交
112 113 114 115 116 117
end


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

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

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

D
Initial  
David Heinemeier Hansson 已提交
129 130 131 132 133 134

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

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

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

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

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

148 149
  # 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 已提交
150 151 152
end

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

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

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

D
David Heinemeier Hansson 已提交
169
  cp "configs/apache.conf", "#{PKG_DESTINATION}/public/.htaccess"
D
Initial  
David Heinemeier Hansson 已提交
170

171
  cp "environments/boot.rb", "#{PKG_DESTINATION}/config/boot.rb"
172
  cp "environments/environment.rb", "#{PKG_DESTINATION}/config/environment.rb"
D
David Heinemeier Hansson 已提交
173 174 175
  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 已提交
176 177
end

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

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

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

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

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

206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
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 已提交
222 223 224 225

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

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

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

237 238 239
Rake::RDocTask.new { |rdoc|
  rdoc.rdoc_dir = 'doc'
  rdoc.title    = "Railties -- Gluing the Engine to the Rails"
240
  rdoc.options << '--line-numbers' << '--inline-source' << '--accessor' << 'cattr_accessor=object'
241 242 243 244 245 246
  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 已提交
247 248 249 250

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

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


PKG_FILES = FileList[
  '[a-zA-Z]*',
  'bin/**/*', 
259
  'builtin/**/*',
D
Initial  
David Heinemeier Hansson 已提交
260 261 262 263 264
  'configs/**/*', 
  'doc/**/*', 
  'dispatches/**/*', 
  'environments/**/*', 
  'helpers/**/*', 
265
  'generators/**/*', 
D
Initial  
David Heinemeier Hansson 已提交
266 267 268 269 270 271 272 273 274 275
  '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
276
    on top of either MySQL, PostgreSQL, SQLite, DB2, SQL Server, or Oracle with eRuby- or Builder-based templates.
D
Initial  
David Heinemeier Hansson 已提交
277 278
  EOF

279
  s.add_dependency('rake', '>= 0.7.0')
280 281 282 283 284
  s.add_dependency('activesupport',    '= 1.2.5' + PKG_BUILD)
  s.add_dependency('activerecord',     '= 1.13.2' + PKG_BUILD)
  s.add_dependency('actionpack',       '= 1.11.2' + PKG_BUILD)
  s.add_dependency('actionmailer',     '= 1.1.5' + PKG_BUILD)
  s.add_dependency('actionwebservice', '= 1.0.0' + PKG_BUILD)
D
Initial  
David Heinemeier Hansson 已提交
285

286
  s.rdoc_options << '--exclude' << '.'
D
David Heinemeier Hansson 已提交
287 288
  s.has_rdoc = false

289
  s.files = PKG_FILES.to_a.delete_if {|f| f.include?('.svn')}
D
Initial  
David Heinemeier Hansson 已提交
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
  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

305 306

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

desc "Publish the release files to RubyForge."
D
David Heinemeier Hansson 已提交
314
task :release => [:gem] do
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 423 424 425
  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
426
end