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 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
                   javascripts/prototype.js javascripts/application.js
43
                   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 ----------------------------------------------------------------

T
Thomas Fuchs 已提交
86
def make_dest_dirs(dirs, path = nil)
87
  mkdir_p dirs.map { |dir| File.join(PKG_DESTINATION, path.to_s, 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) }
121
  FileUtils.rm_r(Dir.glob(File.join(PKG_DESTINATION, 'vendor', 'rails', "**", ".svn")))
D
Initial  
David Heinemeier Hansson 已提交
122 123
end

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

280
  s.add_dependency('rake', '>= 0.7.0')
281 282 283 284 285
  s.add_dependency('activesupport',    '= 1.3.0' + PKG_BUILD)
  s.add_dependency('activerecord',     '= 1.14.0' + PKG_BUILD)
  s.add_dependency('actionpack',       '= 1.12.0' + PKG_BUILD)
  s.add_dependency('actionmailer',     '= 1.2.0' + PKG_BUILD)
  s.add_dependency('actionwebservice', '= 1.1.0' + PKG_BUILD)
D
Initial  
David Heinemeier Hansson 已提交
286

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

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

306 307

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

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