true
(the default), missing build.properties bin.includes will cause
- * build failure. If set to false
, missing build.properties bin.includes will be
- * reported as warnings but the build will not fail.
- */
- @Parameter(defaultValue = "true")
- protected boolean strictBinIncludes;
-
- /**
- * Additional files to be included in the final .jar
.
- *
- * A typical usage might be when bin.includes
in build.properties
- * is not flexible enough, e.g., for generated files, as when conflicting additional files
- * win over bin.includes
.
- *
- * Example: - *
- * <additionalFileSets> - * <fileSet> - * <directory>${project.build.directory}/mytool-gen/</directory> - * <includes> - * <include>**/*</include> - * </includes> - * </fileSet> - * </additionalFileSets> - *- * Note: currently, additional file sets are not used for the
package-iu
goal.
- */
- @Parameter
- protected DefaultFileSet[] additionalFileSets;
-
- @Component
- protected PlexusContainer plexus;
-
- @Component
- protected MavenProjectHelper projectHelper;
-
- @Component(role = TychoProject.class)
- private Maptrue
(the default), missing build.properties
+ * bin.includes will cause build failure. If set to false
, missing
+ * build.properties bin.includes will be reported as warnings but the build will
+ * not fail.
+ */
+ @Parameter(defaultValue = "true")
+ protected boolean strictBinIncludes;
- return fileSet;
- }
+ /**
+ * Additional files to be included in the final .jar
.
+ *
+ * A typical usage might be when bin.includes
in
+ * build.properties
is not flexible enough, e.g., for generated
+ * files, as when conflicting additional files win over
+ * bin.includes
.
+ *
+ * Example: + * + *
+ * <additionalFileSets> + * <fileSet> + * <directory>${project.build.directory}/mytool-gen/</directory> + * <includes> + * <include>**/*</include> + * </includes> + * </fileSet> + * </additionalFileSets> + *+ * + * Note: currently, additional file sets are not used for the + *
package-iu
goal.
+ */
+ @Parameter
+ protected DefaultFileSet[] additionalFileSets;
+
+ @Component
+ protected PlexusContainer plexus;
- protected TychoProject getTychoProjectFacet() {
- return getTychoProjectFacet(project.getPackaging());
- }
+ @Component
+ protected MavenProjectHelper projectHelper;
- protected TychoProject getTychoProjectFacet(String packaging) {
- TychoProject facet = projectTypes.get(packaging);
- if (facet == null) {
- throw new IllegalStateException("Unknown or unsupported packaging type " + packaging);
- }
- return facet;
- }
+ @Component(role = TychoProject.class)
+ private MapaddMavenDescriptor
flag, which indicates
- * whether the generated archive will contain the pom.xml and pom.properties file. If no archive
- * configuration is specified, the default value is false
. If the maven descriptor
- * should be added to the artifact, use the following configuration:
- *
- * - * <plugin> - * <groupId>org.eclipse.tycho</groupId> - * <artifactId>tycho-packaging-plugin</artifactId> - * <version>${tycho-version}</version> - * <configuration> - * <archive> - * <addMavenDescriptor>true</addMavenDescriptor> - * </archive> - * </configuration> - * </plugin> - *- */ - @Parameter - private MavenArchiveConfiguration archive; - - /** - * The output directory of the jar file - * - * By default this is the Maven target/ directory. - */ - @Parameter(property = "project.build.directory") - private File outputDirectory; - - @Parameter(property = "project.basedir") - private File basedir; - - /** - * The path to the
feature.xml
file.
- *
- * Defaults to the feature.xml
under the project's base directory.
- */
- @Parameter(defaultValue = "${project.basedir}/" + FEATURE_XML)
- private File featureFile;
-
- /**
- * Name of the generated JAR.
- */
- @Parameter(property = "project.build.finalName", alias = "jarName", required = true)
- private String finalName;
-
- @Parameter(defaultValue = "${project.build.directory}/site")
- private File target;
-
- @Component
- private FeatureXmlTransformer featureXmlTransformer;
-
- @Component
- private LicenseFeatureHelper licenseFeatureHelper;
+ private static final Object LOCK = new Object();
+
+ private static final String FEATURE_PROPERTIES = "feature.properties";
+
+ /**
+ * The maven
+ * archiver to use. One of the archiver properties is the
+ * addMavenDescriptor
flag, which indicates whether the generated
+ * archive will contain the pom.xml and pom.properties file. If no archive
+ * configuration is specified, the default value is false
. If the
+ * maven descriptor should be added to the artifact, use the following
+ * configuration:
+ *
+ *
+ * <plugin> + * <groupId>org.eclipse.tycho</groupId> + * <artifactId>tycho-packaging-plugin</artifactId> + * <version>${tycho-version}</version> + * <configuration> + * <archive> + * <addMavenDescriptor>true</addMavenDescriptor> + * </archive> + * </configuration> + * </plugin> + *+ */ + @Parameter + private MavenArchiveConfiguration archive; + + /** + * The output directory of the jar file + * + * By default this is the Maven target/ directory. + */ + @Parameter(property = "project.build.directory") + private File outputDirectory; + + @Parameter(property = "project.basedir") + private File basedir; + + /** + * The path to the
feature.xml
file.
+ *
+ * Defaults to the feature.xml
under the project's base directory.
+ */
+ @Parameter(defaultValue = "${project.basedir}/" + FEATURE_XML)
+ private File featureFile;
+
+ /**
+ * Name of the generated JAR.
+ */
+ @Parameter(property = "project.build.finalName", alias = "jarName", required = true)
+ private String finalName;
+
+ @Parameter(defaultValue = "${project.build.directory}/site")
+ private File target;
+
+ /**
+ * Include the build timestamp in the manifest to track changes in the
+ * build-qualifier-aggregator
mojo
+ */
+ @Parameter(defaultValue = "true")
+ private boolean includeBuildTimestamp;
+
+ @Component
+ private FeatureXmlTransformer featureXmlTransformer;
+
+ @Component
+ private LicenseFeatureHelper licenseFeatureHelper;
@Component
private TargetPlatformService platformService;
@@ -117,174 +126,175 @@ public class PackageFeatureMojo extends AbstractTychoPackagingMojo {
@Component
private BuildPropertiesParser buildPropertiesParser;
- @Override
- public void execute() throws MojoExecutionException, MojoFailureException {
- synchronized (LOCK) {
- outputDirectory.mkdirs();
+ @Override
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ synchronized (LOCK) {
+ outputDirectory.mkdirs();
- if (!featureFile.isFile()) {
- throw new MojoExecutionException("The featureFile parameter must represent a valid file");
- }
+ if (!featureFile.isFile()) {
+ throw new MojoExecutionException("The featureFile parameter must represent a valid file");
+ }
- Feature feature;
+ Feature feature;
- try {
- feature = Feature.read(featureFile);
- } catch (final IOException e) {
- throw new MojoExecutionException("Error reading " + featureFile, e);
- }
+ try {
+ feature = Feature.read(featureFile);
+ } catch (final IOException e) {
+ throw new MojoExecutionException("Error reading " + featureFile, e);
+ }
- File licenseFeature = licenseFeatureHelper.getLicenseFeature(feature, project);
+ File licenseFeature = licenseFeatureHelper.getLicenseFeature(feature, project);
- updateLicenseProperties(feature, licenseFeature);
+ updateLicenseProperties(feature, licenseFeature);
- File featureXml = new File(outputDirectory, FEATURE_XML);
- try {
- expandVersionQualifiers(feature);
- Feature.write(feature, featureXml);
- } catch (IOException e) {
- throw new MojoExecutionException("Error updating feature.xml", e);
- }
+ File featureXml = new File(outputDirectory, FEATURE_XML);
+ try {
+ expandVersionQualifiers(feature);
+ Feature.write(feature, featureXml);
+ } catch (IOException e) {
+ throw new MojoExecutionException("Error updating feature.xml", e);
+ }
BuildProperties buildProperties = buildPropertiesParser.parse(DefaultReactorProject.adapt(project));
- checkBinIncludesExist(buildProperties);
-
- File featureProperties = getFeatureProperties(licenseFeature, buildProperties);
-
- File outputJar = new File(outputDirectory, finalName + ".jar");
- outputJar.getParentFile().mkdirs();
-
- MavenArchiver archiver = new MavenArchiver();
- JarArchiver jarArchiver = getJarArchiver();
- archiver.setArchiver(jarArchiver);
- archiver.setOutputFile(outputJar);
- jarArchiver.setDestFile(outputJar);
-
- try {
- // Additional file sets win over bin.includes ones, so we add them first
- if (additionalFileSets != null) {
- for (final var fileSet : additionalFileSets) {
- final var directory = fileSet.getDirectory();
-
- // noinspection ConstantConditions
- if (directory != null && directory.isDirectory()) {
- archiver.getArchiver().addFileSet(fileSet);
- }
- }
- }
-
- archiver.getArchiver().addFileSet(getManuallyIncludedFiles(buildProperties));
- if (licenseFeature != null) {
- archiver.getArchiver()
- .addArchivedFileSet(licenseFeatureHelper.getLicenseFeatureFileSet(licenseFeature));
- }
- archiver.getArchiver().addFile(featureXml, FEATURE_XML);
- if (featureProperties != null) {
- archiver.getArchiver().addFile(featureProperties, FEATURE_PROPERTIES);
- }
- if (archive == null) {
- archive = new MavenArchiveConfiguration();
- archive.setAddMavenDescriptor(false);
- }
+ checkBinIncludesExist(buildProperties);
+
+ File featureProperties = getFeatureProperties(licenseFeature, buildProperties);
+
+ File outputJar = new File(outputDirectory, finalName + ".jar");
+ outputJar.getParentFile().mkdirs();
+
+ MavenArchiver archiver = createMavenArchiver(includeBuildTimestamp);
+ JarArchiver jarArchiver = getJarArchiver();
+ archiver.setArchiver(jarArchiver);
+ archiver.setOutputFile(outputJar);
+ jarArchiver.setDestFile(outputJar);
+
+ try {
+ // Additional file sets win over bin.includes ones, so we add them first
+ if (additionalFileSets != null) {
+ for (final var fileSet : additionalFileSets) {
+ final var directory = fileSet.getDirectory();
+
+ // noinspection ConstantConditions
+ if (directory != null && directory.isDirectory()) {
+ archiver.getArchiver().addFileSet(fileSet);
+ }
+ }
+ }
+
+ archiver.getArchiver().addFileSet(getManuallyIncludedFiles(buildProperties));
+ if (licenseFeature != null) {
+ archiver.getArchiver()
+ .addArchivedFileSet(licenseFeatureHelper.getLicenseFeatureFileSet(licenseFeature));
+ }
+ archiver.getArchiver().addFile(featureXml, FEATURE_XML);
+ if (featureProperties != null) {
+ archiver.getArchiver().addFile(featureProperties, FEATURE_PROPERTIES);
+ }
+ if (archive == null) {
+ archive = new MavenArchiveConfiguration();
+ archive.setAddMavenDescriptor(false);
+ }
MavenProject mavenProject = project;
archiver.createArchive(session, mavenProject, archive);
- } catch (Exception e) {
- throw new MojoExecutionException("Error creating feature package", e);
- }
-
- project.getArtifact().setFile(outputJar);
- }
- }
-
- private void updateLicenseProperties(Feature feature, File licenseFeatureFile) {
- // remove license feature id and version from feature.xml
- feature.setLicenseFeature(null);
- feature.setLicenseFeatureVersion(null);
- // copy the license text and URL from the license feature
- if (licenseFeatureFile != null) {
- Feature licenseFeature = Feature.loadFeature(licenseFeatureFile);
- if (licenseFeature.getLicenseURL() != null) {
- feature.setLicenseURL(licenseFeature.getLicenseURL());
- }
- if (licenseFeature.getLicense() != null) {
- feature.setLicense(licenseFeature.getLicense());
- }
- }
- }
-
- private File getFeatureProperties(File licenseFeature, BuildProperties buildProperties)
- throws MojoExecutionException {
- try {
- File localFeatureProperties = new File(basedir, FEATURE_PROPERTIES);
- File targetFeatureProperties = new File(outputDirectory, FEATURE_PROPERTIES);
- if (targetFeatureProperties.exists() && !targetFeatureProperties.delete()) {
- throw new MojoExecutionException("Could not delete file " + targetFeatureProperties.getAbsolutePath());
- }
- // copy the feature.properties from the current feature to the target directory
- if (buildProperties.getBinIncludes().contains(FEATURE_PROPERTIES) && localFeatureProperties.canRead()) {
- Files.copy(localFeatureProperties.toPath(), targetFeatureProperties.toPath());
- }
- // if there is a license feature, append to the existing feature.properties or create
- // a new one containing the license features's feature.properties content
- if (licenseFeature != null) {
- appendToOrAddFeatureProperties(targetFeatureProperties, licenseFeature);
- }
- if (targetFeatureProperties.exists()) {
- return targetFeatureProperties;
- }
- return null;
- } catch (IOException e) {
- throw new MojoExecutionException("Could not create feature.properties file for project " + project, e);
- }
- }
-
- private void appendToOrAddFeatureProperties(File targetFeatureProperties, File licenseFeature) throws IOException {
- try (ZipFile zip = new ZipFile(licenseFeature)) {
- ZipEntry entry = zip.getEntry(FEATURE_PROPERTIES);
- if (entry != null) {
- try (InputStream inputStream = zip.getInputStream(entry);
- FileWriter writer = new FileWriter(targetFeatureProperties.getAbsolutePath(), true)) {
- // if we append, first add a new line to be sure that we start
- // in a new line of the existing file
- if (targetFeatureProperties.exists()) {
- IOUtil.copy("\n", writer);
- }
- IOUtil.copy(inputStream, writer);
- }
- }
- }
- }
-
- /**
- * @return A {@link FileSet} including files as configured by the bin.includes and
- * bin.excludes properties without the files that are always included
- * automatically.
- */
- private FileSet getManuallyIncludedFiles(BuildProperties buildProperties) {
- Listbuild-qualifier-aggregator
mojo
+ */
+ @Parameter(defaultValue = "true")
+ private boolean includeBuildTimestamp;
+
@Component
private SourceReferenceComputer soureReferenceComputer;
@@ -224,7 +231,7 @@ private File makeJar(BuildOutputJar jar) throws MojoExecutionException {
private File createPluginJar() throws MojoExecutionException {
try {
- MavenArchiver archiver = new MavenArchiver();
+ MavenArchiver archiver = createMavenArchiver(includeBuildTimestamp);
archiver.setArchiver(jarArchiver);
File pluginFile = new File(buildDirectory, finalName + ".jar");