LendingClub / gradle-maven-plugin

maven plugin to invoke gradle
73 stars 36 forks source link

need maven project and session bound to variables for checkInvokeScript feature #29

Open dlethin opened 8 years ago

dlethin commented 8 years ago

I've been taking advantage of the the checkInvokeScript configuration setting built into this mojo to ensure that this plugin only gets execute once in a multi-module build. My solution was working fine until some windows developers tried to build my project. The issue that we ran into is that my checkInvoke script looks something like this:

                  <groupId>org.fortasoft</groupId>
                  <artifactId>gradle-maven-plugin</artifactId>
                  <version>1.0.7</version>
                  <executions>
                    <execution>
                      <id>build application configuration</id>
                      <phase>process-resources</phase>
                      <goals>
                        <goal>invoke</goal>
                      </goals>
                      <configuration>
                        <!-- 
                          this script is called by the gradle-maven-plugin
                          to determine if gradle build should be invoked.
                          Our script keeps a timestamp file based on the
                          maven session starttime. We will only execute
                          the gradle build once per session. This is useful
                          where multiple project within a build need to share
                          configuration. We only need to set it up once
                        -->
                        <checkInvokeScript>

                          def ts = "$${session.startTime.time}"

                          def buildDir = new File("$gradleBuildDir'}")
                          buildDir.mkdirs()

                          def markerFile = new File("$gradleBuildDir'}/gradleTimestamp.txt")

                          if (!markerFile.exists() || !markerFile.text.equals(ts)) {
                            markerFile.text = ts
                            return true
                          } else {
                            println "Gradle already run this maven session. Skipping"
                            return false
                          }

                        </checkInvokeScript>

In this case gradleBuildDir is a maven property I make sure is always set to a correct directory. During maven execution time, maven will interpolate that properties prior to your mojo executing the groovy script.

The problem I'm running into is that for windows users, the directory might have a backslash character in it, like this c:\path\to\file

And this causes errors like this when the plugin executes:

[ERROR] Failed to execute goal org.fortasoft:gradle-maven-plugin:1.0.5:invoke (build application configuration) on project key-mgmt: Execution build application configuration of goal org.fortasoft:gradle-maven-plugin:1.0.5:invoke failed: startup failed:
[ERROR] Script1.groovy: 1: unexpected char: '\' @ line 1, column 21.

To work around this, in a fork, I modified the mojo to bind the MavenProject and MavenSession instances to variables available when executing the script, like such:

    protected boolean shouldExecute() throws MojoFailureException {
        boolean shouldExecute = true;
        if (checkInvokeScript != null && checkInvokeScript.trim().length() > 0) {
            Binding b = new Binding();

            b.setVariable("mavenBaseDir", mavenBaseDir);
            b.setVariable("session", session);
            b.setVariable("project", project);

Then the script can look like this:

                        <checkInvokeScript>
                          def ts = "$${session.startTime.time}"

                          def buildDir = new File("$${project.properties['gradleBuildDir']}")
                          buildDir.mkdirs()

                          def markerFile = new File("$${project.properties['gradleBuildDir']}/gradleTimestamp.txt")

                          if (!markerFile.exists() || !markerFile.text.equals(ts)) {
                            markerFile.text = ts
                            return true
                          } else {
                            println "Gradle already run this maven session. Skipping"
                            return false
                          }

                        </checkInvokeScript>

This seems to solve my problem nicely. I will followup with a merge request from my fork that I hope you will consider accepting and merging removing the need for me to maintain my fork.

Thanks so much for this helpful plugin.

Doug