Rakefile 14.4 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( models controllers helpers 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
HTML_FILES   = %w( 404.html 500.html index.html robots.txt favicon.ico images/rails.png
38 39
                   javascripts/prototype.js
                   javascripts/effects.js javascripts/dragdrop.js javascripts/controls.js )
40
BIN_FILES    = %w( about breakpointer console destroy generate performance/benchmarker performance/profiler process/reaper process/spawner process/spinner runner server plugin )
D
David Heinemeier Hansson 已提交
41

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


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

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

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

54 55 56
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 ]

57 58 59
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 已提交
60 61 62 63 64 65 66
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 已提交
67
  rm_rf PKG_DESTINATION
D
Initial  
David Heinemeier Hansson 已提交
68 69
end

70 71 72
# Get external spinoffs -------------------------------------------------------------------

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

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

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

D
David Heinemeier Hansson 已提交
86 87
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 已提交
88

D
David Heinemeier Hansson 已提交
89 90 91 92
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 已提交
93 94 95 96 97


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

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

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


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

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

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

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

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

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

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

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

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

144 145
  # 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 已提交
146 147 148
end

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

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

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

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

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

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

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

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

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

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

202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
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 已提交
218 219 220 221

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

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

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

233 234 235 236 237 238 239 240 241 242
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 已提交
243 244 245 246

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

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


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

275
  s.add_dependency('rake', '>= 0.6.2')
276 277 278 279 280
  s.add_dependency('activesupport',    '= 1.2.3' + PKG_BUILD)
  s.add_dependency('activerecord',     '= 1.13.0' + PKG_BUILD)
  s.add_dependency('actionpack',       '= 1.11.0' + PKG_BUILD)
  s.add_dependency('actionmailer',     '= 1.1.3' + PKG_BUILD)
  s.add_dependency('actionwebservice', '= 0.9.3' + PKG_BUILD)
D
Initial  
David Heinemeier Hansson 已提交
281

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

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

301 302

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

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