lib/capistrano-maven.rb in capistrano-maven-0.0.6 vs lib/capistrano-maven.rb in capistrano-maven-0.0.7
- old
+ new
@@ -1,8 +1,292 @@
-require "capistrano-maven/deploy"
require "capistrano-maven/version"
+require "capistrano"
+require "capistrano/configuration/actions/file_transfer_ext"
+require "capistrano/configuration/resources/file_resources"
+require "uri"
module Capistrano
module Maven
- # Your code goes here...
+ def self.extended(configuration)
+ configuration.load {
+ namespace(:mvn) {
+ _cset(:mvn_version, '3.0.4')
+ _cset(:mvn_major_version) {
+ mvn_version.split('.').first.to_i
+ }
+ _cset(:mvn_archive_url) {
+ "http://www.apache.org/dist/maven/maven-#{mvn_major_version}/#{mvn_version}/binaries/apache-maven-#{mvn_version}-bin.tar.gz"
+ }
+ _cset(:mvn_archive_file) {
+ File.join(shared_path, 'tools', 'mvn', File.basename(URI.parse(mvn_archive_url).path))
+ }
+ _cset(:mvn_archive_file_local) {
+ File.join(File.expand_path('.'), 'tools', 'mvn', File.basename(URI.parse(mvn_archive_url).path))
+ }
+ _cset(:mvn_checksum_url) {
+ "#{mvn_archive_url}.md5"
+ }
+ _cset(:mvn_checksum_file) {
+ File.join(shared_path, 'tools', 'mvn', File.basename(URI.parse(mvn_checksum_url).path))
+ }
+ _cset(:mvn_checksum_file_local) {
+ File.join(File.expand_path('.'), 'tools', 'mvn', File.basename(URI.parse(mvn_checksum_url).path))
+ }
+ _cset(:mvn_checksum_cmd) {
+ case File.extname(File.basename(URI.parse(mvn_checksum_url).path))
+ when '.md5' then 'md5sum'
+ when '.sha1' then 'sha1sum'
+ end
+ }
+ _cset(:mvn_path) {
+ File.join(shared_path, 'tools', 'mvn', File.basename(URI.parse(mvn_archive_url).path, "-bin.tar.gz"))
+ }
+ _cset(:mvn_path_local) {
+ File.join(File.expand_path('.'), 'tools', 'mvn', File.basename(URI.parse(mvn_archive_url).path, "-bin.tar.gz"))
+ }
+ _cset(:mvn_bin) {
+ File.join(mvn_path, 'bin', 'mvn')
+ }
+ _cset(:mvn_bin_local) {
+ File.join(mvn_path_local, 'bin', 'mvn')
+ }
+ _cset(:mvn_cmd) {
+ if fetch(:mvn_java_home, nil)
+ "env JAVA_HOME=#{mvn_java_home} #{mvn_bin} #{mvn_options.join(' ')}"
+ else
+ "#{mvn_bin} #{mvn_options.join(' ')}"
+ end
+ }
+ _cset(:mvn_cmd_local) {
+ if fetch(:mvn_java_home_local, nil)
+ "env JAVA_HOME=#{mvn_java_home_local} #{mvn_bin_local} #{mvn_options_local.join(' ')}"
+ else
+ "#{mvn_bin_local} #{mvn_options_local.join(' ')}"
+ end
+ }
+ _cset(:mvn_project_path) {
+ release_path
+ }
+ _cset(:mvn_project_path_local) {
+ Dir.pwd
+ }
+ _cset(:mvn_target_path) {
+ File.join(mvn_project_path, 'target')
+ }
+ _cset(:mvn_target_path_local) {
+ File.join(mvn_project_path_local, File.basename(mvn_target_path))
+ }
+ _cset(:mvn_template_path, File.join(File.dirname(__FILE__), 'templates'))
+ _cset(:mvn_update_settings, false)
+ _cset(:mvn_update_settings_locally, false)
+ _cset(:mvn_settings_path) { mvn_project_path }
+ _cset(:mvn_settings_path_local) { mvn_project_path_local }
+ _cset(:mvn_settings, %w(settings.xml))
+ _cset(:mvn_settings_local, %w(settings.xml))
+ _cset(:mvn_cleanup_settings, [])
+ _cset(:mvn_cleanup_settings_local, [])
+ _cset(:mvn_compile_locally, false) # perform precompilation on localhost
+ _cset(:mvn_goals, %w(clean package))
+ _cset(:mvn_common_options) {
+ options = []
+ options << "-P#{mvn_profiles.join(',')}" unless fetch(:mvn_profiles, []).empty?
+ options << "-Dmaven.test.skip=true" if fetch(:mvn_skip_tests, false)
+ options << "-U" if fetch(:mvn_update_snapshots, false)
+ options << "-B"
+ options
+ }
+ _cset(:mvn_options) {
+ options = mvn_common_options + fetch(:mvn_extra_options, [])
+ if mvn_update_settings
+ settings = File.join(mvn_settings_path, mvn_settings.first)
+ options << "--settings=#{settings}"
+ end
+ options
+ }
+ _cset(:mvn_options_local) {
+ options = mvn_common_options + fetch(:mvn_extra_options_local, [])
+ if mvn_update_settings_locally
+ settings = File.join(mvn_settings_path_local, mvn_settings_local.first)
+ options << "--settings=#{settings}"
+ end
+ options
+ }
+
+ desc("Setup maven.")
+ task(:setup, :roles => :app, :except => { :no_release => true }) {
+ transaction {
+ install
+ update_settings if mvn_update_settings
+ setup_locally if mvn_compile_locally
+ }
+ }
+ after 'deploy:setup', 'mvn:setup'
+
+ desc("Setup maven locally.")
+ task(:setup_locally, :except => { :no_release => true }) {
+ transaction {
+ install_locally
+ update_settings_locally if mvn_update_settings_locally
+ }
+ }
+
+ def _validate_archive(archive_file, checksum_file)
+ if cmd = fetch(:mvn_checksum_cmd, nil)
+ "test `#{cmd} #{archive_file} | cut -d' ' -f1` = `cat #{checksum_file}`"
+ else
+ "true"
+ end
+ end
+
+ def _install(options={})
+ path = options.delete(:path)
+ bin = options.delete(:bin)
+ checksum_file = options.delete(:checksum_file)
+ checksum_url = options.delete(:checksum_url)
+ archive_file = options.delete(:archive_file)
+ archive_url = options.delete(:archive_url)
+ dirs = [ File.dirname(checksum_file), File.dirname(archive_file), File.dirname(path) ].uniq()
+ execute = []
+ execute << "mkdir -p #{dirs.join(' ')}"
+ execute << (<<-EOS).gsub(/\s+/, ' ').strip
+ if ! test -f #{archive_file}; then
+ ( rm -f #{checksum_file}; wget --no-verbose -O #{checksum_file} #{checksum_url} ) &&
+ wget --no-verbose -O #{archive_file} #{archive_url} &&
+ #{_validate_archive(archive_file, checksum_file)} || ( rm -f #{archive_file}; false ) &&
+ test -f #{archive_file};
+ fi
+ EOS
+ execute << (<<-EOS).gsub(/\s+/, ' ').strip
+ if ! test -x #{bin}; then
+ ( test -d #{path} || tar xf #{archive_file} -C #{File.dirname(path)} ) &&
+ test -x #{bin};
+ fi
+ EOS
+ execute.join(' && ')
+ end
+
+ task(:install, :roles => :app, :except => { :no_release => true }) {
+ run(_install(:path => mvn_path, :bin => mvn_bin,
+ :checksum_file => mvn_checksum_file, :checksum_url => mvn_checksum_url,
+ :archive_file => mvn_archive_file, :archive_url => mvn_archive_url))
+ run("#{mvn_cmd} --version")
+ }
+
+ task(:install_locally, :except => { :no_release => true }) {
+ run_locally(_install(:path => mvn_path_local, :bin => mvn_bin_local,
+ :checksum_file => mvn_checksum_file_local, :checksum_url => mvn_checksum_url,
+ :archive_file => mvn_archive_file_local, :archive_url => mvn_archive_url))
+ run_locally("#{mvn_cmd_local} --version")
+ }
+
+ task(:update_settings, :roles => :app, :except => { :no_release => true }) {
+ mvn_settings.each do |f|
+ safe_put(template(f, :path => mvn_template_path), File.join(mvn_settings_path, f))
+ end
+ run("rm -f #{mvn_cleanup_settings.map { |x| x.dump }.join(' ')}") unless mvn_cleanup_settings.empty?
+ }
+
+ task(:update_settings_locally, :except => { :no_release => true }) {
+ mvn_settings_local.each do |f|
+ File.write(File.join(mvn_settings_path_local, f), template(f, :path => mvn_template_path))
+ end
+ run_locally("rm -f #{mvn_cleanup_settings_local.map { |x| x.dump }.join(' ')}") unless mvn_cleanup_settings_local.empty?
+ }
+
+ desc("Update maven build.")
+ task(:update, :roles => :app, :except => { :no_release => true }) {
+ transaction {
+ if mvn_compile_locally
+ update_locally
+ else
+ execute
+ end
+ }
+ }
+ after 'deploy:finalize_update', 'mvn:update'
+
+ desc("Update maven build locally.")
+ task(:update_locally, :except => { :no_release => true }) {
+ transaction {
+ execute_locally
+ upload_locally
+ }
+ }
+
+ def _mvn(cmd, path, goals=[])
+ "cd #{path.dump} && #{cmd} #{goals.map { |s| s.dump }.join(' ')}"
+ end
+
+ def _mvn_parse_version(s)
+ # FIXME: is there any better way to get project version?
+ s.split(/(?:\r?\n)+/).reject { |line| /^\[[A-Z]+\]/ =~ line }.last
+ end
+
+ _cset(:mvn_release_build, false)
+ _cset(:mvn_snapshot_pattern, /-SNAPSHOT$/i)
+ _cset(:mvn_project_version) {
+ _mvn_parse_version(capture(_mvn(mvn_cmd, mvn_project_path, %w(-Dexpression=project.version help:evaluate))))
+ }
+ _cset(:mvn_project_version_local) {
+ _mvn_parse_version(run_locally(_mvn(mvn_cmd_local, mvn_project_path_local, %w(-Dexpression=project.version help:evaluate))))
+ }
+
+ def _validate_project_version(version_key)
+ if mvn_release_build
+ version = fetch(version_key)
+ if mvn_snapshot_pattern === version
+ abort("Skip to build project since \`#{version}' is a SNAPSHOT version.")
+ end
+ end
+ end
+
+ desc("Perform maven build.")
+ task(:execute, :roles => :app, :except => { :no_release => true }) {
+ on_rollback {
+ run(_mvn(mvn_cmd, mvn_project_path, %w(clean)))
+ }
+ _validate_project_version(:mvn_project_version)
+ run(_mvn(mvn_cmd, mvn_project_path, mvn_goals))
+ }
+
+ desc("Perform maven build locally.")
+ task(:execute_locally, :roles => :app, :except => { :no_release => true }) {
+ on_rollback {
+ run_locally(_mvn(mvn_cmd_local, mvn_project_path_local, %w(clean)))
+ }
+ _validate_project_version(:mvn_project_version_local)
+ cmdline = _mvn(mvn_cmd_local, mvn_project_path_local, mvn_goals)
+ logger.info(cmdline)
+ abort("execution failure") unless system(cmdline)
+ }
+
+ _cset(:mvn_tar, 'tar')
+ _cset(:mvn_tar_local, 'tar')
+ _cset(:mvn_target_archive) {
+ "#{mvn_target_path}.tar.gz"
+ }
+ _cset(:mvn_target_archive_local) {
+ "#{mvn_target_path_local}.tar.gz"
+ }
+ task(:upload_locally, :roles => :app, :except => { :no_release => true }) {
+ on_rollback {
+ run("rm -rf #{mvn_target_path} #{mvn_target_archive}")
+ }
+ begin
+ run_locally("cd #{File.dirname(mvn_target_path_local)} && #{mvn_tar_local} chzf #{mvn_target_archive_local} #{File.basename(mvn_target_path_local)}")
+ upload(mvn_target_archive_local, mvn_target_archive)
+ run("cd #{File.dirname(mvn_target_path)} && #{mvn_tar} xzf #{mvn_target_archive} && rm -f #{mvn_target_archive}")
+ ensure
+ run_locally("rm -f #{mvn_target_archive_local}")
+ end
+ }
+ }
+ }
+ end
end
end
+
+if Capistrano::Configuration.instance
+ Capistrano::Configuration.instance.extend(Capistrano::Maven)
+end
+
+# vim:set ft=ruby :