From 6e263bc4663b65c3872d78240898daf7fb274b7b Mon Sep 17 00:00:00 2001 From: timii Date: Wed, 18 Jun 2014 21:20:25 +0300 Subject: [PATCH] - Refactored to use extension model \n - Now it is possible to choose which pareser the build uses --- .gitignore | 4 +- pom.xml | 179 ++++---- .../AbstractSematicParserDescription.java | 9 + .../InvalidBuildFileFormatException.java | 7 +- .../SemanticVersionBuildWrapper.java | 412 ++++++++++-------- .../AbstractBuildDefinitionParser.java | 21 + .../parsing/BuildDefinitionParser.java | 11 +- .../parsing/BuildScalaParser.java | 37 +- .../SemanticVersioning/parsing/PomParser.java | 162 +++++-- .../SemanticVersioning/parsing/SbtParser.java | 42 +- .../SemanticVersionBuildWrapper/config.jelly | 3 + 11 files changed, 548 insertions(+), 339 deletions(-) create mode 100644 src/main/java/org/jenkinsci/plugins/SemanticVersioning/AbstractSematicParserDescription.java create mode 100644 src/main/java/org/jenkinsci/plugins/SemanticVersioning/parsing/AbstractBuildDefinitionParser.java diff --git a/.gitignore b/.gitignore index 50412ab..ee6eda8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,6 @@ target/ work/ .idea/ *.iml - +.project +.settings +.classpath diff --git a/pom.xml b/pom.xml index 57bcdd7..6936b4f 100644 --- a/pom.xml +++ b/pom.xml @@ -1,100 +1,105 @@ - - 4.0.0 - - org.jenkins-ci.plugins - plugin - 1.554 - + + 4.0.0 + + org.jenkins-ci.plugins + plugin + 1.554 + - semantic-versioning-plugin - 1.2-SNAPSHOT - hpi + semantic-versioning-plugin + 1.2-SNAPSHOT + hpi - Semantic Versioning Plugin + Semantic Versioning Plugin - http://wiki.jenkins-ci.org/display/JENKINS/semantic-versioning-plugin + http://wiki.jenkins-ci.org/display/JENKINS/semantic-versioning-plugin - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.17 - - true - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.8.1 - - - attach-javadocs - package + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + attach-javadocs + package - - jar - - - - - - + + jar + + + + + + + - - - org.apache.logging.log4j - log4j-api - 2.0-rc1 - - - org.apache.logging.log4j - log4j-core - 2.0-rc1 - - + + + org.apache.logging.log4j + log4j-api + 2.0-rc1 + + + org.apache.logging.log4j + log4j-core + 2.0-rc1 + + + org.jenkins-ci.main + maven-plugin + 1.509.2 + + - - - ciroque - Steve Wagner - scalawagz@outlook.com - - + + + ciroque + Steve Wagner + scalawagz@outlook.com + + - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - - + + + repo.jenkins-ci.org + http://repo.jenkins-ci.org/public/ + + - - - - org.codehaus.mojo - findbugs-maven-plugin - 2.5.3 - - true - target/site - - - - + + + + org.codehaus.mojo + findbugs-maven-plugin + 2.5.3 + + true + target/site + + + + - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - - + + + repo.jenkins-ci.org + http://repo.jenkins-ci.org/public/ + + - - scm:git:ssh://github.com/jenkinsci/semantic-versioning-plugin.git - scm:git:ssh://git@github.com/jenkinsci/semantic-versioning-plugin.git - https://github.com/jenkinsci/semantic-versioning-plugin - + + scm:git:ssh://github.com/jenkinsci/semantic-versioning-plugin.git + scm:git:ssh://git@github.com/jenkinsci/semantic-versioning-plugin.git + https://github.com/jenkinsci/semantic-versioning-plugin + diff --git a/src/main/java/org/jenkinsci/plugins/SemanticVersioning/AbstractSematicParserDescription.java b/src/main/java/org/jenkinsci/plugins/SemanticVersioning/AbstractSematicParserDescription.java new file mode 100644 index 0000000..887bbc6 --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/SemanticVersioning/AbstractSematicParserDescription.java @@ -0,0 +1,9 @@ +package org.jenkinsci.plugins.SemanticVersioning; + + +public abstract class AbstractSematicParserDescription extends hudson.model.Descriptor { + + @Override + public abstract String getDisplayName(); + +} diff --git a/src/main/java/org/jenkinsci/plugins/SemanticVersioning/InvalidBuildFileFormatException.java b/src/main/java/org/jenkinsci/plugins/SemanticVersioning/InvalidBuildFileFormatException.java index 0fb394c..731dd2a 100644 --- a/src/main/java/org/jenkinsci/plugins/SemanticVersioning/InvalidBuildFileFormatException.java +++ b/src/main/java/org/jenkinsci/plugins/SemanticVersioning/InvalidBuildFileFormatException.java @@ -25,7 +25,12 @@ package org.jenkinsci.plugins.SemanticVersioning; public class InvalidBuildFileFormatException extends Exception { - public InvalidBuildFileFormatException(String message) { + /** + * + */ + private static final long serialVersionUID = 1L; + + public InvalidBuildFileFormatException(String message) { super(message); } } diff --git a/src/main/java/org/jenkinsci/plugins/SemanticVersioning/SemanticVersionBuildWrapper.java b/src/main/java/org/jenkinsci/plugins/SemanticVersioning/SemanticVersionBuildWrapper.java index 8c48b96..80707d7 100644 --- a/src/main/java/org/jenkinsci/plugins/SemanticVersioning/SemanticVersionBuildWrapper.java +++ b/src/main/java/org/jenkinsci/plugins/SemanticVersioning/SemanticVersionBuildWrapper.java @@ -28,199 +28,249 @@ import hudson.Extension; import hudson.FilePath; import hudson.Launcher; -import hudson.model.AbstractBuild; -import hudson.model.AbstractProject; import hudson.model.BuildListener; import hudson.model.TaskListener; +import hudson.model.AbstractBuild; +import hudson.model.AbstractProject; +import hudson.model.Descriptor.FormException; import hudson.tasks.BuildWrapper; import hudson.tasks.BuildWrapperDescriptor; import hudson.util.FormValidation; +import hudson.util.ListBoxModel; + +import java.io.File; +import java.io.IOException; +import java.util.Map; + +import jenkins.model.Jenkins; import net.sf.json.JSONObject; + import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.jenkinsci.plugins.SemanticVersioning.parsing.*; +import org.jenkinsci.plugins.SemanticVersioning.parsing.BuildDefinitionParser; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Map; - public class SemanticVersionBuildWrapper extends BuildWrapper { - private static final String DEFAULT_ENVIRONMENT_VARIABLE_NAME = "SEMANTIC_APP_VERSION"; - private static final String MISSING_BUILD_NUMBER = "-1"; - private String environmentVariableName = DEFAULT_ENVIRONMENT_VARIABLE_NAME; - private static Logger logger = LogManager.getLogger(AppVersion.class); - - @DataBoundConstructor - public SemanticVersionBuildWrapper(String environmentVariableName) { - logger.info("### SemanticVersionBuildWrapper"); - this.environmentVariableName = environmentVariableName; - } - - /** - * Used from config.jelly. - * @return the value of the environment variable name to be used. - */ - public String getEnvironmentVariableName() { - logger.info("### SemanticVersionBuildWrapper::getEnvironmentVariableName"); - return this.environmentVariableName; - } - - /** - * Used from config.jelly. - * @return the name of the file in which the semantic version will be stored. - */ - public String getSemanticVersionFilename() { - return ".semanticVersion"; - } - - @Override - public Environment setUp(AbstractBuild build, Launcher launcher, BuildListener listener) { - logger.debug("### SemanticVersionBuildWrapper::setUp"); - AppVersion appVersion = getAppVersion(build); - String buildNumber = getJenkinsBuildNumber(build); - - appVersion.setBuild(Integer.parseInt(buildNumber)); - - logger.debug("### SemanticVersionBuildWrapper::setUp -> appVersion found to be: {" + getEnvironmentVariableName() + ": " + appVersion.getOriginal() + ", buildNumber: " + buildNumber + ", combined: " + appVersion.toString() + "}\n"); - - final String reportedVersion = appVersion.toString(); - - writeVersionToFile(build, reportedVersion); - - return new Environment() { - @Override - public void buildEnvVars(Map env) { - env.put(getEnvironmentVariableName(), reportedVersion); - } - }; - } - - private void writeVersionToFile(AbstractBuild build, String reportedVersion) { - String filename = getSemanticVersionFilename(); - if(filename != null && filename.length() > 0) { - File file = new File(build.getArtifactsDir() + "/" + filename); - logger.info(build.getArtifactsDir() + "/" + filename); - try { - FileUtils.writeStringToFile(file, reportedVersion + "\n"); - } catch (IOException e) { - logger.debug("Exception writing version to file: " + e); - } - } - } - - private AppVersion getAppVersion(AbstractBuild build) { - logger.debug("### SemanticVersionBuildWrapper::getAppVersion"); - AppVersion appVersion = AppVersion.EmptyVersion; - FilePath workspace = build.getWorkspace(); - - Collection parsers = new ArrayList(); - parsers.add(new PomParser(workspace + "/pom.xml")); - parsers.add(new BuildScalaParser(workspace + "/project/Build.scala")); - parsers.add(new SbtParser(workspace + "/build.sbt")); - - for(BuildDefinitionParser parser : parsers) { - try { - logger.debug("### SemanticVersionBuildWrapper::getAppVersion -> attempting to parse using " + parser.getClass().getSimpleName()); - appVersion = parser.extractAppVersion(); - return appVersion; - } catch (IOException e) { - logger.error("EXCEPTION: " + e); - } catch (InvalidBuildFileFormatException e) { - logger.error("EXCEPTION: " + e); - } - } - - return appVersion; - } - - private String getJenkinsBuildNumber(AbstractBuild build) { - logger.debug("### SemanticVersionBuildWrapper::getJenkinsBuildNumber"); - EnvVars environmentVariables = null; - try { - environmentVariables = build.getEnvironment(TaskListener.NULL); - } catch (IOException e) { - logger.error("EXCEPTION: " + e); - } catch (InterruptedException e) { - logger.error("EXCEPTION: " + e); - } - return environmentVariables != null ? environmentVariables.get("BUILD_NUMBER", MISSING_BUILD_NUMBER) : MISSING_BUILD_NUMBER; - } - - @Extension - public static final DescriptorImpl descriptor = new DescriptorImpl(); - - @Override - public BuildWrapperDescriptor getDescriptor() { - return descriptor; - } - - /** - * descriptor for {@link SemanticVersionBuildWrapper}. Used as a singleton. - * The class is marked as public so that it can be accessed from views. - * See src/main/resources/hudson/plugins/hello_world/SbtVersionExtracter/*.jelly - * for the actual HTML fragment for the configuration screen. - */ - public static final class DescriptorImpl extends BuildWrapperDescriptor { - - /** - * In order to load the persisted global configuration, you have to - * call load() in the constructor. - */ - public DescriptorImpl() { - super(SemanticVersionBuildWrapper.class); - logger.debug("### DescriptorImpl"); - load(); - } - - /** - * This human readable name is used in the configuration screen. - * @return the display name for the plugin - */ - public String getDisplayName() { - logger.debug("### DescriptorImpl::getDisplayName"); - return "Determine Semantic Version for project"; - } - - @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { - logger.debug("### DescriptorImpl::configure"); - return super.configure(req, json); - } - - @Override - public boolean isApplicable(AbstractProject abstractProject) { - logger.debug("### DescriptorImpl::isApplicable"); - return true; - } - - /** - * Performs on-the-fly validation of the form field 'name'. - * - * @param value This parameter receives the value that the user has typed. - * @return Indicates the outcome of the validation. This is sent to the browser. - */ - public FormValidation doCheckEnvironmentVariableName(@QueryParameter String value) { - logger.debug("### DescriptorImpl::doCheckEnvironmentVariableName"); - if (value.length() == 0) - return FormValidation.error("Please set a name"); - if (value.length() < 4) - return FormValidation.warning("Isn't the name too short?"); - return FormValidation.ok(); - } - - /** - * Gets the default value for the environment variable name. - * @return the default value for the environment variable name. - */ - public String getDefaultEnvironmentVariableName() { - logger.debug("### DescriptorImpl::getDefaultEnvironmentVariableName"); - return SemanticVersionBuildWrapper.DEFAULT_ENVIRONMENT_VARIABLE_NAME; - } - } + private static final String DEFAULT_ENVIRONMENT_VARIABLE_NAME = "SEMANTIC_APP_VERSION"; + private static final String MISSING_BUILD_NUMBER = "-1"; + private String environmentVariableName = DEFAULT_ENVIRONMENT_VARIABLE_NAME; + private static Logger logger = LogManager.getLogger(AppVersion.class); + private BuildDefinitionParser parser; + + @DataBoundConstructor + public SemanticVersionBuildWrapper(String environmentVariableName, + String parser) { + logger.info("### SemanticVersionBuildWrapper"); + this.environmentVariableName = environmentVariableName; + try { + this.parser = (BuildDefinitionParser) Jenkins.getInstance() + .getExtensionList(parser).iterator().next(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } + + /** + * Used from config.jelly. + * + * @return the value of the environment variable name to be used. + */ + public String getEnvironmentVariableName() { + logger.info("### SemanticVersionBuildWrapper::getEnvironmentVariableName"); + return this.environmentVariableName; + } + + /** + * Used from config.jelly. + * + * @return the name of the file in which the semantic version will be + * stored. + */ + public String getSemanticVersionFilename() { + return ".semanticVersion"; + } + + + /** + * Used from config.jelly. + * + * @return the canonical class name of the parser which the semantic version use + * to parse version number + */ + public String getParser() { + return this.parser.getClass().getCanonicalName(); + } + + @Override + public Environment setUp(AbstractBuild build, Launcher launcher, + BuildListener listener) { + logger.debug("### SemanticVersionBuildWrapper::setUp"); + AppVersion appVersion = getAppVersion(build); + String buildNumber = getJenkinsBuildNumber(build); + + appVersion.setBuild(Integer.parseInt(buildNumber)); + + logger.debug("### SemanticVersionBuildWrapper::setUp -> appVersion found to be: {" + + getEnvironmentVariableName() + + ": " + + appVersion.getOriginal() + + ", buildNumber: " + + buildNumber + + ", combined: " + appVersion.toString() + "}\n"); + + final String reportedVersion = appVersion.toString(); + + writeVersionToFile(build, reportedVersion); + + return new Environment() { + @Override + public void buildEnvVars(Map env) { + env.put(getEnvironmentVariableName(), reportedVersion); + } + }; + } + + private void writeVersionToFile(AbstractBuild build, String reportedVersion) { + String filename = getSemanticVersionFilename(); + if (filename != null && filename.length() > 0) { + File file = new File(build.getArtifactsDir() + "/" + filename); + logger.info(build.getArtifactsDir() + "/" + filename); + try { + FileUtils.writeStringToFile(file, reportedVersion + "\n"); + } catch (IOException e) { + logger.debug("Exception writing version to file: " + e); + } + } + } + + private AppVersion getAppVersion(AbstractBuild build) { + logger.debug("### SemanticVersionBuildWrapper::getAppVersion"); + AppVersion appVersion = AppVersion.EmptyVersion; + if (this.parser != null) { + try { + logger.info("### SemanticVersionBuildWrapper::getAppVersion -> attempting to parse using " + + parser.getClass().getSimpleName()); + return parser.extractAppVersion(build); + + } catch (IOException e) { + logger.error("EXCEPTION: " + e); + } catch (InvalidBuildFileFormatException e) { + logger.error("EXCEPTION: " + e); + } + } + + return appVersion; + } + + private String getJenkinsBuildNumber(AbstractBuild build) { + logger.debug("### SemanticVersionBuildWrapper::getJenkinsBuildNumber"); + EnvVars environmentVariables = null; + try { + environmentVariables = build.getEnvironment(TaskListener.NULL); + } catch (IOException e) { + logger.error("EXCEPTION: " + e); + } catch (InterruptedException e) { + logger.error("EXCEPTION: " + e); + } + return environmentVariables != null ? environmentVariables.get( + "BUILD_NUMBER", MISSING_BUILD_NUMBER) : MISSING_BUILD_NUMBER; + } + + @Extension + public static final DescriptorImpl descriptor = new DescriptorImpl(); + + @Override + public BuildWrapperDescriptor getDescriptor() { + return descriptor; + } + + /** + * descriptor for {@link SemanticVersionBuildWrapper}. Used as a singleton. + * The class is marked as public so that it can be accessed from views. See + * src/main/resources/hudson/plugins/hello_world/SbtVersionExtracter/*.jelly + * for the actual HTML fragment for the configuration screen. + */ + public static final class DescriptorImpl extends BuildWrapperDescriptor { + + /** + * In order to load the persisted global configuration, you have to call + * load() in the constructor. + */ + public DescriptorImpl() { + super(SemanticVersionBuildWrapper.class); + logger.debug("### DescriptorImpl"); + load(); + } + + /** + * This human readable name is used in the configuration screen. + * + * @return the display name for the plugin + */ + public String getDisplayName() { + logger.debug("### DescriptorImpl::getDisplayName"); + return "Determine Semantic Version for project"; + } + + @Override + public boolean configure(StaplerRequest req, JSONObject json) + throws FormException { + logger.debug("### DescriptorImpl::configure"); + + return super.configure(req, json); + } + + @Override + public boolean isApplicable(AbstractProject abstractProject) { + logger.debug("### DescriptorImpl::isApplicable"); + return true; + } + + /** + * Performs on-the-fly validation of the form field 'name'. + * + * @param value + * This parameter receives the value that the user has typed. + * @return Indicates the outcome of the validation. This is sent to the + * browser. + */ + public FormValidation doCheckEnvironmentVariableName( + @QueryParameter String value) { + logger.debug("### DescriptorImpl::doCheckEnvironmentVariableName"); + if (value.isEmpty()) + return FormValidation.error("Please set a name"); + if (value.length() < 4) + return FormValidation.warning("Isn't the name too short?"); + return FormValidation.ok(); + } + + /** + * Generates LisBoxModel for available BuildDefinitionParsers + * + * @return available BuildDefinitionParsers as ListBoxModel + */ + public ListBoxModel doFillParserItems() { + ListBoxModel parsersModel = new ListBoxModel(); + for (BuildDefinitionParser parser : Jenkins.getInstance() + .getExtensionList(BuildDefinitionParser.class)) { + parsersModel.add(parser.getDescriptor().getDisplayName(), parser + .getClass().getCanonicalName()); + } + + return parsersModel; + } + + /** + * Gets the default value for the environment variable name. + * + * @return the default value for the environment variable name. + */ + public String getDefaultEnvironmentVariableName() { + logger.debug("### DescriptorImpl::getDefaultEnvironmentVariableName"); + return SemanticVersionBuildWrapper.DEFAULT_ENVIRONMENT_VARIABLE_NAME; + } + } } diff --git a/src/main/java/org/jenkinsci/plugins/SemanticVersioning/parsing/AbstractBuildDefinitionParser.java b/src/main/java/org/jenkinsci/plugins/SemanticVersioning/parsing/AbstractBuildDefinitionParser.java new file mode 100644 index 0000000..e205ad8 --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/SemanticVersioning/parsing/AbstractBuildDefinitionParser.java @@ -0,0 +1,21 @@ +package org.jenkinsci.plugins.SemanticVersioning.parsing; + +import hudson.ExtensionList; +import hudson.model.Describable; +import jenkins.model.Jenkins; + +import org.apache.tools.ant.ExtensionPoint; + +/** + * BuilDefinitionParser abstraction layer for better backward compatibility + * @author timii + * + */ + +public abstract class AbstractBuildDefinitionParser extends ExtensionPoint implements BuildDefinitionParser { + + public static ExtensionList getParsers() { + return Jenkins.getInstance().getExtensionList(BuildDefinitionParser.class); + } + +} diff --git a/src/main/java/org/jenkinsci/plugins/SemanticVersioning/parsing/BuildDefinitionParser.java b/src/main/java/org/jenkinsci/plugins/SemanticVersioning/parsing/BuildDefinitionParser.java index 44edddb..821a929 100644 --- a/src/main/java/org/jenkinsci/plugins/SemanticVersioning/parsing/BuildDefinitionParser.java +++ b/src/main/java/org/jenkinsci/plugins/SemanticVersioning/parsing/BuildDefinitionParser.java @@ -24,11 +24,14 @@ package org.jenkinsci.plugins.SemanticVersioning.parsing; -import org.jenkinsci.plugins.SemanticVersioning.AppVersion; -import org.jenkinsci.plugins.SemanticVersioning.InvalidBuildFileFormatException; +import hudson.model.Describable; +import hudson.model.AbstractBuild; import java.io.IOException; -public interface BuildDefinitionParser { - AppVersion extractAppVersion() throws IOException, InvalidBuildFileFormatException; +import org.jenkinsci.plugins.SemanticVersioning.AppVersion; +import org.jenkinsci.plugins.SemanticVersioning.InvalidBuildFileFormatException; + +public interface BuildDefinitionParser extends Describable { + AppVersion extractAppVersion(AbstractBuild build) throws IOException, InvalidBuildFileFormatException; } diff --git a/src/main/java/org/jenkinsci/plugins/SemanticVersioning/parsing/BuildScalaParser.java b/src/main/java/org/jenkinsci/plugins/SemanticVersioning/parsing/BuildScalaParser.java index 32dba1e..152482f 100644 --- a/src/main/java/org/jenkinsci/plugins/SemanticVersioning/parsing/BuildScalaParser.java +++ b/src/main/java/org/jenkinsci/plugins/SemanticVersioning/parsing/BuildScalaParser.java @@ -25,25 +25,34 @@ package org.jenkinsci.plugins.SemanticVersioning.parsing; import org.apache.commons.io.FileUtils; +import org.jenkinsci.plugins.SemanticVersioning.AbstractSematicParserDescription; import org.jenkinsci.plugins.SemanticVersioning.AppVersion; import org.jenkinsci.plugins.SemanticVersioning.InvalidBuildFileFormatException; +import hudson.Extension; +import hudson.model.AbstractBuild; +import hudson.model.Descriptor; + import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class BuildScalaParser implements BuildDefinitionParser { +@Extension +public class BuildScalaParser extends AbstractBuildDefinitionParser { - private final String filename; + private static final String BUILD_DEFINITION_FILENAME = "Build.scala"; + public BuildScalaParser() { } + + @Deprecated public BuildScalaParser(String filename) { - this.filename = filename; + } - public AppVersion extractAppVersion() throws InvalidBuildFileFormatException, IOException { - File file = new File(filename); + public AppVersion extractAppVersion(AbstractBuild build) throws InvalidBuildFileFormatException, IOException { + File file = new File(BUILD_DEFINITION_FILENAME); if(file.exists()) { Pattern extendsBuild = Pattern.compile(".*extends\\s+Build.*"); @@ -57,17 +66,29 @@ public AppVersion extractAppVersion() throws InvalidBuildFileFormatException, IO if(found) { version = matcher.toMatchResult().group(1); } else { - throw new InvalidBuildFileFormatException("No version information found in " + filename); + throw new InvalidBuildFileFormatException("No version information found in " + BUILD_DEFINITION_FILENAME); } return AppVersion.parse(version); } else { - throw new InvalidBuildFileFormatException("'" + filename + "' is not a valid build definition file."); + throw new InvalidBuildFileFormatException("'" + BUILD_DEFINITION_FILENAME + "' is not a valid build definition file."); } } else { - throw new FileNotFoundException("'" + filename + "' was not found."); + throw new FileNotFoundException("'" + BUILD_DEFINITION_FILENAME + "' was not found."); } } + + @SuppressWarnings("unchecked") + public Descriptor getDescriptor() { + return new AbstractSematicParserDescription() { + + @Override + public String getDisplayName() { + + return "Build Scala Parserer"; + } + }; + } } diff --git a/src/main/java/org/jenkinsci/plugins/SemanticVersioning/parsing/PomParser.java b/src/main/java/org/jenkinsci/plugins/SemanticVersioning/parsing/PomParser.java index f827d49..a56ffe1 100644 --- a/src/main/java/org/jenkinsci/plugins/SemanticVersioning/parsing/PomParser.java +++ b/src/main/java/org/jenkinsci/plugins/SemanticVersioning/parsing/PomParser.java @@ -24,10 +24,19 @@ package org.jenkinsci.plugins.SemanticVersioning.parsing; -import org.jenkinsci.plugins.SemanticVersioning.AppVersion; -import org.jenkinsci.plugins.SemanticVersioning.InvalidBuildFileFormatException; -import org.w3c.dom.Document; -import org.xml.sax.SAXException; +import hudson.Extension; +import hudson.FilePath; +import hudson.FilePath.FileCallable; +import hudson.maven.AbstractMavenBuild; +import hudson.maven.MavenBuild; +import hudson.maven.MavenModuleSet; +import hudson.model.AbstractBuild; +import hudson.model.Descriptor; +import hudson.remoting.VirtualChannel; + +import java.io.File; +import java.io.IOException; +import java.util.Map; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -36,47 +45,108 @@ import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -public class PomParser implements BuildDefinitionParser { - - private final String filename; - - public PomParser(String filename) { - - this.filename = filename; - } - - public AppVersion extractAppVersion() throws IOException, InvalidBuildFileFormatException { - File file = new File(filename); - if (file.exists()) { - - String version = null; - DocumentBuilder documentBuilder = null; - try { - documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - Document document = documentBuilder.parse(file); - XPath xPath = XPathFactory.newInstance().newXPath(); - XPathExpression expression = xPath.compile("/project/version"); - version = expression.evaluate(document); - } catch (ParserConfigurationException e) { - e.printStackTrace(); - } catch (SAXException e) { - e.printStackTrace(); - throw new InvalidBuildFileFormatException(filename + " is not a valid POM file."); - } catch (XPathExpressionException e) { - e.printStackTrace(); - } - - if(version == null || version.length() == 0) { - throw new InvalidBuildFileFormatException("No version information found in " + filename); - } - - return AppVersion.parse(version); - } else { - throw new FileNotFoundException("'" + filename + "' was not found."); - } - } +import jenkins.model.Jenkins; + +import org.jenkinsci.plugins.SemanticVersioning.AbstractSematicParserDescription; +import org.jenkinsci.plugins.SemanticVersioning.AppVersion; +import org.jenkinsci.plugins.SemanticVersioning.InvalidBuildFileFormatException; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; + +@Extension +public class PomParser extends AbstractBuildDefinitionParser { + + private static final String BUILD_FILE = "pom.xml"; + + public PomParser() { + } + + @Deprecated + public PomParser(String filename) { + } + + public AppVersion extractAppVersion(AbstractBuild build) + throws IOException, InvalidBuildFileFormatException { + String version = null; + + Document document = getPom((AbstractMavenBuild) build); + XPath xPath = XPathFactory.newInstance().newXPath(); + XPathExpression expression; + try { + expression = xPath.compile("/project/version"); + version = expression.evaluate(document); + + } catch (XPathExpressionException e) { + throw new InvalidBuildFileFormatException(document.getBaseURI() + + " is not a valid POM file."); + } + + if (version == null || version.length() == 0) { + throw new InvalidBuildFileFormatException( + "No version information found in " + document.getBaseURI()); + } + return AppVersion.parse(version); + } + + private Document getPom(AbstractMavenBuild mavenBuild) + throws InvalidBuildFileFormatException, IOException { + FilePath moduleRoot = mavenBuild.getModuleRoot(); + MavenModuleSet project = (MavenModuleSet) mavenBuild.getProject(); + FilePath pom = null; + + if (moduleRoot.getName().endsWith(BUILD_FILE)) { + pom = moduleRoot; + } else { + pom = new FilePath(moduleRoot, project.getRootPOM()); + } + + Document pomDocument = null; + try { + pomDocument = pom.act(new FileCallable() { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public Document invoke(File pom, VirtualChannel channel) + throws IOException, InterruptedException { + + try { + DocumentBuilder documentBuilder = null; + documentBuilder = DocumentBuilderFactory.newInstance() + .newDocumentBuilder(); + return documentBuilder.parse(pom); + + } catch (SAXException e) { + throw new InterruptedException(pom + .getAbsolutePath() + + " is not a valid POM file."); + } catch (ParserConfigurationException e) { + throw new InterruptedException(pom + .getAbsolutePath() + + " is not a valid POM file."); + } + } + + }); + } catch (InterruptedException e) { + throw new InvalidBuildFileFormatException(e.getMessage()); + } + + return pomDocument; + } + + @SuppressWarnings("unchecked") + public Descriptor getDescriptor() { + return new AbstractSematicParserDescription() { + + @Override + public String getDisplayName() { + + return "Maven Pom Parserer"; + } + }; + } } diff --git a/src/main/java/org/jenkinsci/plugins/SemanticVersioning/parsing/SbtParser.java b/src/main/java/org/jenkinsci/plugins/SemanticVersioning/parsing/SbtParser.java index 58c1fb7..1b435f4 100644 --- a/src/main/java/org/jenkinsci/plugins/SemanticVersioning/parsing/SbtParser.java +++ b/src/main/java/org/jenkinsci/plugins/SemanticVersioning/parsing/SbtParser.java @@ -24,9 +24,9 @@ package org.jenkinsci.plugins.SemanticVersioning.parsing; -import org.apache.commons.io.FileUtils; -import org.jenkinsci.plugins.SemanticVersioning.AppVersion; -import org.jenkinsci.plugins.SemanticVersioning.InvalidBuildFileFormatException; +import hudson.Extension; +import hudson.model.AbstractBuild; +import hudson.model.Descriptor; import java.io.File; import java.io.FileNotFoundException; @@ -34,20 +34,28 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -public class SbtParser implements BuildDefinitionParser { +import org.apache.commons.io.FileUtils; +import org.jenkinsci.plugins.SemanticVersioning.AbstractSematicParserDescription; +import org.jenkinsci.plugins.SemanticVersioning.AppVersion; +import org.jenkinsci.plugins.SemanticVersioning.InvalidBuildFileFormatException; + +@Extension +public class SbtParser extends AbstractBuildDefinitionParser { - private final String filename; + private static final String BUILD_DEFINITION_FILENAME = "build.sbt"; + public SbtParser() {} + + @Deprecated public SbtParser(String filename) { - this.filename = filename; } - public AppVersion extractAppVersion() throws IOException, InvalidBuildFileFormatException { - File file = new File(filename); + public AppVersion extractAppVersion(AbstractBuild build) throws IOException, InvalidBuildFileFormatException { + File file = new File(BUILD_DEFINITION_FILENAME); if(file.exists()) { String content = FileUtils.readFileToString(file); if(content == null || content.length() <= 0) { - throw new InvalidBuildFileFormatException("'" + filename + "' is not a valid SBT build definition file."); + throw new InvalidBuildFileFormatException("'" + BUILD_DEFINITION_FILENAME + "' is not a valid SBT build definition file."); } else { String version; Pattern pattern = Pattern.compile("version\\s*:=\\s*\"([^\"]*)\"", Pattern.CASE_INSENSITIVE); @@ -55,13 +63,25 @@ public AppVersion extractAppVersion() throws IOException, InvalidBuildFileFormat if(matcher.find()) { version = matcher.toMatchResult().group(1); } else { - throw new InvalidBuildFileFormatException("No version information found in " + filename); + throw new InvalidBuildFileFormatException("No version information found in " + BUILD_DEFINITION_FILENAME); } return AppVersion.parse(version); } } else { - throw new FileNotFoundException("'" + filename + "' was not found."); + throw new FileNotFoundException("'" + BUILD_DEFINITION_FILENAME + "' was not found."); } } + + @SuppressWarnings("unchecked") + public Descriptor getDescriptor() { + return new AbstractSematicParserDescription() { + + @Override + public String getDisplayName() { + + return "SBT Scala build parserer"; + } + }; + } } diff --git a/src/main/resources/org/jenkinsci/plugins/SemanticVersioning/SemanticVersionBuildWrapper/config.jelly b/src/main/resources/org/jenkinsci/plugins/SemanticVersioning/SemanticVersionBuildWrapper/config.jelly index 2b77780..ded4852 100644 --- a/src/main/resources/org/jenkinsci/plugins/SemanticVersioning/SemanticVersionBuildWrapper/config.jelly +++ b/src/main/resources/org/jenkinsci/plugins/SemanticVersioning/SemanticVersionBuildWrapper/config.jelly @@ -27,6 +27,9 @@ Creates a text field that shows the value of the "name" property. When submitted, it will be passed to the corresponding constructor parameter. --> + + +