require 'rubygems'



Gem::manage_gems



require 'rake/rdoctask'

require 'rake/packagetask'

require 'rake/gempackagetask'

require 'rake/testtask'

require 'rake/contrib/rubyforgepublisher'



PKG_NAME           = 'acts_as_versioned'

PKG_VERSION        = '0.3.1'

PKG_FILE_NAME      = "#{PKG_NAME}-#{PKG_VERSION}"

PROD_HOST          = "technoweenie@bidwell.textdrive.com"

RUBY_FORGE_PROJECT = 'ar-versioned'

RUBY_FORGE_USER    = 'technoweenie'



desc 'Default: run unit tests.'

task :default => :test



desc 'Test the calculations plugin.'

Rake::TestTask.new(:test) do |t|

  t.libs << 'lib'

  t.pattern = 'test/**/*_test.rb'

  t.verbose = true

end



desc 'Generate documentation for the calculations plugin.'

Rake::RDocTask.new(:rdoc) do |rdoc|

  rdoc.rdoc_dir = 'rdoc'

  rdoc.title    = "#{PKG_NAME} -- Simple versioning with active record models"

  rdoc.options << '--line-numbers --inline-source'

  rdoc.rdoc_files.include('README', 'CHANGELOG', 'RUNNING_UNIT_TESTS')

  rdoc.rdoc_files.include('lib/**/*.rb')

end



spec = Gem::Specification.new do |s|

  s.name            = PKG_NAME

  s.version         = PKG_VERSION

  s.platform        = Gem::Platform::RUBY

  s.summary         = "Simple versioning with active record models"

  s.files           = FileList["{lib,test}/**/*"].to_a + %w(README MIT-LICENSE CHANGELOG RUNNING_UNIT_TESTS)

  s.files.delete      "acts_as_versioned_plugin.sqlite.db"

  s.files.delete      "acts_as_versioned_plugin.sqlite3.db"

  s.files.delete      "test/debug.log"

  s.require_path    = 'lib'

  s.autorequire     = 'acts_as_versioned'

  s.has_rdoc        = true

  s.test_files      = Dir['test/**/*_test.rb']

  s.add_dependency    'activerecord', '>= 1.10.1'

  s.add_dependency    'activesupport', '>= 1.1.1'

  s.author          = "Rick Olson"

  s.email           = "technoweenie@gmail.com"

  s.homepage        = "http://techno-weenie.net"

end



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

  pkg.need_tar = true

end



desc "Publish the API documentation"

task :pdoc => [:rdoc] do

  Rake::RubyForgePublisher.new(RUBY_FORGE_PROJECT, RUBY_FORGE_USER).upload

end



desc 'Publish the gem and API docs'

task :publish => [:pdoc, :rubyforge_upload]



desc "Publish the release files to RubyForge."

task :rubyforge_upload => :package do

  files = %w(gem tgz).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" => PKG_FILE_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

end