Rakefile 14.3 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 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 )
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
D
David Heinemeier Hansson 已提交
159
  cp "configs/database.yml", "#{PKG_DESTINATION}/config/database.yml"
160
  cp "configs/routes.rb", "#{PKG_DESTINATION}/config/routes.rb"
D
Initial  
David Heinemeier Hansson 已提交
161

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

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

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

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

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

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

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

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

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

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

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

230 231 232 233 234 235 236 237 238 239
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 已提交
240 241 242 243

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

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


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

271
  s.add_dependency('rake', '>= 0.5.3')
272 273 274 275 276
  s.add_dependency('activesupport',    '= 1.1.1' + PKG_BUILD)
  s.add_dependency('activerecord',     '= 1.11.1' + PKG_BUILD)
  s.add_dependency('actionpack',       '= 1.9.1' + PKG_BUILD)
  s.add_dependency('actionmailer',     '= 1.0.1' + PKG_BUILD)
  s.add_dependency('actionwebservice', '= 0.8.1' + PKG_BUILD)
D
Initial  
David Heinemeier Hansson 已提交
277

278
  s.rdoc_options << '--exclude' << '.'
D
David Heinemeier Hansson 已提交
279 280
  s.has_rdoc = false

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

297 298

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

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