概要
1. 这是一个样例,基本照着《Maven实战》-徐晓斌,第17章照抄的;个人练手之作,不喜勿喷!
2. 代码行统计插件。
备注
大量插件可从以下网站获得:
1. http://maven.apache.org/plugins/
2. http://mojo.codehaus.org/plugins.html
m2e插件不能提供搜索框,搜索Maven依赖包的(书里说可以,但实际插件不提供该功能了),可以通过:
https://repository.sonatype.org/index.html 搜索(可根据类名,包名,artifactId等信息查找)
正文
1. 创建Maven项目,archetype选择:maven-archetype-plugin
New--->Project…选择Maven Project
2. 删除MyMojo.java,新增CountMojo.java继承:org.apache.maven.plugin.AbstractMojo
package com.ckhuang.maven.plugin; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.apache.maven.model.Resource; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; /** * * 统计项目文件的行数 * * @author ck.huang * */ @Mojo(name = "count") public class CountMojo extends AbstractMojo { private static final String[] INCLUDES_DEFAULT = new String[] {"xml", "java", "properties"}; /** * * 项目根目录 * */ @Parameter(defaultValue = "${project.basedir}", property = "baseDir", required = true, readonly = true) private File baseDir; /** * * 项目源文件目录 * */ @Parameter(defaultValue = "${project.build.sourceDirectory}", property = "sourceDirectory", required = true, readonly = true) private File sourceDirectory; /** * * 项目测试代码源文件目录 * */ @Parameter(defaultValue = "${project.build.testSourceDirectory}", property = "testSourceDirectory", required = true, readonly = true) private File testSourceDirectory; /** * * 运行时配置文件 * */ @Parameter(defaultValue = "${project.build.reousrce}", required = true, readonly = true) private List<Resource> resources; /** * * 测试时配置文件 * */ @Parameter(defaultValue = "${project.build.testReousrce}", required = true, readonly = true) private List<Resource> testResources; /** * 要统计的文件格式<br/> * 默认为:java,xml,properties<br/> * 可通过配置includes属性修改 */ @Parameter(property = "includes") private String[] includes; public void execute() throws MojoExecutionException, MojoFailureException { if (includes == null || includes.length == 0) { includes = INCLUDES_DEFAULT; } try { getLog().info("includes " + Arrays.toString(includes)); countDir(sourceDirectory); countDir(testSourceDirectory); countResource(resources); countResource(testResources); } catch (IOException e) { throw new MojoExecutionException("Unable to count lines of code.", e); } } /** * 统计文件目录下的文件总行数 * * @param dir 目录路径 * @throws IOException */ private void countDir(File dir) throws IOException { if (!dir.exists()) { return; } List<File> collected = new ArrayList<File>(); collectFiles(collected, dir); int lines = 0; for (File sourceFile : collected) { lines += countLine(sourceFile); } String path = dir.getAbsolutePath().substring(baseDir.getAbsolutePath().length()); getLog().info(path + ":" + lines + " lines of code in " + collected.size() + "files"); } private int countLine(File sourceFile) throws IOException { BufferedReader reader = new BufferedReader(new FileReader(sourceFile)); int line = 0; try { while (reader.ready()) { reader.readLine(); line++; } } finally { reader.close(); } return line; } private void collectFiles(List<File> collected, File file) { if (file.isFile()) { for (String include : includes) { if (file.getName().endsWith("." + include)) { collected.add(file); break; } } } else { for (File sub : file.listFiles()) { collectFiles(collected, sub); } } } /** * 统计配置文件 * * @param resources * @throws IOException */ private void countResource(List<Resource> resources) throws IOException { for (Resource res : resources) { countDir(new File(res.getDirectory())); } } }
3. 在生成的POM,xml文件基础上修改,修改:goalPrefix
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.ckhuang.maven</groupId> <artifactId>maven-loc-plugin</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>maven-plugin</packaging> <name>lineCounter Maven Plugin</name> <!-- FIXME change it to the project's website --> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.version>3.0.4</maven.version> </properties> <dependencies> <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-plugin-api</artifactId> <version>${maven.version}</version> </dependency> <dependency> <groupId>org.apache.maven.plugin-tools</groupId> <artifactId>maven-plugin-annotations</artifactId> <version>3.2</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.codehaus.plexus</groupId> <artifactId>plexus-utils</artifactId> <version>3.0.8</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.2</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-plugin-plugin</artifactId> <version>3.2</version> <configuration> <goalPrefix>loc</goalPrefix> <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound> </configuration> <executions> <execution> <id>mojo-descriptor</id> <goals> <goal>descriptor</goal> </goals> </execution> <execution> <id>help-goal</id> <goals> <goal>helpmojo</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <profiles> <profile> <id>run-its</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-invoker-plugin</artifactId> <version>1.7</version> <configuration> <debug>true</debug> <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo> <pomIncludes> <pomInclude>*/pom.xml</pomInclude> </pomIncludes> <postBuildHookScript>verify</postBuildHookScript> <localRepositoryPath>${project.build.directory}/local-repo</localRepositoryPath> <settingsFile>src/it/settings.xml</settingsFile> <goals> <goal>clean</goal> <goal>test-compile</goal> </goals> </configuration> <executions> <execution> <id>integration-test</id> <goals> <goal>install</goal> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </profile> </profiles> </project>
4. 修改Maven的setting.xml增加插件所属的groupId,以便更简易的访问:
<pluginGroups> <!-- 你的插件groupId --> <pluginGroup>com.ckhuang.maven</pluginGroup> </pluginGroups>
5. 进入某个Maven项目,执行:
mvn loc:count
=========================================
PS,如果没有经过第4步,以及第3步中修改POM.xml的:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-plugin-plugin</artifactId> <version>3.2</version> <configuration> <goalPrefix>loc</goalPrefix> <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound> </configuration> <executions> <execution> <id>mojo-descriptor</id> <goals> <goal>descriptor</goal> </goals> </execution> <execution> <id>help-goal</id> <goals> <goal>helpmojo</goal> </goals> </execution> </executions> </plugin>
则使用插件需要执行:
mvn com.ckhuang.maven:maven-loc-plugin:0.0.1-SNAPSHOT:count
搞定!
后记
涉及的细节如注解:@Mojo,@Parameter(property = "includes")等的使用,${project.build.reousrce}等Maven的环境变量,
将在下一章节进行说明。