📜 ⬆️ ⬇️

Project Lazybones - “Lazy” that works for you

I do not like Maven.
About my passionate hatred of this thing, you can write more than one article, but today I want to talk about one very good feature of Maven - about archetypes. What is this can be read in the official documentation , in each of the tutorials on the Maven on Habré ( 1 , 2 , 3 ), and in general, you probably know yourself.

So, archetypes are cool, and it would be great if 1) they were in many projects with a standard structure. 2) it would be possible to fasten them to those who do not have them.

Peter Ledbrook thought something like this when he looked at the complete absence of archepaps in Ratpack . Then Lazybones project was born - a tool for generating projects.
')
image

In this article I will tell you how to 1) Use Lazybones to generate projects for which templates have already been created. 2) Create new templates for any projects.

Using existing Lazybones templates

Here everything will be extremely short:
  1. Install Lazybones using GVM or download the distribution from Bintray
  2. We look at which templates exist using the lazybones list command (or studying the repository )
  3. We study information about the selected template using the lazybones info < > command (or read the readme in the packag-e template on Bintree)
  4. Create a project with the lazybones create < > < > < > command lazybones create < > < > < >

Everything, thank you for your attention, everyone is free. Although no, now we will do just the interesting.

Creating your project template

Since you are most likely familiar with the # 361 Mavenow archetype ( maven-archetype-quickstart ), we will do something similar (by recreating all the features, we omit some repetitions).
Not only can you compare the amount of downloaded Internet to create both projects, you can also compare the complexity of creating the template itself, because the process of creating an archetype of Maven is beautifully described here .

So let's go.

What we want to achieve:


  1. To build the template, we need the Gradle script and the template directory. Since we are too lazy, we will run lazybones:
    >lazybones create lazybones-project lzb-templates
    As a result, we have the following:

     │ build.gradle // shalbon build script
     │ gradlew // nix script startup file
     │ gradlew.bat // run script file for Windows
     │ README.md // file describing this project
     │
     ├───gradle // supporting directory for the script
     │
     └───templates // empty directory for our templates
    

  2. Go to the templates directory, create a sub-directory of our template in it, and start to sculpt. Create a version file. It is called VERSION and contains only the version, for example 0.1

     > mkdir maven-simple
     > cd maven simple
     > echo 0.1> VERSION
    

  3. In addition, you need to create a readme.md , which will be shown after creating the project.
  4. Create directories src/main/java , src/main/resources . In java and resources from them we put on an empty .retain file

     ├───maven-simple
     │ │ README.md
     │ │ VERSION
     │ │
     │ └───src
     │ └──main
     │ ├──jjava
     │ │ .retain
     │ │
     │ └───resources
     │ .retain
    

  5. Now let's do the templates. Let's start with pom.xml:
     <project> <modelVersion>4.0.0</modelVersion> <groupId>${groupId}</groupId> <artifactId>${artifactId}</artifactId> <version>${version}</version> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.2.1</version> <executions> <execution> <phase>test</phase> <goals> <goal>java</goal> </goals> <configuration> <mainClass>${pkg}.App</mainClass> <arguments> <argument>${message}</argument> </arguments> </configuration> </execution> </executions> </plugin> </plugins> </build> </project> 

    AAAAAH !!!!!!!
    So, took themselves in hand, look. Pay attention to all sorts of ${...} . This is what we will change to the values ​​that the user will give us when running create . In essence, these are just Groovy Templates . If you are familiar with Velocity, Freemarker or any other template handler, everything will be familiar to you. But more about that later.
    Hell's hell in - it's just launching the main App class. Please note that we are not yet aware of the package this class and the parameter that we pass to main .
  6. Now look at the App.java file:
     package ${pkg}; public class App { public static void main(String[] args) { System.out.println(args[0]); } } 

    Here we have only one variable - again, the package . At the same time, we see that main prints the argument. This means that during the launch of mavena, in the test phase, we expect to see a message that the user selects, again, during the create .
    So now we have all the directories and templates:
     │ App.java
     │ lazybones.groovy
     │ pom.xml
     │ README.md
     │ VERSION
     │
     ───src
         └───main
             ├───java
             │ .retain
             │
             └───resources
                     .retain
    

  7. And now the fun begins. It remains for us to write a post-processor that will run after unpacking directories. Tasks: 1) Find out everything the user needs, 2) transfer the java file to the directory corresponding to the package, 3) process the templates.
    An elegant Gruvy script will help us in this, of course:
     import static org.apache.commons.io.FileUtils.moveFileToDirectory Map<String,String> props = [:] // ask  2  - ,    . //     .  (   ,   ) . props.groupId = ask(' groupId [org.example]: ', 'org.example') props.artifactId = ask(' artifactId [maven-simple]: ', 'maven-simple') props.version = ask('  [1.0-SNAPSHOT]: ', '1.0-SNAPSHOT') props.pkg = ask(" package   [$props.groupId]:", props.groupId) props.message = ask('   ? ', ', !') // processTemplates  ,     . processTemplates 'pom.xml', props //    String packageDir = props.pkg.replaceAll(/\./, '/') //     moveFileToDirectory(new File(targetDir, 'App.java'), new File(targetDir, "src/main/java/$packageDir"), true) //  processTemplates 'src/main/java/**/App.java', props 

    I hope the comments explain quite clearly what is happening. The only thing that probably needs to be added is that the ask() and processTemplates() methods and the processTemplates() field get into the script from the uk.co.cacoethes.lazybones.LazybonesScript class, which is the custom uk.co.cacoethes.lazybones.LazybonesScript this script .
  8. It's time to collect. Lazybones has its own plugin for Graidla, which is already configured in the build script, which we generated in step 1. This plugin defines the task rules for building, installing in the local cache and deploying templates to Bintrey. Since the template is not serious, we will not put it on Bintrey, but it is necessary to install it in the cache to try to run it. Run the build:
    >gradlew installTemplateMavenSimple
    :packageTemplateMavenSimple
    :installTemplateMavenSimple

    BUILD SUCCESSFUL
  9. We are testing! Create a new directory and create a project from a template in it (as we have already seen):
    >lazybones create maven-simple 0.1 maven-simple

    Creating project from template maven-simple 0.1 in 'maven-simple'
    groupId [org.example]: com.demo
    artifactId [maven-simple]:
    [1.0-SNAPSHOT]: 0.1
    package [org.example]:org.simple
    ? , !

    -
    ---------------------------------
    . ? .

    Project created in maven-simple!

    The message at the end comes, of course, from readme.md . Pay attention, I did not specify artifactId , I expect maven-simple by default.
    Go to the maven-simple directory, and admire:
     │ pom.xml
     │ README.md
     │
     ───src
         └───main
             ├───java
             │ └──org
             └───simple
             │ App.java
             │
             └───resources
    

    Open pom.xml:
     <project> <modelVersion>4.0.0</modelVersion> <groupId>com.demo</groupId> <artifactId>maven-simple</artifactId> <version>0.1</version> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.2.1</version> <executions> <execution> <phase>test</phase> <goals> <goal>java</goal> </goals> <configuration> <mainClass>org.simple.App</mainClass> <arguments> <argument>, !</argument> </arguments> </configuration> </execution> </executions> </plugin> </plugins> </build> </project> 

    All right. Open App.java:
     package org.simple; public class App { public static void main(String[] args) { System.out.println(args[0]); } } 

    The same order. We start Maven:
     > mvn test
     [INFO] Scanning for projects ...
     [INFO]
     [INFO] ----------------------------------------------- -------------------------
     [INFO] Building maven-simple 0.1
     [INFO] ----------------------------------------------- -------------------------
     [INFO]
     [INFO] --- maven-resources-plugin: 2.6: resources (default-resources) @ maven-simple ---
     [INFO] Copying 0 resource
     [INFO]
     [INFO] --- maven-compiler-plugin: 2.5.1: compile (default-compile) @ maven-simple ---
     [INFO] Nothing to compile - all classes are up to date
     [INFO]
     [INFO] --- maven-resources-plugin: 2.6: testResources (default-testResources) @ maven-simple ---
     [INFO]
     [INFO] --- maven-compiler-plugin: 2.5.1: testCompile (default-testCompile) @ maven-simple ---
     [INFO] No sources to compile
     [INFO]
     [INFO] --- maven-surefire-plugin: 2.12.4: test (default-test) @ maven-simple ---
     [INFO] No tests to run.
     [INFO]
     [INFO] >>> exec-maven-plugin: 1.2.1: java (default) @ maven-simple >>>
     [INFO]
     [INFO] <<< exec-maven-plugin: 1.2.1: java (default) @ maven-simple <<<
     [INFO]
     [INFO] --- exec-maven-plugin: 1.2.1: java (default) @ maven-simple ---
     Hi, Habr!
     [INFO] ----------------------------------------------- -------------------------
     [INFO] BUILD SUCCESS
     [INFO] ----------------------------------------------- -------------------------
     [INFO] Total time: 0.768s
     [INFO] Finished at: Fri Apr 04 02:54:54 IDT 2014
     [INFO] Final Memory: 7M / 304M
     [INFO] ----------------------------------------------- -------------------------
    


That's all. I hope you are imbued with the simplicity and elegance of how to create projects from templates and the creation of the templates themselves in Lazybones. It seems to me, for these simplicity and grace in many respects it is necessary to thank Gruvy.

Shameless PR, you can not read
If you liked it and you agree with me on the account of grace and simplicity, and if you want to learn a little bit of Gruvy yourself, then come to me for training on April 15 in Kazan , or on April 17 in Moscow . I promise to teach Gruvinny buns.

Source: https://habr.com/ru/post/218205/


All Articles