forked from eugenp/tutorials
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
BAEL-1451 Writing a Jenkins plugin (eugenp#3396)
* BAEL-1451 Writing a Jenkins plugin A sample Jenkins plugin which builds basic project stats * BAEL-1451 Writing a Jenkins plugin Formatting
- Loading branch information
1 parent
6f3710b
commit cd4b526
Showing
4 changed files
with
252 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,89 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<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.jenkins-ci.plugins</groupId> | ||
<artifactId>plugin</artifactId> | ||
<version>2.33</version> | ||
<relativePath /> | ||
</parent> | ||
<artifactId>jenkins-hello-world</artifactId> | ||
<version>1.0-SNAPSHOT</version> | ||
<packaging>hpi</packaging> | ||
<properties> | ||
<!-- Baseline Jenkins version you use to build the plugin. Users must have this version or newer to run. --> | ||
<jenkins.version>2.7.3</jenkins.version> | ||
</properties> | ||
<name>Hello World Plugin</name> | ||
<description>A sample Jenkins Hello World plugin</description> | ||
<url>https://wiki.jenkins-ci.org/display/JENKINS/TODO+Plugin</url> | ||
<licenses> | ||
<license> | ||
<name>MIT License</name> | ||
<url>http://opensource.org/licenses/MIT</url> | ||
</license> | ||
</licenses> | ||
<dependencies> | ||
<dependency> | ||
<groupId>org.jenkins-ci.plugins</groupId> | ||
<artifactId>structs</artifactId> | ||
<version>1.7</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.jenkins-ci.plugins.workflow</groupId> | ||
<artifactId>workflow-step-api</artifactId> | ||
<version>2.12</version> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.jenkins-ci.plugins.workflow</groupId> | ||
<artifactId>workflow-cps</artifactId> | ||
<version>2.39</version> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.jenkins-ci.plugins.workflow</groupId> | ||
<artifactId>workflow-job</artifactId> | ||
<version>2.11.2</version> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.jenkins-ci.plugins.workflow</groupId> | ||
<artifactId>workflow-basic-steps</artifactId> | ||
<version>2.6</version> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.jenkins-ci.plugins.workflow</groupId> | ||
<artifactId>workflow-durable-task-step</artifactId> | ||
<version>2.13</version> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.jenkins-ci.plugins.workflow</groupId> | ||
<artifactId>workflow-api</artifactId> | ||
<version>2.20</version> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.jenkins-ci.plugins.workflow</groupId> | ||
<artifactId>workflow-support</artifactId> | ||
<version>2.14</version> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
|
||
<repositories> | ||
<repository> | ||
<id>repo.jenkins-ci.org</id> | ||
<url>https://repo.jenkins-ci.org/public/</url> | ||
</repository> | ||
</repositories> | ||
|
||
<pluginRepositories> | ||
<pluginRepository> | ||
<id>repo.jenkins-ci.org</id> | ||
<url>https://repo.jenkins-ci.org/public/</url> | ||
</pluginRepository> | ||
</pluginRepositories> | ||
</project> |
20 changes: 20 additions & 0 deletions
20
jenkins/hello-world/src/main/java/com/baeldung/jenkins/helloworld/ProjectStats.java
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,20 @@ | ||
package com.baeldung.jenkins.helloworld; | ||
|
||
public class ProjectStats { | ||
|
||
private final int classesNumber; | ||
private final int linesNumber; | ||
|
||
public ProjectStats(int classesNumber, int linesNumber) { | ||
this.classesNumber = classesNumber; | ||
this.linesNumber = linesNumber; | ||
} | ||
|
||
public int getClassesNumber() { | ||
return classesNumber; | ||
} | ||
|
||
public int getLinesNumber() { | ||
return linesNumber; | ||
} | ||
} |
123 changes: 123 additions & 0 deletions
123
...s/hello-world/src/main/java/com/baeldung/jenkins/helloworld/ProjectStatsBuildWrapper.java
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,123 @@ | ||
package com.baeldung.jenkins.helloworld; | ||
|
||
import hudson.Extension; | ||
import hudson.FilePath; | ||
import hudson.Launcher; | ||
import hudson.model.AbstractBuild; | ||
import hudson.model.AbstractProject; | ||
import hudson.model.BuildListener; | ||
import hudson.tasks.BuildWrapper; | ||
import hudson.tasks.BuildWrapperDescriptor; | ||
import org.kohsuke.stapler.DataBoundConstructor; | ||
|
||
import javax.annotation.Nonnull; | ||
import java.io.*; | ||
import java.nio.charset.StandardCharsets; | ||
import java.util.Stack; | ||
|
||
public class ProjectStatsBuildWrapper extends BuildWrapper { | ||
|
||
private static final String REPORT_TEMPLATE_PATH = "/stats.html"; | ||
private static final String PROJECT_NAME_VAR = "$PROJECT_NAME$"; | ||
private static final String CLASSES_NUMBER_VAR = "$CLASSES_NUMBER$"; | ||
private static final String LINES_NUMBER_VAR = "$LINES_NUMBER$"; | ||
|
||
@DataBoundConstructor | ||
public ProjectStatsBuildWrapper() { | ||
} | ||
|
||
@Override | ||
public Environment setUp(AbstractBuild build, final Launcher launcher, BuildListener listener) { | ||
return new Environment() { | ||
@Override | ||
public boolean tearDown(AbstractBuild build, BuildListener listener) | ||
throws IOException, InterruptedException | ||
{ | ||
ProjectStats stats = buildStats(build.getWorkspace()); | ||
String report = generateReport(build.getProject().getDisplayName(), stats); | ||
File artifactsDir = build.getArtifactsDir(); | ||
if (!artifactsDir.isDirectory()) { | ||
boolean success = artifactsDir.mkdirs(); | ||
if (!success) { | ||
listener.getLogger().println("Can't create artifacts directory at " | ||
+ artifactsDir.getAbsolutePath()); | ||
} | ||
} | ||
String path = artifactsDir.getCanonicalPath() + REPORT_TEMPLATE_PATH; | ||
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path), | ||
StandardCharsets.UTF_8))) { | ||
writer.write(report); | ||
} | ||
return super.tearDown(build, listener); | ||
} | ||
}; | ||
} | ||
|
||
private static ProjectStats buildStats(FilePath root) throws IOException, InterruptedException { | ||
int classesNumber = 0; | ||
int linesNumber = 0; | ||
Stack<FilePath> toProcess = new Stack<>(); | ||
toProcess.push(root); | ||
while (!toProcess.isEmpty()) { | ||
FilePath path = toProcess.pop(); | ||
if (path.isDirectory()) { | ||
toProcess.addAll(path.list()); | ||
} else if (path.getName().endsWith(".java")) { | ||
classesNumber++; | ||
linesNumber += countLines(path); | ||
} | ||
} | ||
return new ProjectStats(classesNumber, linesNumber); | ||
} | ||
|
||
private static int countLines(FilePath path) throws IOException, InterruptedException { | ||
byte[] buffer = new byte[1024]; | ||
int result = 1; | ||
try (InputStream in = path.read()) { | ||
while (true) { | ||
int read = in.read(buffer); | ||
if (read < 0) { | ||
return result; | ||
} | ||
for (int i = 0; i < read; i++) { | ||
if (buffer[i] == '\n') { | ||
result++; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
private static String generateReport(String projectName, ProjectStats stats) throws IOException { | ||
ByteArrayOutputStream bOut = new ByteArrayOutputStream(); | ||
try (InputStream in = ProjectStatsBuildWrapper.class.getResourceAsStream(REPORT_TEMPLATE_PATH)) { | ||
byte[] buffer = new byte[1024]; | ||
int read; | ||
while ((read = in.read(buffer)) >= 0) { | ||
bOut.write(buffer, 0, read); | ||
} | ||
} | ||
String content = new String(bOut.toByteArray(), StandardCharsets.UTF_8); | ||
content = content.replace(PROJECT_NAME_VAR, projectName); | ||
content = content.replace(CLASSES_NUMBER_VAR, String.valueOf(stats.getClassesNumber())); | ||
content = content.replace(LINES_NUMBER_VAR, String.valueOf(stats.getLinesNumber())); | ||
return content; | ||
} | ||
|
||
@Extension | ||
public static final class DescriptorImpl extends BuildWrapperDescriptor { | ||
|
||
@Override | ||
public boolean isApplicable(AbstractProject<?, ?> item) { | ||
return true; | ||
} | ||
|
||
@Nonnull | ||
@Override | ||
public String getDisplayName() { | ||
return "Construct project stats during build"; | ||
} | ||
|
||
} | ||
|
||
} |
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,20 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<title>$PROJECT_NAME$</title> | ||
</head> | ||
<body> | ||
Project $PROJECT_NAME$: | ||
<table border="1"> | ||
<tr> | ||
<th>Classes number</th> | ||
<th>Lines number</th> | ||
</tr> | ||
<tr> | ||
<td>$CLASSES_NUMBER$</td> | ||
<td>$LINES_NUMBER$</td> | ||
</tr> | ||
</table> | ||
</body> | ||
</html> |