Nova Ordis Utilities Version Metadata Handling: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
 
(25 intermediate revisions by the same user not shown)
Line 3: Line 3:
* [[Novaordis-utilities#Subjects|novaordis-utilities]]
* [[Novaordis-utilities#Subjects|novaordis-utilities]]
* [[projects#Patterns|projects]]
* [[projects#Patterns|projects]]
* [[novaordis-release-tools]]
* [[nort]]
* [[clad]]
* [[clad]]


Line 13: Line 13:


In order to insure that the artifacts are built to contain version metadata, follow the instructions provided in the "[[#Build_Infrastructure_Configuration|Build Infrastructure Configuration]]" section, below.
In order to insure that the artifacts are built to contain version metadata, follow the instructions provided in the "[[#Build_Infrastructure_Configuration|Build Infrastructure Configuration]]" section, below.
There is also a "light" version reporting capability, implemented by [[bash-wrapper-functions]], described below ([[#.22Light.22_Version_Reporting|"Light" Version Reporting]]).


=Code=
=Code=
Line 24: Line 26:
==VERSION File==
==VERSION File==


Place a <tt>VERSION</tt> file in the <tt>src/main/resources</tt> directory of the project. It should have the following content:
Place a <tt>VERSION</tt> file in the <tt>src/main/resources</tt> directory of the project. It should have the following content -make sure to add a new line after the last line:


<pre>
<pre>
Line 31: Line 33:
</pre>
</pre>


If the project was initialized with [[novaordis-release-tools]], this should have been done automatically already. For more details see "[[Nova_Ordis_Release_Tools_User_Manual_-_Concepts#New_Project_Initialization|New Project Initialization with NORT]]".
If the project produces a [[Building a Maven Complex Release Artifact|Maven-based complex release artifact]], with a "release" module, then place the <tt>VERSION</tt> file in <tt>$PROJECT_HOME/release/src/main/resources</tt>.
 
If the project was initialized with [[nort]], this should have been done automatically already. For more details see "[[nort Concepts#New_Project_Initialization|New Project Initialization with nort]]".
 
==Custom Resource File==
 
<blockquote style="background-color: Gold; border: solid thin Goldenrod;">
:<br>If multiple JAR artifacts present on the same classpath use the same versioning mechanism, there will be collisions, so in this case is best to use an artifact-specific version file name, instead of the generic VERSION.<br><br>
</blockquote>
 
VersionUtilities support using custom version files instead of the "VERSION" default, by exposing the get...(String fileName) methods.


==${version} and ${release_date} in the In-Line Documentation of the Project==
==${version} and ${release_date} in the In-Line Documentation of the Project==
Line 44: Line 56:
==Define maven.build.timestamp.format and release_date==
==Define maven.build.timestamp.format and release_date==


Make sure your POM file contains the definition of the build timestamp format and <tt>release_date</tt>, as follows:
Make sure the top-level POM file of your project contains the definition of the build timestamp format and <tt>release_date</tt>, as follows:


<pre>
<pre>
Line 57: Line 69:
The "version" property is available by default.
The "version" property is available by default.


==Configure the Maven Resources Plugin==
==Enable Variable Substitution==
 
The variable substitution can be enabled in two different way, depending on how the final artifact is being built. If the default artifact building mechanism is in effect, the variable substitution will be performed by the Maven resource plugin, as described in the "[[#Configure_the_Maven_Resources_Plugin|Configure the Maven Resources Plugin]]" section. If the project produces a [[Building a Maven Complex Release Artifact|Maven-based complex release artifact]], with a "release" module, the variable substitution will be performed by the assembly plugin and it can be configured as described in the "[[#Configure_Assembly_Variable_Substitution|Configure Assembly Variable Substitution]]" section.


Make sure the Maven Resources Plugin is available and configured as described here: [[Maven Resources Plugin#Variable_Substitution_in_Resource_Files|variable substitution in resource files]].
===Configure the Maven Resources Plugin===
 
Make sure the [[Maven Resources Plugin]] is available and configured as described here: [[Maven Resources Plugin#Variable_Substitution_in_Resource_Files|variable substitution in resource files]].


Essentially, we want:
Essentially, we want:
Line 66: Line 82:
<filtering>true</filtering>
<filtering>true</filtering>
</pre>
</pre>
===Configure Assembly Variable Substitution===
Add the following section to the assembly descriptor:
<pre>
<assembly ...>
  ...
  <files>
    ...
    <file>
      <source>./src/main/resources/VERSION</source>
      <outputDirectory>lib</outputDirectory>
      <filtered>true</filtered>
    </file>
    ...
  </files>
</assembly>
</pre>
More details on assembly filtering configuration are available in here: "[[Custom_Maven_Assembly_Descriptors#Filtering_and_System_Property_Substitution|Assembly Filtering and System Property Substitution]]".


==Usage==
==Usage==
Line 71: Line 108:
When all of the above are completed, the final artifact should contain correctly resolved <tt>${version}</tt> and <tt>${release_date}</tt> in all resources that have been filtered.
When all of the above are completed, the final artifact should contain correctly resolved <tt>${version}</tt> and <tt>${release_date}</tt> in all resources that have been filtered.


To get the version and release date programmatically, use the following code:
To get the version and release date programmatically, use the following [[#Code|API]].
 
The utility code can be used as part of [[clad]] or directly.
 
Example:


<blockquote style="background-color: AliceBlue; border: solid thin LightSteelBlue;">
<pre>
:<br>https://github.com/NovaOrdis/novaordis-utilities/blob/master/src/main/java/io/novaordis/utilities/VersionUtilities.java<br><br>
String version = VersionUtilities.getVersion();
</blockquote>
String releaseDate = VersionUtilities.getReleaseDate();
               
System.out.println("version " + version);
System.out.println("release date " + releaseDate);
</pre>


The utility code can be used as part of [[clad]] or directly.
="Light" Version Reporting=


The "light" version reporting capability is implemented by [[bash-wrapper-functions]]. It consists in a get-version() bash function that attempts to locate the VERSION file. If found, the information contained by the filed is displayed, and the "version" command is handled at the shell level, and not passed to the Java runtime. If the file is not found, the command is passed to the Java runtime.


See: {{Internal|bash-wrapper-functions|bash-wrapper-functions}}


<font color=red>
{{Warn|Light version reporting is only appropriate for a command line utility that executes quickly and exit. For long running processes, where the version of the code that is executing may potentially be different than the version of the code on the disk, immediately after an upgrade, this mechanism is not recommended.}}
* Verify that the POM file contains the definition of <tt>maven.build.timestamp.format</tt> and <tt>release_date</tt>, as required by [[project Version and Release Date#Define_maven.build.timestamp.format_and_release_date]]. If it does not, inject it.
</font>

Latest revision as of 20:09, 31 July 2017

Internal

Overview

The mechanism relies on a project build pattern and a set of APIs to expose the version and release data of application in a standard manner. The mechanism is used by most of the Nova Ordis projects. clad builds upon it and exposes the version and release metadata as result of the "version" command, which is available by default to all clad-based applications.

The mechanism relies on the presence of a "VERSION" metadata file in the application's classpath. VersionUtilities.getVersion() and VersionUtilities.getReleaseDate() can be used as top-level API to locate, process and display the metadata. In case the metadata file is not found, the both methods log the condition using SLF4J warn() and return null.

In order to insure that the artifacts are built to contain version metadata, follow the instructions provided in the "Build Infrastructure Configuration" section, below.

There is also a "light" version reporting capability, implemented by bash-wrapper-functions, described below ("Light" Version Reporting).

Code

https://github.com/NovaOrdis/novaordis-utilities/blob/master/src/main/java/io/novaordis/utilities/version/VersionUtilities.java

Build Infrastructure Configuration

VERSION File

Place a VERSION file in the src/main/resources directory of the project. It should have the following content -make sure to add a new line after the last line:

version=${version}
release_date=${release_date}

If the project produces a Maven-based complex release artifact, with a "release" module, then place the VERSION file in $PROJECT_HOME/release/src/main/resources.

If the project was initialized with nort, this should have been done automatically already. For more details see "New Project Initialization with nort".

Custom Resource File


If multiple JAR artifacts present on the same classpath use the same versioning mechanism, there will be collisions, so in this case is best to use an artifact-specific version file name, instead of the generic VERSION.

VersionUtilities support using custom version files instead of the "VERSION" default, by exposing the get...(String fileName) methods.

${version} and ${release_date} in the In-Line Documentation of the Project

Since we are going to use the Maven resource plugin to filter resources and replace variables, you can also use ${version} and ${release_date} in the in-line documentation, for example the main USAGE file. Example:

myApp version ${version} released on ${release_date}
...

Define maven.build.timestamp.format and release_date

Make sure the top-level POM file of your project contains the definition of the build timestamp format and release_date, as follows:

    ...
    <properties>
        <maven.build.timestamp.format>MM/dd/yy</maven.build.timestamp.format>
        <release_date>${maven.build.timestamp}</release_date>
    </properties>
    ...

The "version" property is available by default.

Enable Variable Substitution

The variable substitution can be enabled in two different way, depending on how the final artifact is being built. If the default artifact building mechanism is in effect, the variable substitution will be performed by the Maven resource plugin, as described in the "Configure the Maven Resources Plugin" section. If the project produces a Maven-based complex release artifact, with a "release" module, the variable substitution will be performed by the assembly plugin and it can be configured as described in the "Configure Assembly Variable Substitution" section.

Configure the Maven Resources Plugin

Make sure the Maven Resources Plugin is available and configured as described here: variable substitution in resource files.

Essentially, we want:

<filtering>true</filtering>

Configure Assembly Variable Substitution

Add the following section to the assembly descriptor:

<assembly ...>
  ...
  <files>
    ...
    <file>
       <source>./src/main/resources/VERSION</source>
       <outputDirectory>lib</outputDirectory>
       <filtered>true</filtered>
    </file>
    ...
  </files>
</assembly>

More details on assembly filtering configuration are available in here: "Assembly Filtering and System Property Substitution".

Usage

When all of the above are completed, the final artifact should contain correctly resolved ${version} and ${release_date} in all resources that have been filtered.

To get the version and release date programmatically, use the following API.

The utility code can be used as part of clad or directly.

Example:

String version = VersionUtilities.getVersion();
String releaseDate = VersionUtilities.getReleaseDate();
                
System.out.println("version " + version);
System.out.println("release date " + releaseDate);

"Light" Version Reporting

The "light" version reporting capability is implemented by bash-wrapper-functions. It consists in a get-version() bash function that attempts to locate the VERSION file. If found, the information contained by the filed is displayed, and the "version" command is handled at the shell level, and not passed to the Java runtime. If the file is not found, the command is passed to the Java runtime.

See:

bash-wrapper-functions

Light version reporting is only appropriate for a command line utility that executes quickly and exit. For long running processes, where the version of the code that is executing may potentially be different than the version of the code on the disk, immediately after an upgrade, this mechanism is not recommended.