# -*- ruby -*-

require “pathname” require “find” require “tmpdir” require “open-uri”

task :default => :test

def version

@version ||= ENV["VERSION"] || guess_version

end

def guess_version

versions = {}
File.open("glib2/ext/glib2/rbglib.h") do |rbglib_h|
  rbglib_h.each_line do |line|
    if /#define\s+RBGLIB_([A-Z]+)_VERSION\s+(\d+)/ =~ line
      versions[$1.downcase] = $2.to_i
    end
  end
end
["major", "minor", "micro"].collect {|type| versions[type]}.compact.join(".")

end

def dist_dir(base_name, _version=nil)

_version ||= version
"#{base_name}-#{_version}"

end

def archive_name(base_name, _version=nil)

dist_dir(base_name, _version) + ".tar.gz"

end

@needless_paths = [

".svn",
".test-result",
".gdb_history",
"mkmf.log",
"*.o",
"*.so",
"pkg",
"vendor",
"tmp",

] def package(base_name, paths, needless_paths=nil)

_dist_dir = dist_dir(base_name)

rm_rf(_dist_dir)
mkdir_p(_dist_dir)
cp_r(paths, _dist_dir, :preserve => true)

needless_paths ||= @needless_paths
Dir.glob("#{_dist_dir}   /{#{needless_paths.join(',')}}") do |needless_path|
  rm_rf(needless_path)
end
Dir.glob("#{_dist_dir}/   */") do |directory|
  if (Dir.entries(directory) - [".", ".."]).empty?
    rm_r(directory)
  end
end
sh("tar", "cvfz", archive_name(base_name), _dist_dir)

ensure

rm_rf(_dist_dir) if _dist_dir

end

def download(url, local_path=nil)

local_path ||= File.basename(url)
open(url) do |remote_file|
  File.open(local_path, "wb") do |local_file|
    local_file.print(remote_file.read)
  end
end
local_path

end

def change_environment_variable(variables)

original_variables = {}
variables.each do |key, value|
  next if ENV[key]
  original_variables[key] = ENV[key]
  ENV[key] = value
end

begin
  yield
ensure
  original_variables.each do |key, value|
    ENV[key] = value
  end
end

end

desc “configure all packages” task :configure do

ruby("extconf.rb")

end

file “Makefile” do

task(:configure).invoke

end

desc “build all packages” task :build => [“Makefile”] do

sh("make")

end

desc “clean all packages” task :clean do

sh("make", "clean") if File.exist?("Makefile")

end

desc “more clean all packages” task :distclean do

sh("make", "distclean") if File.exist?("Makefile")

end

desc “run tests for all packages” task :test => [:build] do

ruby("run-test.rb")

end

gtk2_base_name = “ruby-gtk2” gtk3_base_name = “ruby-gtk3” gnome2_base_name = “ruby-gnome2-all”

gtk2_packages = [

"glib2",
"gobject-introspection",
"gio2",
"atk",
"pango",
"gdk_pixbuf2",
"gtk2",

] gtk3_packages = gtk2_packages - [“gtk2”] + [

"cairo-gobject",
"gdk3",
"gtk3",

] gnome2_packages = gtk2_packages + gtk3_packages + [

"gstreamer",
"gtksourceview2",
"poppler",
"rsvg2",
"vte",
"vte3",
"gtksourceview3",
"clutter",
"clutter-gtk",
"clutter-gstreamer",
"webkit-gtk",
"webkit-gtk2",

] gnome2_packages = gnome2_packages.uniq

namespace :dist do

base_files = ["AUTHORS", "COPYING.LIB", "NEWS",
              "README.md", "Rakefile",
              "exec_make.rb", "extconf.rb", "run-test.rb"]
desc "make Ruby/GTK2 package"
task :gtk2 do
  package(gtk2_base_name, base_files + gtk2_packages)
end

desc "make Ruby/GTK3 package"
task :gtk3 do
  package(gtk3_base_name, base_files + gtk3_packages)
end

desc "make Ruby/GNOME2 package"
task :gnome2 do
  package(gnome2_base_name, base_files + gnome2_packages)
end

ruby_versions = ["1.9.3-p545", "2.0.0-p451", "2.1.1"]
namespace :test do
  ruby_base_url = "ftp://ftp.ruby-lang.org/pub/ruby"
  ruby_versions.each do |ruby_version|
    base_dir = "tmp/dist-test-#{version}/#{ruby_version}"
    directory base_dir

    prefix = Pathname.new(base_dir) + "local"
    ruby_tar_bz2_base = "ruby-#{ruby_version}.tar.bz2"
    file "#{base_dir}/#{ruby_tar_bz2_base}" => base_dir do
      generation = ruby_version.scan(/\A\d\.\d/)[0]
      ruby_tar_bz2_url = "#{ruby_base_url}/#{generation}/#{ruby_tar_bz2_base}"
      Dir.chdir(base_dir) do
        download(ruby_tar_bz2_url)
      end
    end

    ruby_path = "#{prefix}/bin/ruby"
    expanded_ruby_path = File.expand_path(ruby_path)
    file ruby_path => "#{base_dir}/#{ruby_tar_bz2_base}" do
      expanded_prefix = prefix.expand_path
      Dir.chdir(base_dir) do
        sh("tar", "xvf", ruby_tar_bz2_base)
        Dir.chdir(File.basename(ruby_tar_bz2_base, ".tar.bz2")) do
          sh("./configure",
             "--prefix=#{expanded_prefix}",
             "--with-out-ext=readline")
          sh("make", "-j8")
          sh("make", "install-nodoc")
        end
      end
    end

    rubygems_tgz_base = "rubygems-2.2.2.tgz"
    rubygems_tgz = "#{base_dir}/#{rubygems_tgz_base}"
    file rubygems_tgz => base_dir do
      rubygems_url_base = "http://production.cf.rubygems.org/rubygems"
      Dir.chdir(base_dir) do
        download("#{rubygems_url_base}/#{rubygems_tgz_base}")
      end
    end

    gem_path = "#{prefix}/bin/gem"
    expanded_gem_path = File.expand_path(gem_path)
    file gem_path => [ruby_path, rubygems_tgz] do
      Dir.chdir(base_dir) do
        sh("tar", "xvf", rubygems_tgz_base)
        Dir.chdir(File.basename(rubygems_tgz_base, ".tgz")) do
          sh(expanded_ruby_path, "setup.rb")
        end
      end
    end

    packages = {
      "gtk2" => {
        :archive_name => archive_name(gtk2_base_name),
        :packages => gtk2_packages,
      },
      "gtk3" => {
        :archive_name => archive_name(gtk3_base_name),
        :packages => gtk3_packages,
      },
      "gnome2" => {
        :archive_name => archive_name(gnome2_base_name),
        :packages => gnome2_packages,
      },
    }
    namespace "ruby-#{ruby_version}" do
      packages.each do |name, attributes|
        namespace name do
          tar_gz = File.expand_path(attributes[:archive_name])
          task :prepare => ["dist:#{name}", gem_path] do
            Dir.chdir(base_dir) do
              sh("tar", "xvf", tar_gz)
            end
            if /cairo/ !~ %x#{expanded_gem_path} list cairo`
              sh(expanded_gem_path, "install", "cairo")
            end
          end

          attributes[:packages].each do |sub_package_name|
            task sub_package_name => :prepare do
              Dir.chdir(base_dir) do
                package_base_dir = File.basename(tar_gz, ".tar.gz")
                rm_rf(sub_package_name)
                sh("cp", "-a",
                   "#{package_base_dir}/#{sub_package_name}", sub_package_name)
                Dir.chdir(sub_package_name) do
                  if File.exist?("extconf.rb")
                    sh(expanded_ruby_path, "extconf.rb")
                    sh("make", "-j8")
                    sh("make", "install")
                  end
                end
                rm_rf(sub_package_name)
              end
            end
          end
        end
      end

      packages.each do |name, attributes|
        test_tasks = attributes[:packages].collect do |sub_package_name|
          "dist:test:ruby-#{ruby_version}:#{name}:#{sub_package_name}"
        end
        task name => test_tasks
      end
    end

    test_tasks = packages.collect do |name, attributes|
      "dist:test:ruby-#{ruby_version}:#{name}"
    end
    task "ruby-#{ruby_version}" => test_tasks
  end
end

test_tasks = ruby_versions.collect do |ruby_version|
  "dist:test:ruby-#{ruby_version}"
end
desc "run packages test"
task :test => test_tasks

end desc “make all packages” task :dist => [“dist:gtk2”, “dist:gtk3”, “dist:gnome2”]

directory “misc” file “misc/release.rb” => “misc” do |task|

release_rb = "https://raw.github.com/clear-code/cutter/master/misc/release.rb"
open(release_rb) do |remote_release_rb|
  File.open(task.name, "w") do |local_release_rb|
    local_release_rb.print(remote_release_rb.read)
  end
end

end

desc “release Ruby-GNOME2 packages” task :release => [“misc/release.rb”, :dist] do

sf_user_name = ENV["SF_USER"] || ENV["USER"]
project_id = "ruby-gnome2"
project_name = "Ruby-GNOME 2"
package_name = "ruby-gnome2"
release_name = "ruby-gnome2-#{version}"
package_base_names = [gtk2_base_name, gtk3_base_name, gnome2_base_name]
archive_names = package_base_names.collect do |base_name|
  archive_name(base_name)
end
ruby("misc/release.rb", sf_user_name, project_id, project_name,
     package_name, release_name, "README.md:1", "NEWS",
      archive_names)

end

namespace :gem do

desc "build all gems"
task :build do
  gnome2_packages.each do |package|
    Dir.chdir(package) do
      ruby("-S", "rake", "gem")
    end
  end
end

desc "push all gems"
task :push do
  gnome2_packages.each do |package|
    ruby("-S", "gem", "push",
          Dir.glob(File.join(package, "pkg", "*-#{version}.gem")))
  end
end

desc "install all gems"
task :install do
  gnome2_packages.each do |package|
    ruby("-S", "gem", "install", "--user-install",
          Dir.glob(File.join(package, "pkg", "*-#{version}.gem")))
  end
end

desc "uninstall all gems"
task :uninstall do
  gnome2_packages.each do |package|
    ruby("-S", "gem", "uninstall", "--version", version, package)
  end
end

namespace :win32 do
  win32_unsupported_packages = [
    "vte",
    "vte3",
    "webkit-gtk",
    "webkit-gtk2",
  ]
  win32_gnome2_packages = gnome2_packages - win32_unsupported_packages

  namespace :build do
    desc "build all Windows binaries"
    task :vendor do
      win32_gnome2_packages.each do |package|
        Dir.chdir(package) do
          ruby("-S", "rake", "native:build", "win32:build")
        end
      end
    end

    desc "build all Windows bindings"
    task :ext do
      change_environment_variable("MAKE" => "make debugflags=") do
        win32_gnome2_packages.each do |package|
          Dir.chdir(package) do
            tasks = [
              "cross",
              "win32:builder:build:prepare:pkg_config",
              "native",
              "gem",
            ]
            ruby("-S", "rake", "RUBY_CC_VERSION=2.0.0:2.1.1", *tasks)
          end
        end
      end
    end

    desc "build GSettings schemas for all Windows binaries"
    task :schema do
      Dir.mktmpdir do |dir|
        win32_gnome2_packages.each do |package|
          gschema_xml_glob = File.join(package, "vendor", "local", "share",
                                       "glib-2.0", "schemas", "*.gschema.xml")
          Dir.glob(gschema_xml_glob).each do |schema|
            cp(schema, dir)
          end
        end
        sh("glib-compile-schemas",
           "--targetdir", "glib2/vendor/local/share/glib-2.0/schemas",
           dir)
      end
    end
  end

  desc "build all Windows gems"
  task :build => [
    "gem:win32:build:vendor",
    "gem:win32:build:schema",
    "gem:win32:build:ext",
  ]

  desc "clean all Windows gems build"
  task :clean do
    win32_gnome2_packages.each do |package|
      rm_rf(File.join(package, "tmp"))
    end
  end

  desc "download DLL for Windows all gems"
  task :download do
    win32_gnome2_packages.each do |package|
      Dir.chdir(package) do
        ruby("-S", "rake", "win32:download")
      end
    end
  end

  desc "push all Windows gems"
  task :push do
    win32_gnome2_packages.each do |package|
      ruby("-S", "gem", "push",
            Dir.glob(File.join(package, "pkg", "*-#{version}-x86-mingw32.gem")))
    end
  end
end

end

desc “tag the current release” task :tag do

sh("git", "tag", "-a", version, "-m", "release #{version}!!!")

end