1 /* 2 * Copyright 2006-2012 smartics, Kronseder & Reiner GmbH 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package de.smartics.maven.plugin.buildmetadata; 17 18 import java.io.File; 19 import java.text.DateFormat; 20 import java.text.SimpleDateFormat; 21 import java.util.Date; 22 import java.util.Locale; 23 import java.util.Properties; 24 25 import org.apache.maven.plugin.MojoExecutionException; 26 import org.apache.maven.plugin.MojoFailureException; 27 import org.apache.maven.scm.manager.ScmManager; 28 import org.apache.maven.settings.Settings; 29 import org.codehaus.plexus.util.StringUtils; 30 31 import de.smartics.maven.plugin.buildmetadata.common.Constant; 32 import de.smartics.maven.plugin.buildmetadata.common.ScmControl; 33 import de.smartics.maven.plugin.buildmetadata.common.ScmCredentials; 34 import de.smartics.maven.plugin.buildmetadata.common.ScmInfo; 35 import de.smartics.maven.plugin.buildmetadata.data.HostMetaDataProvider; 36 import de.smartics.maven.plugin.buildmetadata.data.MavenMetaDataProvider; 37 import de.smartics.maven.plugin.buildmetadata.data.MavenMetaDataSelection; 38 import de.smartics.maven.plugin.buildmetadata.data.ScmMetaDataProvider; 39 import de.smartics.maven.plugin.buildmetadata.io.BuildPropertiesFileHelper; 40 import de.smartics.maven.plugin.buildmetadata.io.BuildXmlFileHelper; 41 import de.smartics.maven.plugin.buildmetadata.scm.ScmNoRevisionException; 42 import de.smartics.maven.util.LoggingUtils; 43 44 /** 45 * Provides the build information defined in {@link Constant}. This information 46 * is also written to a properties file. 47 * 48 * @goal provide-buildmetadata 49 * @phase initialize 50 * @requiresProject 51 * @threadSafe 52 * @since 1.0 53 * @description Provides a build meta data to the build process. 54 */ 55 public final class BuildMetaDataMojo extends AbstractBuildMojo // NOPMD 56 { // NOPMD 57 // ********************************* Fields ********************************* 58 59 // --- constants ------------------------------------------------------------ 60 61 // --- members -------------------------------------------------------------- 62 63 // ... Mojo infrastructure .................................................. 64 65 /** 66 * The user's settings. 67 * 68 * @parameter expression="${settings}" 69 * @required 70 * @readonly 71 * @since 1.0 72 */ 73 private Settings settings; 74 75 /** 76 * If set to <code>true</code>, build properties will be generate even if they 77 * already exist in the target folder. 78 * 79 * @parameter default-value="false" 80 * @since 1.0 81 */ 82 private boolean forceNewProperties; 83 84 /** 85 * In offline mode the plugin will not generate revision information. 86 * 87 * @parameter default-value="${settings.offline}" 88 * @required 89 * @readonly 90 * @since 1.0 91 */ 92 private boolean offline; 93 94 /** 95 * Add SCM information if set to <code>true</code>, skip it, if set to 96 * <code>false</code>. If you are not interested in SCM information, set this 97 * to <code>false</code>. 98 * <p> 99 * For security reasons you may want to remove the properties file from the 100 * META-INF folder. Please refer to <code>propertiesOutputFile</code> 101 * property. 102 * </p> 103 * 104 * @parameter expression="${buildMetaData.addScmInfo}" default-value="true" 105 * @since 1.0 106 */ 107 private boolean addScmInfo; 108 109 /** 110 * Fail if revision is requested to be retrieved, access to SCM is provided, 111 * system is online, nothing should prevent the build from fetching the 112 * information. 113 * <p> 114 * If set to <code>true</code> the build will fail, if revision cannot be 115 * fetched under the conditions mentioned above. If set to <code>false</code> 116 * the build will continue silently so that the meta data do not contain the 117 * revision. 118 * </p> 119 * 120 * @parameter expression="${buildMetaData.failOnMissingRevision}" 121 * default-value="false" 122 * @since 1.0 123 */ 124 private boolean failOnMissingRevision; 125 126 /** 127 * Add host information if set to <code>true</code>, skip it, if set to 128 * <code>false</code>. If you are not interested in host information (e.g. for 129 * security reasons), set this to <code>false</code>. 130 * <p> 131 * For security reasons you may want to remove the properties file from the 132 * META-INF folder. Please refer to <code>propertiesOutputFile</code> 133 * property. 134 * </p> 135 * 136 * @parameter expression="${buildMetaData.addHostInfo}" default-value="true" 137 * @since 1.0 138 */ 139 private boolean addHostInfo; 140 141 /** 142 * Add environment variables if set to <code>true</code>, skip it, if set to 143 * <code>false</code>. If you are not interested in the environment variables 144 * of the host (e.g. for security reasons), set this to <code>false</code>. 145 * <p> 146 * For security reasons you may want to remove the properties file from the 147 * META-INF folder. Please refer to <code>propertiesOutputFile</code> 148 * property. 149 * </p> 150 * 151 * @parameter expression="${buildMetaData.addEnvInfo}" default-value="false" 152 * @since 1.0 153 */ 154 private boolean addEnvInfo; 155 156 /** 157 * Add information about the Java runtime running the build if set to 158 * <code>true</code>, skip it, if set to <code>false</code>. 159 * 160 * @parameter expression="${buildMetaData.addJavaRuntimeInfo}" 161 * default-value="true" 162 * @since 1.0 163 */ 164 private boolean addJavaRuntimeInfo; 165 166 /** 167 * Add information about the operating system the build is run in if set to 168 * <code>true</code>, skip it, if set to <code>false</code>. 169 * 170 * @parameter expression="${buildMetaData.addOsInfo}" default-value="true" 171 * @since 1.0 172 */ 173 private boolean addOsInfo; 174 175 /** 176 * Add Maven execution information (all properties starting with 177 * <code>build.maven.execution</code>, like command line, goals, profiles, 178 * etc.) if set to <code>true</code>, skip it, if set to <code>false</code>. 179 * If you are not interested in execution information, set this to 180 * <code>false</code>. 181 * <p> 182 * For security reasons you may want to remove the properties file from the 183 * META-INF folder. Please refer to <code>propertiesOutputFile</code> 184 * property. 185 * </p> 186 * 187 * @parameter expression="${buildMetaData.addMavenExecutionInfo}" 188 * default-value="true" 189 * @since 1.0 190 */ 191 private boolean addMavenExecutionInfo; 192 193 /** 194 * Add project information (homepage URL, categories, tags, etc.) if set to 195 * <code>true</code>, skip it, if set to <code>false</code>. If you are not 196 * interested in execution information, set this to <code>false</code>. 197 * 198 * @parameter expression="${buildMetaData.addProjectInfo}" 199 * default-value="false" 200 * @since 1.1 201 */ 202 private boolean addProjectInfo; 203 204 /** 205 * While the command line may be useful to refer to for a couple of reasons, 206 * displaying it with the build properties is a security issue. Some plugins 207 * allow to read passwords as properties from the command line and this 208 * sensible data will be shown. 209 * <p> 210 * Therefore the command line is hidden by default (<code>true</code>). If you 211 * want to include this information, use a value of <code>false</code>. 212 * </p> 213 * 214 * @parameter expression="${buildMetaData.hideCommandLineInfo}" 215 * default-value="true" 216 * @since 1.0 217 */ 218 private boolean hideCommandLineInfo; 219 220 /** 221 * While the <code>MAVEN_OPTS</code> may be useful to refer to for a couple of 222 * reasons, displaying them with the build properties is a security issue. 223 * Some plugins allow to read passwords as properties from the command line 224 * and this sensible data will be shown. 225 * <p> 226 * Therefore the <code>MAVEN_OPTS</code> are hidden by default ( 227 * <code>true</code>). If you want to include this information, use a value of 228 * <code>false</code>. 229 * </p> 230 * <p> 231 * This exclusion does not prevent the property from being written as part of 232 * <code>addEnvInfo</code>! 233 * </p> 234 * 235 * @parameter expression="${buildMetaData.hideMavenOptsInfo}" 236 * default-value="true" 237 * @since 1.0 238 */ 239 private boolean hideMavenOptsInfo; 240 241 /** 242 * While the <code>JAVA_OPTS</code> may be useful to refer to for a couple of 243 * reasons, displaying them with the build properties is a security issue. 244 * Some plugins allow to read passwords as properties from the command line 245 * and this sensible data will be shown. 246 * <p> 247 * Therefore the <code>JAVA_OPTS</code> are hidden by default ( 248 * <code>true</code>). If you want to include this information, use a value of 249 * <code>false</code>. 250 * </p> 251 * <p> 252 * This exclusion does not prevent the property from being written as part of 253 * <code>addEnvInfo</code>! 254 * </p> 255 * 256 * @parameter expression="${buildMetaData.hideJavaOptsInfo}" 257 * default-value="true" 258 * @since 1.0 259 */ 260 private boolean hideJavaOptsInfo; 261 262 /** 263 * A simple flag to skip the generation of the build information. If set on 264 * the command line use <code>-DbuildMetaData.skip</code>. 265 * 266 * @parameter expression="${buildMetaData.skip}" default-value="false" 267 * @since 1.0 268 */ 269 private boolean skip; 270 271 /** 272 * If it should be checked if the local files are up-to-date with the remote 273 * files in the SCM repository. If the value is <code>true</code> the result 274 * of the check, including the list of changed files, is added to the build 275 * meta data. 276 * 277 * @parameter expression="${buildMetaData.validateCheckout}" 278 * default-value="true" 279 * @since 1.0 280 */ 281 private boolean validateCheckout; 282 283 /** 284 * Specifies the log level used for this plugin. 285 * <p> 286 * Allowed values are <code>SEVERE</code>, <code>WARNING</code>, 287 * <code>INFO</code> and <code>FINEST</code>. 288 * </p> 289 * 290 * @parameter expression="${buildMetaData.logLevel}" 291 * @since 1.0 292 */ 293 private String logLevel; 294 295 /** 296 * The manager instance to access the SCM system. Provides access to the 297 * repository and the provider information. 298 * 299 * @component 300 * @since 1.0 301 */ 302 private ScmManager scmManager; 303 304 /** 305 * Allows the user to choose which scm connection to use when connecting to 306 * the scm. Can either be "connection" or "developerConnection". 307 * 308 * @parameter default-value="connection" 309 * @required 310 * @since 1.0 311 */ 312 private String connectionType; 313 314 // ... core information ..................................................... 315 316 /** 317 * The date pattern to use to format the build and revision dates. Please 318 * refer to the <a href = 319 * "http://java.sun.com/j2se/1.5.0/docs/api/java/text/SimpleDateFormat.html" 320 * >SimpleDateFormat</a> class for valid patterns. 321 * 322 * @parameter expression="${buildMetaData.buildDate.pattern}" 323 * default-value="dd.MM.yyyy" 324 * @since 1.0 325 */ 326 protected String buildDatePattern = Constant.DEFAULT_DATE_PATTERN; // NOPMD 327 328 /** 329 * The property to query for the build user. 330 * 331 * @parameter default-value="username" 332 * @since 1.0 333 */ 334 private String buildUserPropertyName; 335 336 // ... build information related ............................................ 337 338 /** 339 * Flag to add the build date to the full version separated by a '-'. If 340 * <code>true</code> the build date is added, if <code>false</code> it is not. 341 * 342 * @parameter expression="${buildMetaData.addBuildDateToFullVersion}" 343 * default-value="true" 344 * @since 1.0 345 */ 346 private boolean addBuildDateToFullVersion; 347 348 // ... svn related .......................................................... 349 350 /** 351 * Used to specify the date format of the log entries that are retrieved from 352 * your SCM system. 353 * 354 * @parameter expression="${changelog.dateFormat}" 355 * default-value="yyyy-MM-dd HH:mm:ss" 356 * @required 357 * @since 1.0 358 */ 359 private String scmDateFormat; 360 361 /** 362 * Input dir. Directory where the files under SCM control are located. 363 * 364 * @parameter expression="${basedir}" 365 * @required 366 * @since 1.0 367 */ 368 private File basedir; 369 370 /** 371 * The user name (used by svn and starteam protocol). 372 * 373 * @parameter expression="${username}" 374 * @since 1.0 375 */ 376 private String userName; 377 378 /** 379 * The user password (used by svn and starteam protocol). 380 * 381 * @parameter expression="${password}" 382 * @since 1.0 383 */ 384 private String password; 385 386 /** 387 * The private key (used by java svn). 388 * 389 * @parameter expression="${privateKey}" 390 * @since 1.0 391 */ 392 private String privateKey; 393 394 /** 395 * The passphrase (used by java svn). 396 * 397 * @parameter expression="${passphrase}" 398 * @since 1.0 399 */ 400 private String passphrase; 401 402 /** 403 * The url of tags base directory (used by svn protocol). 404 * 405 * @parameter expression="${tagBase}" 406 * @since 1.0 407 */ 408 private String tagBase; 409 410 /** 411 * Flag to add the revision number to the full version separated by an 'r'. If 412 * <code>true</code> the revision number is added, if <code>false</code> it is 413 * not. 414 * 415 * @parameter expression="${buildMetaData.addReleaseNumberToFullVersion}" 416 * default-value="true" 417 * @since 1.0 418 */ 419 private boolean addReleaseNumberToFullVersion; 420 421 /** 422 * Flag to add the tag <code>-locally-modified</code> to the full version 423 * string to make visible that this artifact has been created with locally 424 * modified sources. This is often the case while the artifact is built while 425 * still working on an issue before it is committed to the SCM repository. 426 * 427 * @parameter expression="${buildMetaData.addLocallyModifiedTagToFullVersion}" 428 * default-value="true" 429 * @since 1.0 430 */ 431 private boolean addLocallyModifiedTagToFullVersion; 432 433 /** 434 * The range of the query in days to fetch change log entries from the SCM. If 435 * no change logs have been found, the range is incremented up to {@value 436 * de.smartics.maven.plugin.buildmetadata.scm.maven.ScmAccessInfo;# 437 * DEFAULT_RETRY_COUNT} (5) times. If no change log has been found after these 438 * {@value de.smartics.maven.plugin.buildmetadata.scm.maven.ScmAccessInfo;# 439 * DEFAULT_RETRY_COUNT} (5) additional queries, the revision number will not 440 * be set with a valid value. 441 * 442 * @parameter expression="${buildMetaData.queryRangeInDays}" 443 * default-value="30" 444 * @since 1.0 445 */ 446 private int queryRangeInDays; 447 448 /** 449 * Flag to fail if local modifications have been found. The value is 450 * <code>true</code> if the build should fail if there are modifications (any 451 * files not in-sync with the remote repository), <code>false</code> if the 452 * fact is only to be noted in the build properties. 453 * 454 * @parameter default-value="false" 455 * @since 1.0 456 */ 457 private boolean failOnLocalModifications; 458 459 /** 460 * The flag to ignore files and directories starting with a dot for checking 461 * modified files. This implicates that any files or directories, starting 462 * with a dot, are ignored when the check on changed files is run. If the 463 * value is <code>true</code>, dot files are ignored, if it is set to 464 * <code>false</code>, dot files are respected. 465 * 466 * @parameter default-value="true" 467 * @since 1.0 468 */ 469 private boolean ignoreDotFilesInBaseDir; 470 471 // ****************************** Initializer ******************************* 472 473 // ****************************** Constructors ****************************** 474 475 // ****************************** Inner Classes ***************************** 476 477 // ********************************* Methods ******************************** 478 479 // --- init ----------------------------------------------------------------- 480 481 // --- get&set -------------------------------------------------------------- 482 483 // --- business ------------------------------------------------------------- 484 485 /** 486 * {@inheritDoc} 487 */ 488 public void execute() throws MojoExecutionException, MojoFailureException 489 { 490 if (!skip) 491 { 492 super.execute(); 493 494 final BuildPropertiesFileHelper helper = 495 new BuildPropertiesFileHelper(getLog(), propertiesOutputFile); 496 final Properties projectProperties = helper.getProjectProperties(project); 497 if (!isBuildPropertiesAlreadySet(projectProperties)) 498 { 499 LoggingUtils.configureLogger(getLog(), logLevel); 500 final Properties buildMetaDataProperties = new Properties(); 501 if (isBuildPropertiesToBeRebuild()) 502 { 503 final Date buildDate = session.getStartTime(); 504 505 provideBuildUser(projectProperties, buildMetaDataProperties); 506 provideMavenMetaData(buildMetaDataProperties); 507 provideHostMetaData(buildMetaDataProperties); 508 final ScmInfo scmInfo = provideScmMetaData(buildMetaDataProperties); 509 provideBuildDateMetaData(buildMetaDataProperties, buildDate); 510 511 // The custom providers are required to be run at the end. 512 // This allows these providers to access the information generated 513 // by the built-in providers. 514 provideBuildMetaData(buildMetaDataProperties, scmInfo, providers, 515 false); 516 517 writeBuildMetaData(helper, buildMetaDataProperties); 518 } 519 else 520 { 521 getLog().info("Reusing previously built metadata file."); 522 helper.readBuildPropertiesFile(buildMetaDataProperties); 523 } 524 525 updateMavenEnvironment(buildMetaDataProperties, helper); 526 } 527 } 528 else 529 { 530 getLog().info("Skipping buildmetadata collection since skip=true."); 531 } 532 } 533 534 private void writeBuildMetaData(final BuildPropertiesFileHelper helper, 535 final Properties buildMetaDataProperties) throws MojoExecutionException 536 { 537 helper.writePropertiesFile(buildMetaDataProperties); 538 if (createXmlReport) 539 { 540 final BuildXmlFileHelper xmlHelper = 541 new BuildXmlFileHelper(getLog(), this.xmlOutputFile, this.properties); 542 xmlHelper.writeXmlFile(buildMetaDataProperties); 543 } 544 } 545 546 private void provideMavenMetaData(final Properties buildMetaDataProperties) 547 { 548 final MavenMetaDataSelection selection = new MavenMetaDataSelection(); 549 selection.setAddMavenExecutionInfo(addMavenExecutionInfo); 550 selection.setAddEnvInfo(addEnvInfo); 551 selection.setAddJavaRuntimeInfo(addJavaRuntimeInfo); 552 selection.setAddOsInfo(addOsInfo); 553 selection.setAddProjectInfo(addProjectInfo); 554 selection.setHideCommandLineInfo(hideCommandLineInfo); 555 selection.setHideJavaOptsInfo(hideJavaOptsInfo); 556 selection.setHideMavenOptsInfo(hideMavenOptsInfo); 557 selection.setSelectedSystemProperties(properties); 558 559 final MavenMetaDataProvider mavenMetaDataProvider = 560 new MavenMetaDataProvider(project, session, runtime, selection); 561 mavenMetaDataProvider.provideBuildMetaData(buildMetaDataProperties); 562 } 563 564 private ScmInfo provideScmMetaData(final Properties buildMetaDataProperties) 565 throws MojoFailureException 566 { 567 try 568 { 569 final ScmInfo scmInfo = createScmInfo(); 570 final ScmMetaDataProvider scmMetaDataProvider = 571 new ScmMetaDataProvider(project, scmInfo); 572 scmMetaDataProvider.provideBuildMetaData(buildMetaDataProperties); 573 return scmInfo; 574 } 575 catch (final ScmNoRevisionException e) 576 { 577 throw new MojoFailureException(e.getMessage()); // NOPMD 578 } 579 } 580 581 private void provideHostMetaData(final Properties buildMetaDataProperties) 582 throws MojoExecutionException 583 { 584 if (addHostInfo) 585 { 586 final HostMetaDataProvider hostMetaData = new HostMetaDataProvider(); 587 hostMetaData.provideBuildMetaData(buildMetaDataProperties); 588 } 589 } 590 591 private void provideBuildDateMetaData( 592 final Properties buildMetaDataProperties, final Date buildDate) 593 { 594 final String buildDateString = 595 createBuildDate(buildMetaDataProperties, buildDate); 596 createYears(buildMetaDataProperties, buildDate); 597 createBuildVersion(buildMetaDataProperties, buildDate, buildDateString); 598 } 599 600 private ScmInfo createScmInfo() 601 { 602 final ScmCredentials scmCredentials = 603 new ScmCredentials(settings, userName, password, privateKey, passphrase); 604 final ScmControl scmControl = 605 new ScmControl(failOnLocalModifications, ignoreDotFilesInBaseDir, 606 offline, addScmInfo, validateCheckout, failOnMissingRevision); 607 final ScmInfo scmInfo = 608 new ScmInfo(scmManager, connectionType, scmDateFormat, basedir, 609 scmCredentials, tagBase, queryRangeInDays, buildDatePattern, 610 scmControl); 611 return scmInfo; 612 } 613 614 private boolean isBuildPropertiesToBeRebuild() 615 { 616 return forceNewProperties || !propertiesOutputFile.exists(); 617 } 618 619 private boolean isBuildPropertiesAlreadySet(final Properties projectProperties) 620 { 621 return projectProperties.getProperty(Constant.PROP_NAME_FULL_VERSION) != null; 622 } 623 624 /** 625 * Provides the name of the user running the build. The value is either 626 * specified in the project properties or is taken from the Java system 627 * properties (<code>user.name</code>). 628 * 629 * @param projectProperties the project properties. 630 * @param buildMetaDataProperties the build meta data properties. 631 */ 632 private void provideBuildUser(final Properties projectProperties, 633 final Properties buildMetaDataProperties) 634 { 635 String userNameValue = System.getProperty("user.name"); 636 if ((buildUserPropertyName != null)) 637 { 638 final String value = projectProperties.getProperty(buildUserPropertyName); 639 if (!StringUtils.isBlank(value)) 640 { 641 userNameValue = value; 642 } 643 } 644 645 if (userNameValue != null) 646 { 647 buildMetaDataProperties.setProperty(Constant.PROP_NAME_BUILD_USER, 648 userNameValue); 649 } 650 } 651 652 /** 653 * Creates and adds the build date information. 654 * 655 * @param buildMetaDataProperties the build meta data properties. 656 * @param buildDate the date of the build. 657 * @return the formatted build date. 658 */ 659 private String createBuildDate(final Properties buildMetaDataProperties, 660 final Date buildDate) 661 { 662 final DateFormat format = 663 new SimpleDateFormat(buildDatePattern, Locale.ENGLISH); 664 final String buildDateString = format.format(buildDate); 665 final String timestamp = String.valueOf(buildDate.getTime()); 666 667 buildMetaDataProperties.setProperty(Constant.PROP_NAME_BUILD_DATE, 668 buildDateString); 669 buildMetaDataProperties.setProperty(Constant.PROP_NAME_BUILD_DATE_PATTERN, 670 this.buildDatePattern); 671 buildMetaDataProperties.setProperty(Constant.PROP_NAME_BUILD_TIMESTAMP, 672 timestamp); 673 674 return buildDateString; 675 } 676 677 /** 678 * Adds the build and copyright year information. 679 * 680 * @param buildMetaDataProperties the build meta data properties. 681 * @param buildDate the build date to create the build year information. 682 */ 683 private void createYears(final Properties buildMetaDataProperties, 684 final Date buildDate) 685 { 686 final DateFormat yearFormat = new SimpleDateFormat("yyyy", Locale.ENGLISH); 687 final String buildYearString = yearFormat.format(buildDate); 688 buildMetaDataProperties.setProperty(Constant.PROP_NAME_BUILD_YEAR, 689 buildYearString); 690 final String inceptionYearString = project.getInceptionYear(); 691 final String copyrightYearString = 692 (buildYearString.equals(inceptionYearString) ? inceptionYearString 693 : inceptionYearString + '-' + buildYearString); 694 buildMetaDataProperties.setProperty(Constant.PROP_NAME_COPYRIGHT_YEAR, 695 copyrightYearString); 696 } 697 698 /** 699 * Adds the version information of the artifact. 700 * 701 * @param buildMetaDataProperties the build meta data properties. 702 * @param buildDate the date of the build. 703 * @param buildDateString the formatted date string. 704 */ 705 private void createBuildVersion(final Properties buildMetaDataProperties, 706 final Date buildDate, final String buildDateString) 707 { 708 final String version = project.getVersion(); 709 buildMetaDataProperties.setProperty(Constant.PROP_NAME_VERSION, version); 710 buildMetaDataProperties.setProperty(Constant.PROP_NAME_GROUP_ID, 711 project.getGroupId()); 712 buildMetaDataProperties.setProperty(Constant.PROP_NAME_ARTIFACT_ID, 713 project.getArtifactId()); 714 buildMetaDataProperties.setProperty(Constant.PROP_NAME_BUILD_DATE, 715 buildDateString); 716 717 final String fullVersion = 718 createFullVersion(buildMetaDataProperties, buildDate); 719 buildMetaDataProperties.setProperty(Constant.PROP_NAME_FULL_VERSION, 720 fullVersion); 721 } 722 723 /** 724 * Creates the full version string which may include the date, the build, and 725 * the revision. 726 * 727 * @param buildMetaDataProperties the generated build meta data properties. 728 * @param buildDate the date of the current build. 729 * @return the full version string. 730 */ 731 private String createFullVersion(final Properties buildMetaDataProperties, 732 final Date buildDate) 733 { 734 final String version = project.getVersion(); 735 736 final DateFormat format = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH); 737 final String datePart = format.format(buildDate); 738 final String revisionId = 739 buildMetaDataProperties.getProperty(Constant.PROP_NAME_SCM_REVISION_ID); 740 741 final String versionPrefix, versionSuffix; 742 if (version.endsWith("-SNAPSHOT")) 743 { 744 versionPrefix = version.substring(0, version.lastIndexOf('-')); 745 versionSuffix = "-SNAPSHOT"; 746 } 747 else 748 { 749 versionPrefix = version; 750 versionSuffix = ""; 751 } 752 753 final String modified; 754 if (addLocallyModifiedTagToFullVersion 755 && "true".equals(buildMetaDataProperties 756 .getProperty(Constant.PROP_NAME_SCM_LOCALLY_MODIFIED))) 757 { 758 modified = "-locally-modified"; 759 } 760 else 761 { 762 modified = ""; 763 } 764 765 final String fullVersion = 766 versionPrefix 767 + (addBuildDateToFullVersion ? '-' + datePart : "") 768 + (addReleaseNumberToFullVersion 769 && StringUtils.isNotBlank(revisionId) ? "r" + revisionId : "") 770 + modified + versionSuffix; 771 772 return fullVersion; 773 } 774 775 // --- object basics -------------------------------------------------------- 776 777 }