Conditionally include exclude files while creating project using maven archetype

5.3k views Asked by At

Am trying to create an archetype which will conditionally include file based on the user input.

Like for eg., if a user will use this custom archetype and pass parameters like
-DprojectType=webProject or -DprojectType=webDBProject


if webProject copy only files related to webProject and if its webDBProject copy files related to webProject and DB related files.

I found out that conditionally include/exclude file is not possible at least in near future using archetype-descriptor.

How do I conditionally include or exclude a file from an archetype when project is generated?

The other option i had was to execute a goal after archetype generation and include/remove unwanted files. But we can't utilize the eclipse M2E plugin with this.

The final option i was trying is to utilize velocity template itself to execute the post processing operations.

Since we can't instantiate an object inside velocity template, I was trying to use reflection to create a file instance and delete some file like the following,

$somestring.getClass().forName("java.io.File").getMethod("delete", null).invoke($somestring.getClass().forName("java.io.File").getConstructor($somestring.getClass()).newInstance("delete.txt"), null)

writing the above line in a velocity template file and running against a standalone velocity java program is running fine. But the same is not working when executing as part of maven archetype generator.

I tried to go step by step, where the execution was successful until getting the class but the getConstructor() part is failing to execute while running archetype:generate.

Did anyone tried and know the reason or have alternate solution?

Also anyone knows what version of velocity engine being used in Maven ?

3

There are 3 answers

0
Edy Segura On

In case you want to remove a whole directory you can change the example above a little bit in order to achieve that! Here we go:

import java.nio.file.Files

// the path where the project got generated
File rootDir = new File(request.getOutputDirectory() + "/" + request.getArtifactId())

// the properties available to the archetype
Properties properties = request.getProperties()
String addSwaggerUI = properties.get("addSwaggerUI")

// the Java package of the generated project, e.g. com.acme
String packageName = properties.get("package")

// convert it into a path, e.g. com/acme
String packagePath = packageName.replace(".", "/")

if (addSwaggerUI == "false") {
  println ""
  println "|---------> Hi there!"
  println "|-> ${rootDir}"
  println "|-> ${packageName}"
  println "|-> ${packagePath}"
  println "|-> ${addSwaggerUI}"
  println "|---------> Bye bye!"
  println ""
  new File(rootDir, "src/main/java/${packagePath}/config").deleteDir()
}

More archetype-post-generate.groovy examples can be found here and here!

0
Nikolaos Georgiou On

The answer above by GreyBeardedGeek is the correct one. In case someone needs an example of how that Groovy script should look like, I wrote a small blogpost.

Here's the Groovy script from my post:

import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths

// the path where the project got generated
Path projectPath = Paths.get(request.outputDirectory, request.artifactId)

// the properties available to the archetype
Properties properties = request.properties

// connectionType is either ftp or sftp
String connectionType = properties.get("connectionType")

// the Java package of the generated project, e.g. com.acme
String packageName = properties.get("package")

// convert it into a path, e.g. com/acme
String packagePath = packageName.replace(".", "/")

if (connectionType == "sftp") {
  // delete the FTP file
  Files.deleteIfExists projectPath.resolve("src/main/java/" + packagePath + "/polling/FtpFlowBuilder.java")
} else if (connectionType == "ftp") {
  // delete the SFTP file
  Files.deleteIfExists projectPath.resolve("src/main/java/" + packagePath + "/polling/SftpFlowBuilder.java")
}

1
GreyBeardedGeek On

I realize that this is a really old question, but now (in 2018), I'm accomplishing this task through the use of Maven's support for a post-generate groovy script.

If you include a groovy script named "archetype-post-generate.groovy" in the archetype project's src/main/resources/META-INF directory, then it will be executed after the archetype is generated.

The script will have access to the archetype's properties, e.g. ${artifactId}, including any custom properties.

What I do is to include all possible files in the archetype, and then in the groovy script, I inspect the relevant archetype properties, and delete the unwanted files.

In my script, I'm also renaming some files, as well as editing some of the files by reading them in, doing string replacements, and then writing them back out.

It's a bit cumbersome, but it works.