Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit bf404f8
Showing
5 changed files
with
376 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
*.ipr | ||
*.iws | ||
*.iml | ||
target | ||
*.releaseBackup | ||
release.properties |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
Hello. | ||
|
||
There are a couple of plugins out there to compile | ||
Google Protobuf files, but most of them end up | ||
giving NPEs, so you have to fallback to Exec Plugin. | ||
|
||
That's why I wanted to create a quite simple plugin | ||
that just does the job. Plus the source code is very | ||
small and simple to fix any possible issue. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
<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/maven-v4_0_0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<parent> | ||
<groupId>org.sonatype.oss</groupId> | ||
<artifactId>oss-parent</artifactId> | ||
<version>7</version> | ||
</parent> | ||
|
||
<groupId>com.petruk.protobuf</groupId> | ||
<artifactId>protobuf-maven-plugin</artifactId> | ||
<packaging>maven-plugin</packaging> | ||
<version>0.1-SNAPSHOT</version> | ||
<name>Once Again Maven Protobuf Plugin</name> | ||
<url>http://github.com/igor-petruk/protobuf-maven-plugin</url> | ||
<properties> | ||
<mavenVersion>2.0.9</mavenVersion> | ||
</properties> | ||
|
||
<developers> | ||
<developer> | ||
<id>igor-petruk</id> | ||
<name>Igor Petruk</name> | ||
<email>igor.petrouk@gmail.com</email> | ||
</developer> | ||
</developers> | ||
|
||
<licenses> | ||
<license> | ||
<name>The Apache Software License, Version 2.0</name> | ||
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url> | ||
<distribution>repo</distribution> | ||
</license> | ||
</licenses> | ||
|
||
<scm> | ||
<connection>scm:git:git://github.com/igor-petruk/protobuf-maven-plugin.git</connection> | ||
<developerConnection>scm:git:ssh://git@github.com/igor-petruk/protobuf-maven-plugin.git</developerConnection> | ||
<url>https://github.com/igor-petruk/protobuf-maven-plugin</url> | ||
</scm> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.apache.maven</groupId> | ||
<artifactId>maven-artifact</artifactId> | ||
<version>${mavenVersion}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.maven</groupId> | ||
<artifactId>maven-plugin-api</artifactId> | ||
<version>${mavenVersion}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.maven</groupId> | ||
<artifactId>maven-project</artifactId> | ||
<version>${mavenVersion}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.maven</groupId> | ||
<artifactId>maven-model</artifactId> | ||
<version>${mavenVersion}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.maven</groupId> | ||
<artifactId>maven-core</artifactId> | ||
<version>${mavenVersion}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.maven</groupId> | ||
<artifactId>maven-artifact-manager</artifactId> | ||
<version>${mavenVersion}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.maven</groupId> | ||
<artifactId>maven-repository-metadata</artifactId> | ||
<version>${mavenVersion}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.maven.shared</groupId> | ||
<artifactId>maven-dependency-tree</artifactId> | ||
<version>1.2</version> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>junit</groupId> | ||
<artifactId>junit</artifactId> | ||
<version>3.8.1</version> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
|
||
<profiles> | ||
<profile> | ||
<id>release-sign-artifacts</id> | ||
<activation> | ||
<property> | ||
<name>performRelease</name> | ||
<value>true</value> | ||
</property> | ||
</activation> | ||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-gpg-plugin</artifactId> | ||
<version>1.1</version> | ||
<executions> | ||
<execution> | ||
<id>sign-artifacts</id> | ||
<phase>verify</phase> | ||
<goals> | ||
<goal>sign</goal> | ||
</goals> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
</profile> | ||
</profiles> | ||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,218 @@ | ||
package com.petruk.protobuf; | ||
|
||
/* | ||
* Copyright 2001-2005 The Apache Software Foundation. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import org.apache.maven.artifact.Artifact; | ||
import org.apache.maven.artifact.factory.ArtifactFactory; | ||
import org.apache.maven.artifact.metadata.ArtifactMetadataSource; | ||
import org.apache.maven.artifact.repository.ArtifactRepository; | ||
import org.apache.maven.artifact.resolver.ArtifactCollector; | ||
import org.apache.maven.artifact.resolver.filter.ArtifactFilter; | ||
import org.apache.maven.plugin.AbstractMojo; | ||
import org.apache.maven.plugin.MojoExecutionException; | ||
import org.apache.maven.project.MavenProject; | ||
import org.apache.maven.shared.dependency.tree.DependencyNode; | ||
import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder; | ||
import org.apache.maven.shared.dependency.tree.DependencyTreeBuilderException; | ||
|
||
import java.io.File; | ||
import java.io.FileWriter; | ||
import java.io.IOException; | ||
import java.util.Map; | ||
import java.util.Scanner; | ||
|
||
/** | ||
* @goal run | ||
* @phase generate-sources | ||
* @requiresDependencyResolution | ||
*/ | ||
public class MyMojo extends AbstractMojo { | ||
|
||
private static final String PROTOBUF_GROUPID="com.google.protobuf"; | ||
private static final String PROTOBUF_ARTIFACTID="protobuf-java"; | ||
private static final String PROTOC="protoc"; | ||
private static final String VERSION_KEY="--version"; | ||
private static final ProtoFileFilter PROTO_FILTER = | ||
new ProtoFileFilter(".proto"); | ||
|
||
/** | ||
* The Maven project. | ||
* | ||
* @parameter expression="${project}" | ||
* @required | ||
* @readonly | ||
*/ | ||
private MavenProject project; | ||
|
||
/** | ||
* The artifact repository to use. | ||
* | ||
* @parameter expression="${localRepository}" | ||
* @required | ||
* @readonly | ||
*/ | ||
private ArtifactRepository localRepository; | ||
|
||
/** | ||
* The artifact factory to use. | ||
* | ||
* @component | ||
* @required | ||
* @readonly | ||
*/ | ||
private ArtifactFactory artifactFactory; | ||
|
||
/** | ||
* The artifact metadata source to use. | ||
* | ||
* @component | ||
* @required | ||
* @readonly | ||
*/ | ||
private ArtifactMetadataSource artifactMetadataSource; | ||
|
||
/** | ||
* The artifact collector to use. | ||
* | ||
* @component | ||
* @required | ||
* @readonly | ||
*/ | ||
private ArtifactCollector artifactCollector; | ||
|
||
/** | ||
* The dependency tree builder to use. | ||
* | ||
* @component | ||
* @required | ||
* @readonly | ||
*/ | ||
private DependencyTreeBuilder dependencyTreeBuilder; | ||
|
||
/** | ||
* Location of the file. | ||
* @parameter expression="${run.inputDirectories}" | ||
* @required | ||
*/ | ||
private File[] inputDirectories; | ||
|
||
/** | ||
* Location of the file. | ||
* @parameter expression="${run.outputDirectory}" | ||
* @required | ||
*/ | ||
private File outputDirectory; | ||
|
||
public void execute() throws MojoExecutionException | ||
{ | ||
String dependencyVersion = getProtobufVersion(); | ||
getLog().info("Protobuf dependency version " + dependencyVersion); | ||
String executableVersion = detectProtobufVersion(); | ||
if (executableVersion==null){ | ||
throw new MojoExecutionException("Unable to find '"+PROTOC+"'"); | ||
} | ||
getLog().info("'protoc' executable version "+executableVersion); | ||
if (!dependencyVersion.startsWith(executableVersion)){ | ||
throw new MojoExecutionException("Protobuf installation version does not match Protobuf library version"); | ||
} | ||
performProtoCompilation(); | ||
} | ||
|
||
private void performProtoCompilation() throws MojoExecutionException{ | ||
File f = outputDirectory; | ||
if ( !f.exists() ) | ||
{ | ||
f.mkdirs(); | ||
} | ||
for (File input: inputDirectories){ | ||
getLog().info("Directory "+input); | ||
File[] files = input.listFiles(PROTO_FILTER); | ||
for (File file: files){ | ||
processFile(file, outputDirectory); | ||
} | ||
} | ||
} | ||
|
||
private void processFile(File file, File outputDir) throws MojoExecutionException{ | ||
getLog().info(" Processing "+file.getName()); | ||
Runtime runtime = Runtime.getRuntime(); | ||
try { | ||
Process process = runtime.exec(new String[]{ | ||
PROTOC, | ||
"--proto_path="+file.getParentFile().getAbsolutePath(), | ||
"--java_out="+outputDir, | ||
file.toString() | ||
}); | ||
int result = process.waitFor(); | ||
if (result!=0){ | ||
Scanner scanner = new Scanner(process.getErrorStream()); | ||
while (scanner.hasNextLine()){ | ||
getLog().info(" " + scanner.nextLine()); | ||
} | ||
throw new MojoExecutionException("'protoc' failed for "+file+". Exit code "+result); | ||
} | ||
}catch (InterruptedException e){ | ||
throw new MojoExecutionException("Interrupted",e); | ||
} catch (IOException e) { | ||
throw new MojoExecutionException("Unable to execute protoc for "+file, e); | ||
} | ||
} | ||
|
||
private String getProtobufVersion() throws MojoExecutionException{ | ||
try { | ||
ArtifactFilter artifactFilter = null; | ||
DependencyNode node = dependencyTreeBuilder.buildDependencyTree(project,localRepository, | ||
artifactFactory, | ||
artifactMetadataSource, | ||
null, | ||
artifactCollector | ||
); | ||
return traverseNode(node); | ||
|
||
} catch (DependencyTreeBuilderException e) { | ||
throw new MojoExecutionException("Unable to traverse dependency tree", e); | ||
} | ||
} | ||
|
||
private String detectProtobufVersion() throws MojoExecutionException{ | ||
Runtime runtime = Runtime.getRuntime(); | ||
try { | ||
Process process = runtime.exec(new String[]{ | ||
PROTOC,VERSION_KEY}); | ||
Scanner scanner = new Scanner(process.getInputStream()); | ||
String[] version = scanner.nextLine().split(" "); | ||
return version[1]; | ||
} catch (IOException e) { | ||
return null; | ||
} | ||
} | ||
|
||
private String traverseNode(DependencyNode node) { | ||
Artifact artifact = node.getArtifact(); | ||
if ((PROTOBUF_GROUPID.equals(artifact.getGroupId()) | ||
&& (PROTOBUF_ARTIFACTID.equals(artifact.getArtifactId())))){ | ||
return artifact.getVersion(); | ||
} | ||
for (Object o: node.getChildren()){ | ||
DependencyNode child = (DependencyNode)o; | ||
String result = traverseNode(child); | ||
if (result!=null) | ||
return result; | ||
} | ||
return null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package com.petruk.protobuf; | ||
|
||
import java.io.File; | ||
import java.io.FilenameFilter; | ||
|
||
/** | ||
* User: Igor Petruk | ||
* Date: 07.02.12 | ||
* Time: 17:01 | ||
*/ | ||
public class ProtoFileFilter implements FilenameFilter{ | ||
String extension; | ||
|
||
public ProtoFileFilter(String extension) { | ||
this.extension = extension; | ||
} | ||
|
||
@Override | ||
public boolean accept(File dir, String name) { | ||
return name.endsWith(extension); | ||
} | ||
} |