Is it possible to define different profiles in gradle? I've written a WebApplication and i want to deploy it with the production settings. Furthermore my app is using PrettyFaces. Since i'm using different two languages i also want a language sepcific build. Here is my use case:
production/en, production/ru
The build with a specific language indicates which db to use and which language is the default one. Furthermore the urls (PrettyFaces) are different files. In my opinion i need a different web.xml and a different pretty-faces.xml ?
Thanks in advance!
Here are some options:
Create a task for each setting, so you can do gradle buildEn or gradle buildRu to differentiate the builds. You can write each task manually, or dynamically generate them.
Pass a project property to your build, e.g. gradle build -Plang=ru. Then you can reference lang from your task and do the logic there. Project properties can also be specified in gradle.properties file if you don't like passing the property every time. Anyway check this out.
Probably not what you want, but you can add behaviour to your build if a certain task is present in the build graph (in the example additional logic is executed when graph contains release task).
Good luck
Related
I know you can access different modules (included using include) in a project via org.gradle.api.Project#getSubprojects(), and I know you can get the name and directories of separate builds that have been included (using includeBuild) via org.gradle.api.invocation.Gradle#getIncludedBuilds().
But how can my plugin get information such as the locations of Java source files and class files for projects included using includeBuild?
My goal here is to determine which files have changed in the current git branch (which I can do), and then collect their corresponding class files into a jar file that's used for our patching mechanism that inserts the patch jars at the front of the classpath rather than redeploying the whole application.
I don’t think it is a goal of Gradle to provide including builds with detailed information on included builds. Currently, the Gradle docs basically only state two goals for such composite builds:
combine builds that are usually developed independently, […]
decompose a large multi-project build into smaller, more isolated chunks […]
Actually, isolation between the involved builds seems to be an important theme in general:
Included builds do not share any configuration with the composite build, or the other included builds. Each included build is configured and executed in isolation.
For that reason, it also doesn’t seem to be possible or even desired to let an including build consume any build configurations (like task outputs) of an included build. That would only couple the builds and hence thwart the isolation goal.
Included builds interact with other builds only via dependency substitution:
If any build in the composite has a dependency that can be satisfied by the included build, then that dependency will be replaced by a project dependency on the included build.
So, if you’d like to consume specific parts of an included build from the including build, then you have to do multiple things:
Have a configuration in the included build which produces these “specific parts” as an artifact.
Have a configuration in the including build which consumes the artifact as a dependency.
Make sure that both configurations are compatible wrt. their capabilities so that dependency substitution works.
Let some task in the including build use the dependency artifact in whatever way you need.
Those things happen kind of automatically when you have a simple dependency between two Gradle projects, like a Java application depending on a Java library. But you can define your own kinds of dependencies, too.
The question is: would that really be worth the effort? Can’t you maybe solve your goal more easily or at least without relying on programmatically retrieved information on included builds? For example: if you know that your included build produces class files under build/classes/java/main, then maybe just take the classes of interest from there via org.gradle.api.initialization.IncludedBuild#getProjectDir().
I know, this may not be the answer you had hoped to get. I still hope it’s useful.
We have a directory structure like so
java
build/build.gradle (This does NOT exist yet, but we want this)
servers
server1/build.gradle
server2/build.gradle
libraries
lib1/build.gradle
lib2/build.gradle
We have 11 servers and 14 libraries with varying uses of dependencies. EACH server is a composite build ONLY depending on libraries (we don’t allow servers to depend on each other). In this way, as our mono-repo grows, opening up server1 does NOT get slower and slower as more and more gradle code is added(ie. gradle only loads server1 and all it’s libraries and none of the other libraries OR servers are loaded keeping things FAST).
Ok, so one problem we are running into is duplication now which is why we need build/build.gradle file AND we want EVERY module in our mono repo to include that somehow for a few goals(each goal may need a different solution)
GOAL 1: To have an ext { … } section containing a Map of Strings to gradle dependencies much like so
deps = [
'web-webserver': "org.webpieces:http-webserver:${webpiecesVersion}",
'web-webserver-test': "org.webpieces:http-webserver-test:${webpiecesVersion}",
'web-devrouter': "org.webpieces:http-router-dev:${webpiecesVersion}"
]
In this way, we want ALL our projects to them import dependencies like so
compile deps['web-webserver']
GOAL 2: We want to 'include' a standard list of plugins so we are versioning all gradle plugins the same across the repo. While the above configures all jars to avoid jar hell in a mono-repo, we would like to do the same with just this section
plugins {
id 'com.github.sherter.google-java-format' version '0.9'
}
Of course, it each project may also want to add a few more plugins OR even not depend on this section(in case of an emergency and trying to just get the job done).
GOAL 3: We want checkstyle configuration (or any plugin config) to be defined the SAME for all projects (eventually!!!). We would like the checkstyle gradle to live in a common area but have all libraries somehow pull it in. Again, it would be nice for it to be optional in that, I can pull the gradle section into my build.gradle OR can create a new one in case of emergencies so I don't have to fix all projects in the monorepo right away.
IDEALLY, perhaps I kind of want configuration injection where when I run server1/build.gradle, it actually runs java/build/build.grade as it’s parent somehow but with overrides (IF I declare 'extends xxx.gradle' maybe) then all libraries it uses also use java/build/build.gradle as their parent. I am not sure this is possible or feasible. I am pretty sure 'extends xxx' doesn't exist in gradle.
Are any of these GOALS possible?
thanks,
Dean
I have been working on a monorepo with the exact same requirement as you, using gradle composite builds as well. The way we have solved this problem is by using pre compiled plugins
You need to do a new gradle project with only the code you want to share. This will create a plugin, that you can just add as a composite build and apply to the other projects.
I'm a bit confused by why you don't just use a "standard" gradle top level build file and compose the others as subprojects.
This solves all 3 of your goals
If you are concerned by build speed, you can target each server individually simply by running
./gradlew :server1:build
But if you are not able to do this for some reason you can use the apply from: syntax as described here
Suppose a team in the US has a project containing this local library
<dependency><artifactId>garbage</artifactId></dependency>
but the UK version of our project has a pom.xml with this dependency listed instead:
</dependency><artefactId>rubbish</artefactId><dependency>
which specifies the localised build of the artefact.
Currently, a script takes the garbage project, builds it with UK localisation, but then has to patch up the .jar files after the fact so that the artefactId reflects the localisation, including if the string has been copied as part of the build process. This method has proven to be unreliable, however: Is there a way of migrating to a system which uses Maven, alone, to change the build ID depending on something like the LANG environment variable?
Or; is it not possible to introduce configuration into the pom.xml configuration file itself?
If you need to build a project for different environments, you can use Maven Profiles:
http://maven.apache.org/guides/introduction/introduction-to-profiles.html
You can put different dependencies into different profiles and activate/deactivate the profiles in build process, on the command line or e.g. by marker files.
I want to use allprojects/afterEvaluate in a multiproject build to do something on each project based on properties that it has set. Is there a way to set properties per project in a way that is not inherited by subprojects?
ext.myProp works if I'm only concerned with leaf projects. But if a parent needs to set that property too, I can't find a way to distinguish which project it was set on. The multiproject guide explains that properties are (begrudgingly) inherited.
This mechanism reminds me of prototypal inheritance in JavaScript. Does gradle have a hasOwnProperty equivalent?
I dug some more and found that while there's no general way to isolate which of the several delegated scopes a project property is coming from, if you're specifically looking for an ext property, then there is a has method you can check on a specific project's ext container that does not delegate (at least not to the extent that hasProperty does).
So proj.ext.has('myProp') will be true if a value has been assigned to that project directly.
An important caveat is that properties set via -P or gradle.properties appear to be replicated into the extension containers of all projects automatically, and I don't think there's a way to distinguish that. Extension or task properties might be easier to isolate since they're not inherited, but they're less ad hoc.
I have multiple projects that are build with gradle. All projects are basically using the same build logic and many common properties, only certain variables are different between projects.
I'd like to centralize all common parts and "include" that in every gradle project, so I don't have to touch every gradle project when some commonly used properties change. I'd also like to have the ability to override properties for special cases.
What's the gradle way to do this?
What's the gradle way to do this?
Simple answer: Initialization scripts
Properties are the best way to set user-/system-specific (using the gradle.properties file in the Gradle user home directory) or project-specific (using the gradle.properties file in the project directory) parameters. If you want to setup a consistent environment across development systems (local machines, CI, ...) and even multiple users (different credentials), you can develop one or more initialization scripts.
You can place them at your Gradle user home directory (this way they will be used by all Gradle installations) or at your Gradle install directory (for one specific installed Gradle version).
Project and system properties can be set from an initialization script via a StartParameter object:
startParameter.with {
projectProperties['key'] = 'value'
systemPropertiesArgs['key'] = 'value'
}
Both projectProperties and systemPropertiesArgs are simple maps.