capistrano-maven 0.0.7 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -26,28 +26,27 @@ This recipes will try to do following things during Capistrano `deploy:setup` an
26
26
 
27
27
  To build you Maven projects during Capistrano `deploy` tasks, add following in you `config/deploy.rb`. By default, Maven build will run after the Capistrano's `deploy:finalize_update`.
28
28
 
29
- # in "config/deploy.rb"
30
- require 'capistrano-maven'
31
- set(:mvn_version, '3.0.4') # Maven version to build project
29
+ # config/deploy.rb
30
+ require "capistrano-maven"
31
+ set(:mvn_version, "3.0.5") # Maven version to build project
32
32
 
33
33
  Following options are available to manage your Maven build.
34
34
 
35
- * `:mvn_version` - project Maven version
36
- * `:mvn_archive_url` - download URL for specified Maven version
37
- * `:mvn_compile_locally` - compile project on localhost. false by default.
38
- * `:mvn_goals` - Maven goals to execute. default is "clean package".
35
+ * `:mvn_version` - The project Maven version.
36
+ * `:mvn_archive_url` - The download URL for specified Maven version.
37
+ * `:mvn_setup_remotely` - Setup `mvn` on remote servers. As same value as `:mvn_update_remotely` by default.
38
+ * `:mvn_setup_locally` - Setup `mvn` on local server. Asa same value as `:mvn_update_locally` by default.
39
+ * `:mvn_update_remotely` - Run `mvn` on remote servers. `true` by default.
40
+ * `:mvn_update_locally` - Run `mvn` on local server. `false` by default.
41
+ * `:mvn_goals` - Maven goals to execute. Run `clean package` by default.
42
+ * `:mvn_settings` - List of your optional setting files for Maven.
43
+ * `:mvn_settings_local` - List of your optional setting files for Maven.
44
+ * `:mvn_template_path` - The local path where the templates of setting files are in. By default, searches from `config/templates`.
45
+ * `:mvn_java_home` - Optional `JAVA_HOME` settings for Maven commands.
46
+ * `:mvn_java_home_local` - Optional `JAVA_HOME` settings for Maven commands in localhost.
39
47
  * `:mvn_profiles` - Maven profiles to use.
40
- * `:mvn_skip_tests` - add `-Dmaven.test.skip=true` in Maven commands. false by default.
41
- * `:mvn_update_snapshots` - add `--update-snapshots` if Maven commands. false by default.
42
- * `:mvn_update_settings` - update `settings.xml` or not. false by default.
43
- * `:mvn_update_settings_locally` - udate `settings.xml` or not on local compilation. false by default.
44
- * `:mvn_settings` - list of your optional setting files for Maven. use `%w(settings.xml)` by default.
45
- * `:mvn_settings_local` - list of your optional setting files for Maven. use `%w(settings.xml)` by default.
46
- * `:mvn_settings_path` - the destination path of the optional `settings.xml` file. use `:release_path` by default.
47
- * `:mvn_settings_path_local` - the destination path of the optional `settings.xml` file. use `pwd` by default.
48
- * `:mvn_template_path` - specify ERB template path for settings.xml.
49
- * `:mvn_java_home` - optional `JAVA_HOME` settings for Maven commands.
50
- * `:mvn_java_home_local` - optional `JAVA_HOME` settings for Maven commands in localhost.
48
+ * `:mvn_skip_tests` - Add `-Dmaven.test.skip=true` in Maven commands. `false` by default.
49
+ * `:mvn_update_snapshots` - Add `-U` if Maven commands. `false` by default.
51
50
  * `:mvn_release_build` - Skip building on SNAPSHOT version. `false` by default.
52
51
 
53
52
  ## Contributing
@@ -16,6 +16,10 @@ Gem::Specification.new do |gem|
16
16
  gem.version = Capistrano::Maven::VERSION
17
17
 
18
18
  gem.add_dependency("capistrano")
19
- gem.add_dependency("capistrano-file-resources", "~> 0.0.1")
20
- gem.add_dependency("capistrano-file-transfer-ext", "~> 0.0.3")
19
+ gem.add_dependency("capistrano-file-resources", "~> 0.1.0")
20
+ gem.add_dependency("capistrano-file-transfer-ext", "~> 0.1.0")
21
+ gem.add_development_dependency("capistrano-jdk-installer", "~> 0.1.0")
22
+ gem.add_development_dependency("net-scp", "~> 1.0.4")
23
+ gem.add_development_dependency("net-ssh", "~> 2.2.2")
24
+ gem.add_development_dependency("vagrant", "~> 1.0.6")
21
25
  end
@@ -9,276 +9,338 @@ module Capistrano
9
9
  def self.extended(configuration)
10
10
  configuration.load {
11
11
  namespace(:mvn) {
12
- _cset(:mvn_version, '3.0.4')
13
- _cset(:mvn_major_version) {
14
- mvn_version.split('.').first.to_i
15
- }
12
+ _cset(:mvn_roles, [:app])
13
+ _cset(:mvn_version, "3.0.5")
14
+ _cset(:mvn_major_version) { mvn_version.split(".").first.to_i }
16
15
  _cset(:mvn_archive_url) {
17
16
  "http://www.apache.org/dist/maven/maven-#{mvn_major_version}/#{mvn_version}/binaries/apache-maven-#{mvn_version}-bin.tar.gz"
18
17
  }
19
- _cset(:mvn_archive_file) {
20
- File.join(shared_path, 'tools', 'mvn', File.basename(URI.parse(mvn_archive_url).path))
21
- }
22
- _cset(:mvn_archive_file_local) {
23
- File.join(File.expand_path('.'), 'tools', 'mvn', File.basename(URI.parse(mvn_archive_url).path))
24
- }
25
- _cset(:mvn_checksum_url) {
26
- "#{mvn_archive_url}.md5"
27
- }
28
- _cset(:mvn_checksum_file) {
29
- File.join(shared_path, 'tools', 'mvn', File.basename(URI.parse(mvn_checksum_url).path))
30
- }
31
- _cset(:mvn_checksum_file_local) {
32
- File.join(File.expand_path('.'), 'tools', 'mvn', File.basename(URI.parse(mvn_checksum_url).path))
33
- }
34
- _cset(:mvn_checksum_cmd) {
35
- case File.extname(File.basename(URI.parse(mvn_checksum_url).path))
36
- when '.md5' then 'md5sum'
37
- when '.sha1' then 'sha1sum'
18
+ _cset(:mvn_tools_path) { File.join(shared_path, "tools", "mvn") }
19
+ _cset(:mvn_tools_path_local) { File.expand_path("tools/mvn") }
20
+ _cset(:mvn_archive_path) { mvn_tools_path }
21
+ _cset(:mvn_archive_path_local) { mvn_tools_path_local }
22
+ _cset(:mvn_archive_file) { File.join(mvn_archive_path, File.basename(URI.parse(mvn_archive_url).path)) }
23
+ _cset(:mvn_archive_file_local) { File.join(mvn_archive_path_local, File.basename(URI.parse(mvn_archive_url).path)) }
24
+ _cset(:mvn_path) { File.join(mvn_tools_path, File.basename(URI.parse(mvn_archive_url).path, "-bin.tar.gz")) }
25
+ _cset(:mvn_path_local) { File.join(mvn_tools_path_local, File.basename(URI.parse(mvn_archive_url).path, "-bin.tar.gz")) }
26
+ _cset(:mvn_bin_path) { File.join(mvn_path, "bin") }
27
+ _cset(:mvn_bin_path_local) { File.join(mvn_path_local, "bin") }
28
+ _cset(:mvn_bin) { File.join(mvn_bin_path, "mvn") }
29
+ _cset(:mvn_bin_local) { File.join(mvn_bin_path_local, "mvn") }
30
+ _cset(:mvn_project_path) { release_path }
31
+ _cset(:mvn_project_path_local) { File.expand_path(".") }
32
+ _cset(:mvn_template_path) { File.expand_path("config/templates") }
33
+
34
+ ## Maven environment
35
+ _cset(:mvn_common_environment, {})
36
+ _cset(:mvn_default_environment) {
37
+ environment = {}
38
+ environment["JAVA_HOME"] = fetch(:mvn_java_home) if exists?(:mvn_java_home)
39
+ if exists?(:mvn_java_options)
40
+ environment["MAVEN_OPTS"] = [ fetch(:mvn_java_options, []) ].flatten.join(" ")
38
41
  end
39
- }
40
- _cset(:mvn_path) {
41
- File.join(shared_path, 'tools', 'mvn', File.basename(URI.parse(mvn_archive_url).path, "-bin.tar.gz"))
42
- }
43
- _cset(:mvn_path_local) {
44
- File.join(File.expand_path('.'), 'tools', 'mvn', File.basename(URI.parse(mvn_archive_url).path, "-bin.tar.gz"))
45
- }
46
- _cset(:mvn_bin) {
47
- File.join(mvn_path, 'bin', 'mvn')
48
- }
49
- _cset(:mvn_bin_local) {
50
- File.join(mvn_path_local, 'bin', 'mvn')
51
- }
52
- _cset(:mvn_cmd) {
53
- if fetch(:mvn_java_home, nil)
54
- "env JAVA_HOME=#{mvn_java_home} #{mvn_bin} #{mvn_options.join(' ')}"
55
- else
56
- "#{mvn_bin} #{mvn_options.join(' ')}"
42
+ environment["PATH"] = [ mvn_bin_path, "$PATH" ].join(":") if mvn_setup_remotely
43
+ _merge_environment(mvn_common_environment, environment)
44
+ }
45
+ _cset(:mvn_default_environment_local) {
46
+ environment = {}
47
+ environment["JAVA_HOME"] = fetch(:mvn_java_home_local) if exists?(:mvn_java_home_local)
48
+ if exists?(:mvn_java_options_local)
49
+ environment["MAVEN_OPTS"] = [ fetch(:mvn_java_options_local, []) ].flatten.join(" ")
57
50
  end
58
- }
59
- _cset(:mvn_cmd_local) {
60
- if fetch(:mvn_java_home_local, nil)
61
- "env JAVA_HOME=#{mvn_java_home_local} #{mvn_bin_local} #{mvn_options_local.join(' ')}"
51
+ environment["PATH"] = [ mvn_bin_path_local, "$PATH" ].join(":") if mvn_setup_locally
52
+ _merge_environment(mvn_common_environment, environment)
53
+ }
54
+ _cset(:mvn_environment) { _merge_environment(mvn_default_environment, fetch(:mvn_extra_environment, {})) }
55
+ _cset(:mvn_environment_local) { _merge_environment(mvn_default_environment_local, fetch(:mvn_extra_environment_local, {})) }
56
+ def _command(cmdline, options={})
57
+ environment = options.fetch(:env, {})
58
+ if environment.empty?
59
+ cmdline
62
60
  else
63
- "#{mvn_bin_local} #{mvn_options_local.join(' ')}"
61
+ env = (["env"] + environment.map { |k, v| "#{k}=#{v.dump}" }).join(" ")
62
+ "#{env} #{cmdline}"
64
63
  end
65
- }
66
- _cset(:mvn_project_path) {
67
- release_path
68
- }
69
- _cset(:mvn_project_path_local) {
70
- Dir.pwd
71
- }
72
- _cset(:mvn_target_path) {
73
- File.join(mvn_project_path, 'target')
74
- }
75
- _cset(:mvn_target_path_local) {
76
- File.join(mvn_project_path_local, File.basename(mvn_target_path))
77
- }
78
- _cset(:mvn_template_path, File.join(File.dirname(__FILE__), 'templates'))
79
- _cset(:mvn_update_settings, false)
80
- _cset(:mvn_update_settings_locally, false)
81
- _cset(:mvn_settings_path) { mvn_project_path }
82
- _cset(:mvn_settings_path_local) { mvn_project_path_local }
83
- _cset(:mvn_settings, %w(settings.xml))
84
- _cset(:mvn_settings_local, %w(settings.xml))
85
- _cset(:mvn_cleanup_settings, [])
86
- _cset(:mvn_cleanup_settings_local, [])
87
- _cset(:mvn_compile_locally, false) # perform precompilation on localhost
64
+ end
65
+ def command(cmdline, options={})
66
+ _command(cmdline, :env => mvn_environment.merge(options.fetch(:env, {})))
67
+ end
68
+ def command_local(cmdline, options={})
69
+ _command(cmdline, :env => mvn_environment_local.merge(options.fetch(:env, {})))
70
+ end
71
+ _cset(:mvn_cmd) { command("#{mvn_bin.dump} #{mvn_options.map { |x| x.dump }.join(" ")}") }
72
+ _cset(:mvn_cmd_local) { command_local("#{mvn_bin_local.dump} #{mvn_options_local.map { |x| x.dump }.join(" ")}") }
88
73
  _cset(:mvn_goals, %w(clean package))
89
74
  _cset(:mvn_common_options) {
90
75
  options = []
91
- options << "-P#{mvn_profiles.join(',')}" unless fetch(:mvn_profiles, []).empty?
76
+ options << "-P#{mvn_profiles.join(",")}" unless fetch(:mvn_profiles, []).empty?
92
77
  options << "-Dmaven.test.skip=true" if fetch(:mvn_skip_tests, false)
93
78
  options << "-U" if fetch(:mvn_update_snapshots, false)
94
79
  options << "-B"
95
80
  options
96
81
  }
97
- _cset(:mvn_options) {
98
- options = mvn_common_options + fetch(:mvn_extra_options, [])
99
- if mvn_update_settings
100
- settings = File.join(mvn_settings_path, mvn_settings.first)
101
- options << "--settings=#{settings}"
102
- end
82
+ _cset(:mvn_default_options) {
83
+ options = mvn_common_options.dup
84
+ options += mvn_settings.map { |s| "--settings=#{File.join(mvn_settings_path, s).dump}" } if mvn_update_settings
103
85
  options
104
86
  }
105
- _cset(:mvn_options_local) {
106
- options = mvn_common_options + fetch(:mvn_extra_options_local, [])
107
- if mvn_update_settings_locally
108
- settings = File.join(mvn_settings_path_local, mvn_settings_local.first)
109
- options << "--settings=#{settings}"
110
- end
87
+ _cset(:mvn_default_options_local) {
88
+ options = mvn_common_options.dup
89
+ options += mvn_settings_local.map { |s| "--settings=#{File.join(mvn_settings_path_local, s).dump}" } if mvn_update_settings_locally
111
90
  options
112
91
  }
92
+ _cset(:mvn_options) { mvn_default_options + fetch(:mvn_extra_options, []) }
93
+ _cset(:mvn_options_local) { mvn_default_options_local + fetch(:mvn_extra_options_local, []) }
113
94
 
114
- desc("Setup maven.")
115
- task(:setup, :roles => :app, :except => { :no_release => true }) {
116
- transaction {
117
- install
118
- update_settings if mvn_update_settings
119
- setup_locally if mvn_compile_locally
120
- }
95
+ _cset(:mvn_setup_remotely) { mvn_update_remotely }
96
+ _cset(:mvn_setup_locally) { mvn_update_locally }
97
+ _cset(:mvn_update_remotely) { not(mvn_update_locally) }
98
+ _cset(:mvn_update_locally) { # perform update on localhost
99
+ if exists?(:mvn_compile_locally)
100
+ logger.info(":mvn_compile_locally has been deprecated. use :mvn_update_locally instead.")
101
+ fetch(:mvn_compile_locally, false)
102
+ else
103
+ false
104
+ end
121
105
  }
122
- after 'deploy:setup', 'mvn:setup'
123
106
 
124
- desc("Setup maven locally.")
125
- task(:setup_locally, :except => { :no_release => true }) {
126
- transaction {
127
- install_locally
128
- update_settings_locally if mvn_update_settings_locally
107
+ if top.namespaces.key?(:multistage)
108
+ after "multistage:ensure", "mvn:setup_default_environment"
109
+ else
110
+ on :start do
111
+ if top.namespaces.key?(:multistage)
112
+ after "multistage:ensure", "mvn:setup_default_environment"
113
+ else
114
+ setup_default_environment
115
+ end
116
+ end
117
+ end
118
+
119
+ _cset(:mvn_environment_join_keys, %w(DYLD_LIBRARY_PATH LD_LIBRARY_PATH MANPATH PATH))
120
+ def _merge_environment(x, y)
121
+ x.merge(y) { |key, x_val, y_val|
122
+ if mvn_environment_join_keys.include?(key)
123
+ ( y_val.split(":") + x_val.split(":") ).uniq.join(":")
124
+ else
125
+ y_val
126
+ end
129
127
  }
128
+ end
129
+
130
+ task(:setup_default_environment, :roles => mvn_roles, :except => { :no_release => true }) {
131
+ if fetch(:mvn_setup_default_environment, true)
132
+ set(:default_environment, _merge_environment(default_environment, mvn_environment))
133
+ end
130
134
  }
131
135
 
132
- def _validate_archive(archive_file, checksum_file)
133
- if cmd = fetch(:mvn_checksum_cmd, nil)
134
- "test `#{cmd} #{archive_file} | cut -d' ' -f1` = `cat #{checksum_file}`"
136
+ def _invoke_command(cmdline, options={})
137
+ if options[:via] == :run_locally
138
+ run_locally(cmdline)
135
139
  else
136
- "true"
140
+ invoke_command(cmdline, options)
137
141
  end
138
142
  end
139
143
 
140
- def _install(options={})
141
- path = options.delete(:path)
142
- bin = options.delete(:bin)
143
- checksum_file = options.delete(:checksum_file)
144
- checksum_url = options.delete(:checksum_url)
145
- archive_file = options.delete(:archive_file)
146
- archive_url = options.delete(:archive_url)
147
- dirs = [ File.dirname(checksum_file), File.dirname(archive_file), File.dirname(path) ].uniq()
144
+ def _download(uri, filename, options={})
145
+ options = fetch(:mvn_download_options, {}).merge(options)
146
+ if FileTest.exist?(filename)
147
+ logger.info("Found downloaded archive: #{filename}")
148
+ else
149
+ dirs = [ File.dirname(filename) ]
150
+ execute = []
151
+ execute << "mkdir -p #{dirs.uniq.map { |x| x.dump }.join(" ")}"
152
+ execute << "wget --no-verbose -O #{filename.dump} #{uri.dump}"
153
+ _invoke_command(execute.join(" && "), options)
154
+ end
155
+ end
156
+
157
+ def _upload(filename, remote_filename, options={})
158
+ _invoke_command("mkdir -p #{File.dirname(remote_filename).dump}", options)
159
+ transfer_if_modified(:up, filename, remote_filename, fetch(:mvn_upload_options, {}).merge(options))
160
+ end
161
+
162
+ def _install(filename, destination, options={})
148
163
  execute = []
149
- execute << "mkdir -p #{dirs.join(' ')}"
150
- execute << (<<-EOS).gsub(/\s+/, ' ').strip
151
- if ! test -f #{archive_file}; then
152
- ( rm -f #{checksum_file}; wget --no-verbose -O #{checksum_file} #{checksum_url} ) &&
153
- wget --no-verbose -O #{archive_file} #{archive_url} &&
154
- #{_validate_archive(archive_file, checksum_file)} || ( rm -f #{archive_file}; false ) &&
155
- test -f #{archive_file};
156
- fi
157
- EOS
158
- execute << (<<-EOS).gsub(/\s+/, ' ').strip
159
- if ! test -x #{bin}; then
160
- ( test -d #{path} || tar xf #{archive_file} -C #{File.dirname(path)} ) &&
161
- test -x #{bin};
162
- fi
163
- EOS
164
- execute.join(' && ')
164
+ execute << "mkdir -p #{File.dirname(destination).dump}"
165
+ execute << "tar xf #{filename.dump} -C #{File.dirname(destination).dump}"
166
+ _invoke_command(execute.join(" && "), options)
167
+ end
168
+
169
+ def _installed?(destination, options={})
170
+ mvn = File.join(destination, "bin", "mvn")
171
+ cmdline = "test -d #{destination.dump} && test -x #{mvn.dump}"
172
+ _invoke_command(cmdline, options)
173
+ true
174
+ rescue
175
+ false
165
176
  end
166
177
 
167
- task(:install, :roles => :app, :except => { :no_release => true }) {
168
- run(_install(:path => mvn_path, :bin => mvn_bin,
169
- :checksum_file => mvn_checksum_file, :checksum_url => mvn_checksum_url,
170
- :archive_file => mvn_archive_file, :archive_url => mvn_archive_url))
171
- run("#{mvn_cmd} --version")
178
+ ## setup
179
+ desc("Setup maven.")
180
+ task(:setup, :roles => mvn_roles, :except => { :no_release => true }) {
181
+ transaction {
182
+ setup_remotely if mvn_setup_remotely
183
+ setup_locally if mvn_setup_locally
184
+ }
185
+ }
186
+ after "deploy:setup", "mvn:setup"
187
+
188
+ task(:setup_remotely, :roles => mvn_roles, :except => { :no_release => true }) {
189
+ _download(mvn_archive_url, mvn_archive_file_local, :via => :run_locally)
190
+ _upload(mvn_archive_file_local, mvn_archive_file)
191
+ unless _installed?(mvn_path)
192
+ _install(mvn_archive_file, mvn_path)
193
+ _installed?(mvn_path)
194
+ end
195
+ update_settings if mvn_update_settings
172
196
  }
173
197
 
174
- task(:install_locally, :except => { :no_release => true }) {
175
- run_locally(_install(:path => mvn_path_local, :bin => mvn_bin_local,
176
- :checksum_file => mvn_checksum_file_local, :checksum_url => mvn_checksum_url,
177
- :archive_file => mvn_archive_file_local, :archive_url => mvn_archive_url))
178
- run_locally("#{mvn_cmd_local} --version")
198
+ desc("Setup maven locally.")
199
+ task(:setup_locally, :roles => mvn_roles, :except => { :no_release => true }) {
200
+ _download(mvn_archive_url, mvn_archive_file_local, :via => :run_locally)
201
+ unless _installed?(mvn_path_local, :via => :run_locally)
202
+ _install(mvn_archive_file_local, mvn_path_local, :via => :run_locally)
203
+ _installed?(mvn_path_local, :via => :run_locally)
204
+ end
205
+ update_settings_locally if mvn_update_settings_locally
179
206
  }
180
207
 
181
- task(:update_settings, :roles => :app, :except => { :no_release => true }) {
182
- mvn_settings.each do |f|
183
- safe_put(template(f, :path => mvn_template_path), File.join(mvn_settings_path, f))
208
+ _cset(:mvn_update_settings) { mvn_setup_remotely and not(mvn_settings.empty?) }
209
+ _cset(:mvn_update_settings_locally) { mvn_setup_locally and not(mvn_settings_local.empty?) }
210
+ _cset(:mvn_settings_path) { mvn_tools_path }
211
+ _cset(:mvn_settings_path_local) { mvn_tools_path_local }
212
+ _cset(:mvn_settings, [])
213
+ _cset(:mvn_settings_local) { mvn_settings }
214
+ task(:update_settings, :roles => mvn_roles, :except => { :no_release => true }) {
215
+ mvn_settings.each do |file|
216
+ safe_put(template(file, :path => mvn_template_path), File.join(mvn_settings_path, file))
184
217
  end
185
- run("rm -f #{mvn_cleanup_settings.map { |x| x.dump }.join(' ')}") unless mvn_cleanup_settings.empty?
186
218
  }
187
219
 
188
- task(:update_settings_locally, :except => { :no_release => true }) {
189
- mvn_settings_local.each do |f|
190
- File.write(File.join(mvn_settings_path_local, f), template(f, :path => mvn_template_path))
220
+ task(:update_settings_locally, :roles => mvn_roles, :except => { :no_release => true }) {
221
+ mvn_settings_local.each do |file|
222
+ destination = File.join(mvn_settings_path_local, file)
223
+ run_locally("mkdir -p #{File.dirname(destination).dump}")
224
+ File.write(destination, template(file, :path => mvn_template_path))
191
225
  end
192
- run_locally("rm -f #{mvn_cleanup_settings_local.map { |x| x.dump }.join(' ')}") unless mvn_cleanup_settings_local.empty?
193
226
  }
194
227
 
228
+ ## update
195
229
  desc("Update maven build.")
196
- task(:update, :roles => :app, :except => { :no_release => true }) {
230
+ task(:update, :roles => mvn_roles, :except => { :no_release => true }) {
197
231
  transaction {
198
- if mvn_compile_locally
199
- update_locally
200
- else
201
- execute
202
- end
232
+ update_remotely if mvn_update_remotely
233
+ update_locally if mvn_update_locally
203
234
  }
204
235
  }
205
- after 'deploy:finalize_update', 'mvn:update'
236
+ _cset(:mvn_update_hook_type, :after)
237
+ _cset(:mvn_update_hook, "deploy:finalize_update")
238
+ on(:start) do
239
+ [ mvn_update_hook ].flatten.each do |hook|
240
+ send(mvn_update_hook_type, hook, "mvn:update") if hook
241
+ end
242
+ end
206
243
 
207
- desc("Update maven build locally.")
208
- task(:update_locally, :except => { :no_release => true }) {
209
- transaction {
210
- execute_locally
211
- upload_locally
212
- }
244
+ task(:update_remotely, :roles => mvn_roles, :except => { :no_release => true }) {
245
+ execute_remotely
213
246
  }
214
247
 
215
- def _mvn(cmd, path, goals=[])
216
- "cd #{path.dump} && #{cmd} #{goals.map { |s| s.dump }.join(' ')}"
217
- end
248
+ desc("Update maven build locally.")
249
+ task(:update_locally, :roles => mvn_roles, :except => { :no_release => true }) {
250
+ execute_locally
251
+ upload_locally
252
+ }
218
253
 
219
- def _mvn_parse_version(s)
254
+ def _parse_project_version(s)
220
255
  # FIXME: is there any better way to get project version?
221
256
  s.split(/(?:\r?\n)+/).reject { |line| /^\[[A-Z]+\]/ =~ line }.last
222
257
  end
223
258
 
224
- _cset(:mvn_release_build, false)
225
- _cset(:mvn_snapshot_pattern, /-SNAPSHOT$/i)
226
259
  _cset(:mvn_project_version) {
227
- _mvn_parse_version(capture(_mvn(mvn_cmd, mvn_project_path, %w(-Dexpression=project.version help:evaluate))))
260
+ _parse_project_version(mvn.exec(%w(-Dexpression=project.version help:evaluate), :via => :capture))
228
261
  }
229
262
  _cset(:mvn_project_version_local) {
230
- _mvn_parse_version(run_locally(_mvn(mvn_cmd_local, mvn_project_path_local, %w(-Dexpression=project.version help:evaluate))))
263
+ _parse_project_version(mvn.exec_locally(%w(-Dexpression=project.version help:evaluate), :via => :capture_locally))
231
264
  }
232
-
233
- def _validate_project_version(version_key)
234
- if mvn_release_build
235
- version = fetch(version_key)
236
- if mvn_snapshot_pattern === version
237
- abort("Skip to build project since \`#{version}' is a SNAPSHOT version.")
238
- end
265
+ _cset(:mvn_snapshot_pattern, /-SNAPSHOT$/i)
266
+ def _validate_project_version(key)
267
+ if fetch(:mvn_release_build, false)
268
+ version = fetch(key)
269
+ abort("Skip to build project since \`#{version}' is a SNAPSHOT version.") if mvn_snapshot_pattern === version
239
270
  end
240
271
  end
241
272
 
242
273
  desc("Perform maven build.")
243
- task(:execute, :roles => :app, :except => { :no_release => true }) {
244
- on_rollback {
245
- run(_mvn(mvn_cmd, mvn_project_path, %w(clean)))
246
- }
274
+ task(:execute, :roles => mvn_roles, :except => { :no_release => true }) {
275
+ execute_remotely
276
+ }
277
+ task(:execute_remotely, :roles => mvn_roles, :except => { :no_release => true }) {
278
+ on_rollback do
279
+ mvn.exec("clean")
280
+ end
247
281
  _validate_project_version(:mvn_project_version)
248
- run(_mvn(mvn_cmd, mvn_project_path, mvn_goals))
282
+ mvn.exec(mvn_goals)
249
283
  }
250
284
 
251
285
  desc("Perform maven build locally.")
252
- task(:execute_locally, :roles => :app, :except => { :no_release => true }) {
253
- on_rollback {
254
- run_locally(_mvn(mvn_cmd_local, mvn_project_path_local, %w(clean)))
255
- }
286
+ task(:execute_locally, :roles => mvn_roles, :except => { :no_release => true }) {
287
+ on_rollback do
288
+ mvn.exec_locally("clean")
289
+ end
256
290
  _validate_project_version(:mvn_project_version_local)
257
- cmdline = _mvn(mvn_cmd_local, mvn_project_path_local, mvn_goals)
258
- logger.info(cmdline)
259
- abort("execution failure") unless system(cmdline)
291
+ mvn.exec_locally(mvn_goals)
260
292
  }
261
293
 
262
- _cset(:mvn_tar, 'tar')
263
- _cset(:mvn_tar_local, 'tar')
264
- _cset(:mvn_target_archive) {
265
- "#{mvn_target_path}.tar.gz"
266
- }
267
- _cset(:mvn_target_archive_local) {
268
- "#{mvn_target_path_local}.tar.gz"
269
- }
270
- task(:upload_locally, :roles => :app, :except => { :no_release => true }) {
271
- on_rollback {
272
- run("rm -rf #{mvn_target_path} #{mvn_target_archive}")
273
- }
294
+ _cset(:mvn_target_path) { File.join(mvn_project_path, "target") }
295
+ _cset(:mvn_target_path_local) { File.join(mvn_project_path_local, "target") }
296
+ task(:upload_locally, :roles => mvn_roles, :except => { :no_release => true }) {
297
+ on_rollback do
298
+ run("rm -rf #{mvn_target_path.dump}")
299
+ end
300
+ filename = "#{mvn_target_path_local}.tar.gz"
301
+ remote_filename = "#{mvn_target_path}.tar.gz"
274
302
  begin
275
- run_locally("cd #{File.dirname(mvn_target_path_local)} && #{mvn_tar_local} chzf #{mvn_target_archive_local} #{File.basename(mvn_target_path_local)}")
276
- upload(mvn_target_archive_local, mvn_target_archive)
277
- run("cd #{File.dirname(mvn_target_path)} && #{mvn_tar} xzf #{mvn_target_archive} && rm -f #{mvn_target_archive}")
303
+ run_locally("cd #{File.dirname(mvn_target_path_local).dump} && tar chzf #{filename.dump} #{File.basename(mvn_target_path_local).dump}")
304
+ run("mkdir -p #{File.dirname(mvn_target_path).dump}")
305
+ top.upload(filename, remote_filename)
306
+ run("cd #{File.dirname(mvn_target_path).dump} && tar xzf #{remote_filename.dump}")
278
307
  ensure
279
- run_locally("rm -f #{mvn_target_archive_local}")
308
+ run("rm -f #{remote_filename.dump}") rescue nil
309
+ run_locally("rm -f #{filename.dump}") rescue nil
280
310
  end
281
311
  }
312
+
313
+ def _exec_command(args=[], options={})
314
+ args = [ args ].flatten
315
+ mvn = options.fetch(:mvn, "mvn")
316
+ execute = []
317
+ execute << "cd #{options[:path].dump}" if options.key?(:path)
318
+ execute << "#{mvn} #{args.map { |x| x.dump }.join(" ")}"
319
+ execute.join(" && ")
320
+ end
321
+
322
+ ## public methods
323
+ def exec(args=[], options={})
324
+ cmdline = _exec_command(args, { :path => mvn_project_path, :mvn => mvn_cmd, :via => :run }.merge(options))
325
+ _invoke_command(cmdline, options)
326
+ end
327
+
328
+ def exec_locally(args=[], options={})
329
+ via = options.delete(:via)
330
+ cmdline = _exec_command(args, { :path => mvn_project_path_local, :mvn => mvn_cmd_local, :via => :run_locally }.merge(options))
331
+ if via == :capture_locally
332
+ _invoke_command(cmdline, options.merge(:via => :run_locally))
333
+ else
334
+ logger.trace("executing locally: #{cmdline.dump}")
335
+ elapsed = Benchmark.realtime do
336
+ system(cmdline)
337
+ end
338
+ if $?.to_i > 0 # $? is command exit code (posix style)
339
+ raise Capistrano::LocalArgumentError, "Command #{cmd} returned status code #{$?}"
340
+ end
341
+ logger.trace "command finished in #{(elapsed * 1000).round}ms"
342
+ end
343
+ end
282
344
  }
283
345
  }
284
346
  end