Lazybones Project - “Lazybones” that works for you
- Tutorial
I do not like Maven.
More than one article can be written about my passionate hatred of this thing, but today I want to talk about one very good feature of Maven - about archetypes. What is this you can read in the official documentation , in each of the tutorials on Maven on Habré ( 1 , 2 , 3 ), and indeed, 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.
That's what Peter Ledbrook thought when he looked at the complete absence of archetypes in Ratpack . Then the Lazybones project was born- a tool for generating projects.
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.
Then everything will be extremely short:
That's all, thank you for your attention, everyone is free. Although no, now we will do just interesting.
Since you are most likely familiar with the # 361 Maven archetype ( maven-archetype-quickstart ), we will do something similar (having recreated all the features, we will omit some repetitions).
Not only can you compare the number of downloaded Internet to create both projects, you can also compare the complexity of creating the template itself, because the process of creating the Maven archetype is perfectly described here .
What we want to achieve:
That's all. I hope you are imbued with simplicity and grace both creating projects from templates and creating the templates themselves in Lazybones. It seems to me that for these simplicity and grace it is in many ways necessary to thank Groovey.
More than one article can be written about my passionate hatred of this thing, but today I want to talk about one very good feature of Maven - about archetypes. What is this you can read in the official documentation , in each of the tutorials on Maven on Habré ( 1 , 2 , 3 ), and indeed, 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.
That's what Peter Ledbrook thought when he looked at the complete absence of archetypes in Ratpack . Then the Lazybones project was born- a tool for generating projects.
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
Then everything will be extremely short:
- Install Lazybones using GVM or download the distribution package from Bintray
- We look at what patterns exist using the command
lazybones list
(or study the repository ) - We study the information about the selected template using the command
lazybones info <имя шаблона>
(or read readme in packag-e of the template on Bintrey) - Create a project team
lazybones create <имя шаблона> <версия шаблона> <имя директории в которой создавать>
That's all, thank you for your attention, everyone is free. Although no, now we will do just interesting.
Creating your own project template
Since you are most likely familiar with the # 361 Maven archetype ( maven-archetype-quickstart ), we will do something similar (having recreated all the features, we will omit some repetitions).
Not only can you compare the number of downloaded Internet to create both projects, you can also compare the complexity of creating the template itself, because the process of creating the Maven archetype is perfectly described here .
So let's go.
What we want to achieve:
- Create basic pom.xml with selected via the interactive command line
groupId
,artifactId
and version - Create directories src / main / java, src / main / resources (the same for tests, but we will not, for simplicity's sake)
- Create a class for the example, register the selected one through the interactive command line in it
package
and put it in the appropriatepackage
directory (the same for the test, but we will not, for the simplicity of the example) - Generate in the class that
main
, when the test phase starts, print a message selected through the interactive command line - Assemble template
- Create a project according to our template
- Run
mvn test
- Profit
- To build the template, we need a Gradle script and a directory with templates. Since we are too lazy, we will run lazybones:
>lazybones create lazybones-project lzb-templates
As a result, we have the following:│ build.gradle // chalbon assembly script │ gradlew // script launch file for nyx │ gradlew.bat // script launch file for Windows │ README.md // file describing this project │ ├───gradle // auxiliary directory for the script │ └───templates // empty directory for our templates
- We go into the directory
templates
, create a sub-directory of our template in it, and begin to sculpt. Create a version file. It is calledVERSION
and contains only a version, for example 0.1> mkdir maven-simple > cd maven simple > echo 0.1> VERSION
- In addition, you need to create
readme.md
, which will be shown after the creation of the project. - Create a directory
src/main/java
,src/main/resources
. Injava
andresources
of them we put on an empty file.retain
├───maven-simple │ │ README.md │ │ VERSION │ │ │ └───src │ └───main │ ├───java │ │ .retain │ │ │ └───resources │ .retain
- Now let's take care of the templates. Let's start with pom.xml:
4.0.0 ${groupId} ${artifactId} ${version} org.codehaus.mojo exec-maven-plugin 1.2.1 test java ${pkg}.App ${message} AAAAA !!!!!!!
So, pulled ourselves together, look. Pay attention to all sorts${...}
. This is what we will change to the values that the user will ask us at startupcreate
. In essence, these are just Groovy Templates tokens . If you are familiar with Velocity, Freemarker or any other template handler, you will be familiar with everything. But more on that later.
Hell hell in is just the start of amain
classApp
. Please note that we are not yet aware ofpackage
this class and the parameter that we pass tomain
. - Now look at the file
App.java
:package ${pkg}; public class App { public static void main(String[] args) { System.out.println(args[0]); } }
Here we have only one variable - again the samepackage
. At the same time, we see that main prints the argument. This means that during the launch of the maven, in the test phase, we expect to see the message that the user selects, again, duringcreate
.
So now we have all the directories and templates:│ App.java │ lazybones.groovy │ pom.xml │ README.md │ VERSION │ └───src └───main ├───java │ .retain │ └───resources .retain
- And now the fun begins. It remains for us to write a post processor that will run after unpacking the 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.
The elegant Groove script will help us in this, of course:import static org.apache.commons.io.FileUtils.moveFileToDirectory Map
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 what is happening quite clearly. The only thing that probably needs to be added is that the methodsask()
and theprocessTemplates()
fieldtargetDir
get into the script from the classuk.co.cacoethes.lazybones.LazybonesScript
, which is a custom super-class of this script . - It's time to collect. Lazybones has its own plugin for Gradle, which is already configured in the build script that we generated in step 1. This plugin defines task rules for building, installing in the local cache, and deploying templates to Bintray. Since the template is not serious, we won’t put it on Bintray, but it’s mandatory to install it in the cache to try to run it. We start assembly:
>gradlew installTemplateMavenSimple
:packageTemplateMavenSimple
:installTemplateMavenSimple
BUILD SUCCESSFUL
- Testing! We create a new directory and create a project from the template in it (as we have already seen): The
>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!
message at the end comes, of course, fromreadme.md
. Please note, I did not specifyartifactId
, expectmaven-simple
by default.
We go into the maven-simple directory, and admire:│ pom.xml │ README.md │ └───src └───main ├───java │ └───org │ └───simple │ App.java │ └───resources
Open pom.xml:4.0.0 com.demo maven-simple 0.1 org.codehaus.mojo exec-maven-plugin 1.2.1 test java org.simple.App Привет, Хабр!
Everything is as it should. Open App.java:package org.simple; public class App { public static void main(String[] args) { System.out.println(args[0]); } }
The same order. Launch 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 --- Hello, Habr! [INFO] ----------------------------------------------- ------------------------- [INFO] BUILD SUCCESS [INFO] ----------------------------------------------- ------------------------- [INFO] Total time: 0.768s [INFO] Finished at: Fri Apr 04 02:54:57 IDT 2014 [INFO] Final Memory: 7M / 304M [INFO] ----------------------------------------------- -------------------------
That's all. I hope you are imbued with simplicity and grace both creating projects from templates and creating the templates themselves in Lazybones. It seems to me that for these simplicity and grace it is in many ways necessary to thank Groovey.
Shameless PR, you can not read
If you liked and you agree with me on the account of grace and simplicity, and if you want to learn a little Groove yourself, then come to me for a training on April 15 in Kazan , or on April 17 in Moscow . I promise to teach Groovy buns.