Permalink
Browse files

Pull in plugin work

Merge remote branch 'origin/plugins'
  • Loading branch information...
jhs committed Nov 4, 2010
2 parents c61f35c + 91ade96 commit a4401d288a4f40117207dd618a227af7c4c5881a
Showing with 191 additions and 130 deletions.
  1. +14 −0 README.md
  2. +27 −25 tasks/couchdb.rake
  3. +4 −56 tasks/distro.rake
  4. +55 −0 tasks/distros.rb
  5. +86 −48 tasks/lib.rb
  6. +1 −0 tasks/places.rb
  7. +4 −1 tasks/shortcuts.rake
View
@@ -158,6 +158,20 @@ Want to build [GeoCouch][geocouch]? No problem.
rake git="git://github.com/vmx/couchdb geocouch"
+### CouchDB Plugins
+
+Any CouchDB plugin can be loaded remotely from Git, built, and installed
+into the final CouchDB system.
+
+ rake plugin="git://github.com/vmx/couchdb origin/gc-separate"
+
+Multiple plugins can be processed together:
+
+ rake plugins="git://github.com/vmx/couchdb origin/gc-separate,git://github.com/somebody/whatever some_tag"
+
+(Both `plugin` and `plugins` supports comma-separated lists; use whichever
+you remember better.)
+
### Install CouchDB somewhere besides `build/`.
Add a `couchdb_build` parameter to place the final couchdb binaries anywhere.
View
@@ -12,7 +12,7 @@ namespace :couchdb do
task :dependencies => :deps
desc 'Build CouchDB'
- task :build => couchdb_build_deps + [COUCH_BIN]
+ task :build => couchdb_build_deps + [:plugins, COUCH_BIN]
desc 'Build CouchDB and then clean out unnecessary things like autotools'
task :clean_install => :build do
@@ -25,33 +25,19 @@ namespace :couchdb do
end
end
- directory "#{BUILD}/var/run/couchdb"
-
- file COUCH_BIN => [AUTOCONF_259, "#{BUILD}/var/run/couchdb"] do
- source = "#{DEPS}/couchdb"
+ file COUCH_SOURCE => :known_distro do
+ git_checkout(ENV['git']) if ENV['git']
+ end
- if ENV['git']
- remote, commit = ENV['git'].split
- checkout = "#{HERE}/git-build/#{URI.escape(remote, /[\/:]/)}"
+ task :plugins => COUCH_SOURCE do
+ # This task will be assigned dependencies dynamically, see the "plugins" stuff below.
+ puts "Plugins done"
+ end
- if File.directory?(checkout) || File.symlink?(checkout)
- puts "Using #{checkout} for build from Git"
- elsif File.exists? checkout
- raise "Don't know what to do with #{checkout}"
- else
- sh "git clone '#{remote}' '#{checkout}'"
- end
+ directory "#{BUILD}/var/run/couchdb"
- Dir.chdir checkout do
- sh "git checkout #{commit}"
- sh "git reset --hard"
- sh "git clean -f -d"
- rm = (DISTRO[0] == :solaris) ? 'rm' : 'rm -v'
- sh "git ls-files --others -i --exclude-standard | xargs #{rm} || true"
- end
-
- source = checkout
- end
+ file COUCH_BIN => [COUCH_SOURCE, AUTOCONF_259, "#{BUILD}/var/run/couchdb"] do
+ source = COUCH_SOURCE
begin
Dir.chdir(source) do
@@ -92,4 +78,20 @@ namespace :couchdb do
end
end
+ # Determine what plugins are desired and have them built.
+ plugins = (ENV['plugin'] || "") + "," + (ENV['plugins'] || "")
+ plugins.split(',').select{|x| ! x.strip.empty? }.each do |git_plugin|
+ remote, commit = git_plugin.split
+ plugin_mark = "#{COUCH_BUILD}/lib/build-couchdb/plugins/#{git_checkout_name remote}/#{commit}"
+
+ task :plugins => plugin_mark
+ file plugin_mark => 'environment:path' do
+ source = git_checkout(git_plugin)
+ Dir.chdir(source) do
+ ENV['COUCH_SRC'] = "#{COUCH_SOURCE}/src/couchdb"
+ gmake
+ end
+ end
+ end
+
end
View
@@ -1,57 +1,5 @@
-
-task :known_distro => [ :known_mac, :known_ubuntu, :known_debian, :known_redhat, :known_opensuse, :known_slf, :known_solaris ] do
- raise 'Unknown distribution, build not supported' unless Object.const_defined? 'DISTRO'
-end
-
-task :known_mac do
- DISTRO = [:osx, 10.0] if `uname`.chomp == 'Darwin'
-end
-
-task :known_ubuntu do
- if File.exist? '/etc/lsb-release'
- info = Hash[ *File.new('/etc/lsb-release').lines.map{ |x| x.split('=').map { |y| y.chomp } }.flatten ]
- if info['DISTRIB_ID'] == 'Ubuntu'
- DISTRO = [:ubuntu, info['DISTRIB_RELEASE']]
- end
- end
-end
-
-task :known_debian do
- ver = '/etc/debian_version'
- DISTRO = [:debian, File.new(ver).readline.chomp] if !File.exist?('/etc/lsb-release') && File.exist?(ver)
-end
-
-task :known_redhat do
- if File.exist? '/etc/fedora-release'
- release = File.new('/etc/fedora-release').readline.match(/Fedora release (\d+)/)[1]
- DISTRO = [:fedora, release]
- end
- if File.exist? '/etc/redhat-release'
- release = File.new('/etc/redhat-release').readline.match(/Red Hat Enterprise Linux Server release (\d+)/)[1]
- DISTRO = [:fedora, release]
- end
-end
-
-task :known_slf do
- if File.exist? '/etc/redhat-release'
- release = File.new('/etc/redhat-release').readline.match(/Scientific Linux SLF release (\d+)/)[1]
- DISTRO = [:slf, release]
-
- if RUBY_VERSION <= '1.8.7'
- raise 'Version of ruby is too old. Consider installing a more recent version'
- end
- end
-end
-
-task :known_opensuse do
- if File.exist? '/etc/SuSE-release'
- release = File.new('/etc/SuSE-release').readline.match(/openSUSE (\d+)/)[1]
- DISTRO = [:opensuse, release]
- end
-end
-
-task :known_solaris do
- if `uname`.chomp == "SunOS"
- DISTRO = [:solaris, `uname -r`.chomp]
- end
+task :known_distro do
+ distro = detect_distro()
+ raise 'Unknown distribution, build not supported' unless distro
+ DISTRO = distro
end
View
@@ -0,0 +1,55 @@
+# Distribution (platform) detection
+
+def detect_distro
+ # OSX
+ if `uname`.chomp == 'Darwin'
+ return [:osx, 10.0]
+ end
+
+ # Solaris
+ if `uname`.chomp == "SunOS"
+ return [:solaris, `uname -r`.chomp]
+ end
+
+ # Ubuntu
+ if File.exist? '/etc/lsb-release'
+ info = Hash[ *File.new('/etc/lsb-release').lines.map{ |x| x.split('=').map { |y| y.chomp } }.flatten ]
+ if info['DISTRIB_ID'] == 'Ubuntu'
+ return [:ubuntu, info['DISTRIB_RELEASE']]
+ end
+ end
+
+ # Debian
+ ver = '/etc/debian_version'
+ return [:debian, File.new(ver).readline.chomp] if !File.exist?('/etc/lsb-release') && File.exist?(ver)
+
+ # Fedora
+ if File.exist? '/etc/fedora-release'
+ release = File.new('/etc/fedora-release').readline.match(/Fedora release (\d+)/)[1]
+ return [:fedora, release]
+ end
+
+ # Red Hat
+ if File.exist? '/etc/redhat-release'
+ release = File.new('/etc/redhat-release').readline.match(/Red Hat Enterprise Linux Server release (\d+)/)[1]
+ return [:fedora, release]
+ end
+
+ # Scientific Linux
+ if File.exist? '/etc/redhat-release'
+ release = File.new('/etc/redhat-release').readline.match(/Scientific Linux SLF release (\d+)/)[1]
+ return [:slf, release]
+
+ if RUBY_VERSION <= '1.8.7'
+ raise 'Version of ruby is too old. Consider installing a more recent version'
+ end
+ end
+
+ # OpenSUSE
+ if File.exist? '/etc/SuSE-release'
+ release = File.new('/etc/SuSE-release').readline.match(/openSUSE (\d+)/)[1]
+ return [:opensuse, release]
+ end
+
+ nil
+end
View
@@ -9,70 +9,77 @@
log_filename = "rake.log"
File.unlink(log_filename) if File.exists?(log_filename)
-["$stdout", "$stderr"].each do |std|
- rd, wr = IO.pipe
- if fork
- rd.close
- wr.sync = true
- eval "#{std}.reopen(wr)"
- eval "#{std}.sync = true"
- #Process.wait
- else
- # Child
- wr.close
- begin
- # Input must be forked.
- label = std[1..-1].upcase
- File.open(log_filename, 'a') do |f|
- f.sync = true
- while(line = rd.gets)
- eval "#{std}_old.puts(line)"
- f.puts([label, line].join(' '))
+unless ARGV[0] == 'environment:shell'
+ ["$stdout", "$stderr"].each do |std|
+ rd, wr = IO.pipe
+ if fork
+ rd.close
+ wr.sync = true
+ eval "#{std}.reopen(wr)"
+ eval "#{std}.sync = true"
+ #Process.wait
+ else
+ # Child
+ wr.close
+ begin
+ # Input must be forked.
+ label = std[1..-1].upcase
+ File.open(log_filename, 'a') do |f|
+ f.sync = true
+ while(line = rd.gets)
+ eval "#{std}_old.puts(line)"
+ f.puts([label, line].join(' '))
+ end
end
+ ensure
+ rd.close
+ exit
end
- ensure
- rd.close
- exit
end
end
end
require File.dirname(__FILE__) + '/places'
+require File.dirname(__FILE__) + '/distros'
def package_dep opts
+ # Unfortunately the dependency must be defined after the OS is detected,
+ # Even if this task is a no-op, if other tasks depend on it, they will re-run
+ # if this task runs. Therefore it must not be defined at all for un-requested
+ # distros. That means calling detect_distro() now and presumably later in :known_distro.
+ distro = detect_distro()
+
only_distro = opts.delete :distro
- only_distros = opts.delete :distros
- only_distros ||= [only_distro]
+ if only_distro && only_distro != distro[0]
+ puts "#{distro[0]} does not need #{opts.inspect}"
+ return "/" # Return a file dependency that will presumably always work.
+ end
+ puts "Package dependency for #{distro[0]}: #{opts.inspect}"
program_file, package = opts.to_a.first
Rake.application.in_explicit_namespace(':') do
- task "package:#{package}" => :known_distro do
- if only_distros.empty? || only_distros.include?(DISTRO[0])
- puts "Package dependency for #{DISTRO[0]}: #{program_file} => #{package}"
- case DISTRO[0]
- when :ubuntu, :debian
- installed = `dpkg --list`.split("\n").map { |x| x.split[1] } # Hm, this is out of scope if defined outside.
- if installed.none? { |pkg| pkg == package }
- sh "sudo apt-get -y install #{package}"
- end
- when :solaris
- installed = `pkg-get -l`.split("\n")
- if installed.none? { |pkg| pkg == package }
- sh "sudo pkg-get install #{package}"
- end
- when :osx
- installed = `brew list`.split("\n")
- if installed.none? { |pkg| pkg == package }
- sh "sudo brew install #{package}"
- end
- else
- puts "Skipping package requirement '#{package}' on an unsupported platform"
- end
+ file program_file => :known_distro do
+ case DISTRO[0]
+ when :ubuntu, :debian
+ installed = `dpkg --list`.split("\n").map { |x| x.split[1] } # Hm, this is out of scope if defined outside.
+ if installed.none? { |pkg| pkg == package }
+ sh "sudo apt-get -y install #{package}"
+ end
+ when :solaris
+ installed = `pkg-get -l`.split("\n")
+ if installed.none? { |pkg| pkg == package }
+ sh "sudo pkg-get install #{package}"
+ end
+ when :osx
+ installed = `brew list`.split("\n")
+ if installed.none? { |pkg| pkg == package }
+ sh "sudo brew install #{package}"
+ end
+ else
+ puts "Skipping package requirement '#{package}' on an unsupported platform"
end
end
-
- file program_file => "package:#{package}"
end
program_file
@@ -222,6 +229,37 @@ def configure_cmd(source, opts={})
return "env #{env} #{source}/configure #{prefix} --with-erlang=#{BUILD}/lib/erlang/usr/include"
end
+def git_checkout_name(url)
+ URI.escape(url, /[\/:]/)
+end
+
+def git_checkout(url_and_commit, opts={})
+ remote, commit = url_and_commit.split
+ checkout = "#{HERE}/git-build/#{git_checkout_name remote}"
+ return checkout if opts[:noop]
+
+ fetch = false
+ if File.directory?(checkout) || File.symlink?(checkout)
+ puts "Using #{checkout} for build from Git"
+ fetch = true
+ elsif File.exists? checkout
+ raise "Don't know what to do with #{checkout}"
+ else
+ sh "git clone '#{remote}' '#{checkout}'"
+ end
+
+ Dir.chdir checkout do
+ sh "git fetch origin" if fetch
+ sh "git checkout #{commit}"
+ sh "git reset --hard"
+ sh "git clean -f -d"
+ rm = (DISTRO[0] == :solaris) ? 'rm' : 'rm -v'
+ sh "git ls-files --others -i --exclude-standard | xargs #{rm} || true"
+ end
+
+ return checkout
+end
+
module Rake
module TaskManager
def in_explicit_namespace(name)
View
@@ -3,6 +3,7 @@
JS_LIB = "#{BUILD}/bin/js-config"
ERL_BIN = "#{BUILD}/bin/erl"
ICU_BIN = "#{BUILD}/bin/icu-config"
+COUCH_SOURCE = ENV['git'] ? git_checkout(ENV['git'], :noop => true) : "#{DEPS}/couchdb"
COUCH_BUILD = ENV['couchdb_build'] || BUILD
COUCH_BIN = "#{COUCH_BUILD}/bin/couchdb"
MANIFESTS = "#{BUILD}/manifests"
View
@@ -1,6 +1,9 @@
-desc Rake::Task['couchdb:build'].comment
+desc Rake::Task['couchdb:clean_install'].comment
task :default => 'couchdb:clean_install'
+desc Rake::Task['couchdb:build'].comment
+task :couchdb => 'couchdb:build'
+
desc Rake::Task['environment:shell'].comment
task :sh => 'environment:shell'

0 comments on commit a4401d2

Please sign in to comment.