How to conditionally include one of two files in a .war package with Buildr?
Pergunta
We're using Buildr to package an application as a .war file. To streamline the automated deployment process further, I'd like to conditionally select one of these two files (from the directory src/main/resources
)...
database-hsql.properties
database-postgres.properties
...and have it included in the resulting .war with the name database.properties
. (In the same place inside the WAR, namely WEB-INF/classes/
, where files from src/main/resources
now end up.)
Any simple way to do this? Any approach would be fine — e.g. parameterising "package" (somehow) or defining two different tasks/targets (I'm not sure of the terminology) such as "package-hsql" & "package-pgsql" — as long as it works and is simple enough.
Relevant bits of buildfile
:
load 'dependencies'
require 'buildr/hibernate'
desc "..."
define "foo" do
project.version = VERSION_NUMBER
project.group = GROUP
manifest["Implementation-Vendor"] = COPYRIGHT
compile.with WICKET,GUAVA,GSON, ... [many more libs]
test.with MOCKITO
resources
test.compile.with SERVLET,_('src/main/webapp'),_('src/main/resources')
package(:war).with(:libs=> [WICKET,GUAVA,GSON, ... ])
end
Bonus question: how to execute an arbitrary shell command (I'd use something involving e.g. >>
or sed
) in each of the two cases to make changes to another config file? (I'd also want to "inject" some db settings to applicationContext.xml
from another file; this would be preferable to keeping two copies of that file in VCS with mostly identical content.)
Sorry if this is too basic; I'm a total newbie with Buildr, and don't really know Ruby. (And yes, it's not an optimal situation to be using a tool that no current team member is proficient with...) If anything needs clarifying, please point it out!
Solução
The usual way to parameterize a buildr build is with environment variables. So for instance you might design your build to be executed like so:
$ buildr package DATABASE=postgres
In your buildfile you might then have:
ENV['DATABASE'] ||= 'hsql' # this line makes the default 'hsql'
define "foo" do
# the rest of the definition
resources.enhance do
cp _(:source, :main, :resources, "database-#{ENV['DATABASE']}.properties"), _(:target, :resources, "database.properties")
end
end
This is the simplest solution; one thing you might consider a drawback is that it will copy the two database-*.properties
files in addition to the database.properties
file that you'll actually use. If that's a problem it could be worked around at the cost of some more complexity.
Bonus answer: You can execute an arbitrary shell command using system
. E.g., at the cost of subshelling I could have implemented the above as:
resources.enhance do
system("cp '#{_(:source, :main, :resources, "database-#{ENV['DATABASE']}.properties")}' '#{_(:target, :resources, "database.properties")}'")
end
If you are wanting to inject properties into a configuration file, you might want to look at Buildr's filter mechanism.