{"id":14988138,"url":"https://github.com/apache/sling-slingfeature-maven-plugin","last_synced_at":"2025-10-19T12:30:44.304Z","repository":{"id":43173477,"uuid":"131209598","full_name":"apache/sling-slingfeature-maven-plugin","owner":"apache","description":"Apache Sling OSGi Feature Maven Plugin","archived":false,"fork":false,"pushed_at":"2024-12-23T14:54:21.000Z","size":1388,"stargazers_count":3,"open_issues_count":1,"forks_count":11,"subscribers_count":31,"default_branch":"master","last_synced_at":"2025-01-30T09:01:41.568Z","etag":null,"topics":["java","maven","osgi","osgi-feature-model","sling"],"latest_commit_sha":null,"homepage":"https://sling.apache.org/","language":"Java","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/apache.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-04-26T20:54:27.000Z","updated_at":"2024-12-23T14:46:13.000Z","dependencies_parsed_at":"2024-01-25T23:05:34.332Z","dependency_job_id":"f8842ac5-b9e7-43b6-9020-3c975d1d7be8","html_url":"https://github.com/apache/sling-slingfeature-maven-plugin","commit_stats":{"total_commits":711,"total_committers":31,"mean_commits":22.93548387096774,"dds":0.5091420534458508,"last_synced_commit":"ba6349c22b88c956d73ca3a70556b5d6af606c9c"},"previous_names":[],"tags_count":65,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apache%2Fsling-slingfeature-maven-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apache%2Fsling-slingfeature-maven-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apache%2Fsling-slingfeature-maven-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apache%2Fsling-slingfeature-maven-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/apache","download_url":"https://codeload.github.com/apache/sling-slingfeature-maven-plugin/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":237125560,"owners_count":19259303,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","maven","osgi","osgi-feature-model","sling"],"created_at":"2024-09-24T14:16:09.013Z","updated_at":"2025-10-19T12:30:44.291Z","avatar_url":"https://github.com/apache.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Apache Sling](https://sling.apache.org/res/logos/sling.png)](https://sling.apache.org)\n\n\u0026#32;[![Build Status](https://ci-builds.apache.org/job/Sling/job/modules/job/sling-slingfeature-maven-plugin/job/master/badge/icon)](https://ci-builds.apache.org/job/Sling/job/modules/job/sling-slingfeature-maven-plugin/job/master/)\u0026#32;[![Test Status](https://img.shields.io/jenkins/tests.svg?jobUrl=https://ci-builds.apache.org/job/Sling/job/modules/job/sling-slingfeature-maven-plugin/job/master/)](https://ci-builds.apache.org/job/Sling/job/modules/job/sling-slingfeature-maven-plugin/job/master/test/?width=800\u0026height=600)\u0026#32;[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=apache_sling-slingfeature-maven-plugin\u0026metric=coverage)](https://sonarcloud.io/dashboard?id=apache_sling-slingfeature-maven-plugin)\u0026#32;[![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=apache_sling-slingfeature-maven-plugin\u0026metric=alert_status)](https://sonarcloud.io/dashboard?id=apache_sling-slingfeature-maven-plugin)\u0026#32;[![JavaDoc](https://www.javadoc.io/badge/org.apache.sling/slingfeature-maven-plugin.svg)](https://www.javadoc.io/doc/org.apache.sling/slingfeature-maven-plugin)\u0026#32;[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.apache.sling/slingfeature-maven-plugin/badge.svg)](https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.apache.sling%22%20a%3A%22slingfeature-maven-plugin%22) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)\n\n# Apache Sling OSGi Feature Maven Plugin\n\nThis module is part of the [Apache Sling](https://sling.apache.org) project.\n\nMaven Plugin for building OSGi features and applications.\n\n# Authoring Feature Files\n\nThe format of a feature file is described in the [Apache Sling Feature Model](https://github.com/apache/sling-org-apache-sling-feature/blob/master/readme.md).\nAs described there, a feature file must have an ID. If you use this Maven Plugin you have two options:\n\n* Including the full ID in the source of your feature file\n* Let the plugin generate the ID for you\n\n## Including the ID in the feature file\n\nIf you want to have full control over the ID, you can encode it directly in the feature file. However, it is advised to use placeholders for the group id, artifact id\nand version and let the maven plugin insert them for you.\n\nIn the following example the qualifier `base` is specified for the feature file:\n\n``` json\n   {\n      \"id\":\"${project.groupId}:${project.artifactId}:slingosgifeature:base:${project.version}\",\n      ...\n   }\n```\n\n## Auto generated ID\n\nIf you omit the ID in your feature file, the maven plugin will generate an ID for you based on the file name of the feature file. The file name becomes the qualifier of the ID.\nIf your feature is named `feature.json` then this becomes the main artifact of the project without a qualifier.\n\n## Replacement of placeholders\n\n### Default placeholders\n\nThis maven plugin replaces some placeholders when processing feature files, placeholders use the common `${name}` syntax. The following placeholders are replaced by default:\n\n* project.groupId - The group id of the current maven project\n* project.artifactId - The artifact id of the current maven project\n* project.version - The version of the current maven project\n* project.osgiVersion - The version converted to an proper OSGi version.\n\nThe replacement of these placeholders can be disabled by setting the configuration `enableProjectVariableReplacement` to `true`.\n\n### Additional placeholders\n\nThe plugin can be configured to replace placeholders in the feature file based on maven project properties. To enable this, the configuration `replacePropertyVariables` can be set with a comma separated list of property names like:\n\n``` xml\n    \u003creplacePropertyVariables\u003eoak.version,jackrabbit.version\u003c/replacePropertyVariables\u003e\n```\n\nThe value needs to be set as a property on the maven project to be replaced.\n\n### Legacy Replacement\n\nUp to version 1.3.4 of the maven plugin, all occurences of placeholders where tried to be replaced by the maven plugin. However, this had two problems:\n\n* if a variable name in the feature model clashes with an (randomly) set maven project property, the usage of the variable got replaced with the value of the property.\n* Placeholders got replaced not only based on project properties but also on other inputs like system properties etc. making the build not reproducible.\n\nFor versions higher than 1.3.4, the `enableLegacyVariableReplacement` configuration can be set to `true` to enable this old behaviour. But it is discouraged to do so and rather use `replacePropertyVariables` with a clearly defined set of placeholders.\n\n## External Files for Text Extensions\n\nFor versions higher than 1.4.0, the maven plugin supports to author extensions in external files. For example a repoinit section can be written in a text file next to the feature model file. If an extension of type text is specified in the feature model with the value `@file`, the maven plugin looks for a file in the same directory as the feature model. The file must have the same name as the feature file followed by a dash, the name of the extension and \".txt\". For example a feature file `src/main/features/myfeature.json` with a repoinit extension using \"@file\" reads the repoinit from `src/main/features/myfeature-repoinit.txt`.\n\nIn addition, it is possible to control the name of the file name by specifying the part after the dash. For example using `@file:xssapi.xml` as the value of the extension leads to the a file named `myfeature-xssapi.xml` to be read.\n\n## Global Metadata\n\nFor versions higher than 1.4.16, the maven plugin supports configuring global metadata for bundles and artifacts. For bundles as well for each extension with artifacts, a map of defaults can be configured. If the source of the feature does not have the configured property, it will be added. This allows to add for example the same metadata start order to bundles while single bundles might still override that value.\n\nThe below configuration sets the start-order to 5 and foo to bar for bundles, and start-order to 1 for content-packages.\n\n``` xml\n\u003cconfiguration\u003e\n    \u003cdefaultMetadata\u003e\n        \u003cbundles\u003e \u003c!-- Defaults for bundles --\u003e\n            \u003cstart-order\u003e5\u003c/start-order\u003e\n            \u003cfoo\u003ebar\u003c/foo\u003e\n        \u003c/bundles\u003e\n        \u003ccontent-packages\u003e \u003c!-- Defaults for an extension namend content-packages --\u003e\n            \u003cstart-order\u003e1\u003c/start-order\u003e\n        \u003c/content-packages\u003e\n    \u003c/defaultMetadata\u003e\n\u003c/configuration\u003e\n```\n\n# Global Configuration\n\n* features : The directory containing the feature files. The default is `src/main/features`.\n* featuresIncludes : The include pattern for feature files from the above directory. Default is `**/*.json`, therefore all files with the extension `.json` are read including sub directories.\n* featuresExcludes : The exclude pattern for feature files from the above directory. Empty by default.\n* includeArtifact : Include an feature specified as a Maven artifact.\n* includeClassifier : Include a feature generated as aggregate with a classifier in this project.\n* validateFeatures : Boolean switch defining whether the feature files should be validated against the schema. This is enabled by default.\n\nThis global configuration specifies the initial set of feature files used for the current project, the other goals can then refine this subset.\n\nThere might be other plugins involved which generate feature files are part of the build. This plugin by default looks into a directory named *generated-features* inside the build directory for such files. Including of generated files can be controlled with the following configurations:\n\n* generatedFeatures : Directory with the generated features. By default *generated-features* inside the build directory is used.\n* generatedFeaturesIncludes : The include pattern for feature files from the above directory. Default is `**/*.json`, therefore all files with the extension `.json` are read including sub directories.\n* generatedFeaturesExcludes : The exclude pattern for feature files from the above directory. Empty by default.\n\nFor interoperability with other plugins, the location where this plug-in stores generated feature files is indicated by the expression `${project.slingfeature.outputDirectory}`.\n\n# Supported goals\n\nMost of the plugin goals take a selection of features as input, for example to aggregate a set of features to a new feature or to analyse a specific set of features according to some rules.\n\nAll of these goals use the same way of selecting the features: Whenever a goal can select from the above global list of features, `filesInclude` and `filesExclude` can be used to select from the above list of project files. The patterns are relative to the specified features directory:\n\n``` xml\n   ...\n      \u003c!-- Include all feature files with a filename starting with base --\u003e\n      \u003cfilesInclude\u003e**/base-*.json\u003c/filesInclude\u003e\n      \u003c!-- Include a specific file --\u003e\n      \u003cfilesInclude\u003eadditional/special-feature.json\u003c/filesInclude\u003e\n      \u003c!-- Exclude this file --\u003e\n      \u003cfilesExclude\u003econnectors/base-http.json\u003c/filesExclude\u003e\n   ...\n```\n\nThe order of the above include statements defines the order in which the features are processed. If an include contains a pattern, all files matching that pattern are processed in string order based on their full path.\n\nIn addition, most of the goals can also be configured to select aggregated features (see below) based on their qualifier. The special token `*` can be used to select all aggregated features and the token `:` selects the aggregated feature without a classifier (main artifact).\n\n``` xml\n   ...\n      \u003cincludeClassifier\u003ecore-aggregate\u003c/includeClassifier\u003e\n      \u003cincludeClassifier\u003eweb-aggregate\u003c/includeClassifier\u003e\n   ...\n```\n\nAgain the order of the instructions defines the order of processing.\n\nMost of the goals also support including of `ref` files. A ref file is a text file where each line in the text file contains a Maven url like mvn:groupId/artifactId/version. Lines starting with a hash can contain comments. The provided patterns are relative to the project directory.\n\n``` xml\n   ...\n      \u003c!-- Include all ref files within a source directory --\u003e\n      \u003crefsInclude\u003esrc/main/references/*.ref\u003c/refsInclude\u003e\n      \u003c!-- Include ref files generated by another plugin --\u003e\n      \u003crefsInclude\u003etarget/generated-refs/*.ref\u003c/refsInclude\u003e\n   ...\n```\n\nFinally, most of the goals also support to add features from other projects:\n\n``` xml\n   ...\n      \u003cincludeArtifact\u003e\n          \u003cgroupId\u003eorg.apache.sling\u003c/groupId\u003e\n          \u003cartifactId\u003esomefeature\u003c/artifactId\u003e\n          \u003cversion\u003e1.0.0\u003c/version\u003e\n          \u003ctype\u003eslingosgifeature\u003c/type\u003e\n      \u003c/includeArtifact\u003e\n   ...\n```\n\nAll of the above ways to select features (project files, project aggregates and external features) can be mixed in the configuration. It's possible to first specify an artifact include, followed by a aggregate classifier, followed by file includes. And this is then the order of processing. Please note that file excludes can be placed anywhere and regardless of their position, they are always applied to every files include.\n\n## Feature Aggregation (aggregate-features)\n\nProduce an aggregated feature from a list of features. The list of features is either specified by include/exclude patterns based on the configured features directory of the project or Maven coordinates of features.\n\nSample configuration:\n\n``` xml\n  \u003cplugin\u003e\n    \u003cgroupId\u003eorg.apache.sling\u003c/groupId\u003e\n    \u003cartifactId\u003eslingfeature-maven-plugin\u003c/artifactId\u003e\n    \u003cextensions\u003etrue\u003c/extensions\u003e\n    \u003cexecutions\u003e\n      \u003cexecution\u003e\n        \u003cid\u003emerge-features\u003c/id\u003e\n        \u003cgoals\u003e\n          \u003cgoal\u003eaggregate-features\u003c/goal\u003e\n        \u003c/goals\u003e\n        \u003cconfiguration\u003e\n          \u003caggregates\u003e\n               \u003c!-- A list of feature aggregations, each aggregate creates a new feature: --\u003e\n              \u003caggregate\u003e\n                   \u003cclassifier/\u003e \u003c!-- optional classifier or main artifact (no classifier)--\u003e\n                   \u003ctitle/\u003e          \u003c!-- optional title--\u003e\n                   \u003cdescription/\u003e \u003c!-- optional description--\u003e\n                   \u003cvendor/\u003e \u003c!-- optional description--\u003e\n                   \u003cmarkAsFinal/\u003e \u003c!-- optional flag to mark the feature as final --\u003e\n                   \u003cmarkAsComplete/\u003e \u003c!-- optional flag to mark the feature as complete --\u003e\n                   \u003cfilesInclude/\u003e \u003c!-- optional include for local files, this can be specified more than once --\u003e\n                   \u003cfilesExclude/\u003e  \u003c!-- optional exclude for local files, this can be specified more than once --\u003e\n                   \u003cincludeArtifact/\u003e       \u003c!-- optional artifact for external features, this can be specified more than once --\u003e\n                   \u003cincludeClassifier/\u003e   \u003c!-- optional classifier for aggregates, this can be specified more than once --\u003e\n                   \u003cvariablesOverrides\u003e\n                       \u003c!-- Feature variables can be specified/overridden here --\u003e\n                       \u003chttps.port\u003e8443\u003c/https.port\u003e\n                       \u003csome.variable/\u003e \u003c!-- set some.variable to null --\u003e\n                   \u003c/variablesOverrides\u003e\n                   \u003cframeworkPropertiesOverrides\u003e\n                       \u003c!-- Framework property overrides go here --\u003e\n                       \u003corg.osgi.framework.bootdelegation\u003esun.*,com.sun.*\u003c/org.osgi.framework.bootdelegation\u003e\n                   \u003c/frameworkPropertiesOverrides\u003e\n                   \u003cartifactsOverrides\u003e\n                       \u003c!-- Artifact clash overrides go here --\u003e\n                       \u003cartifactsOverride\u003eorg.apache.sling:abundle:LATEST\u003c/artifactsOverride\u003e\n                       \u003cartifactsOverride\u003eorg.apache.sling:anotherbundle:1.4.5\u003c/artifactsOverride\u003e\n                   \u003c/artifactsOverrides\u003e\n              \u003c/aggregate\u003e\n          \u003c/aggregates\u003e\n        \u003c/configuration\u003e\n      \u003c/execution\u003e\n    \u003c/executions\u003e\n  \u003c/plugin\u003e\n```\n\nAll features found in the directory as well as the artifact sections of the plugin configuration are aggregated into a single feature. Includes are processed in the way they appear in the configuration. If an include contains a pattern which includes more than one feature, than the features are included based on their full alphabetical file path. The features are aggregated in the order they are included.\n\nIf an include or an exclude is not using a pattern but directly specifying a file, this file must exists. Otherwise the build fails.\n\nThe merged feature will have the same `groupId`, `artifactId` and `version` as the pom in which the aggregation is configured. It will have type `slingosgifeature` and as classifier the one specified in the configuration named `classifier`.\n\nVariables and framework properties can be overridden using the `\u003cvariables\u003e` and `\u003cfraweworkProperties\u003e` sections. The values configured are only used if at least one feature contains such a variable or framework property. If multiple definitions of the same variable or framework properties are found in the features that are to be aggregated and the values for these variable / framework properties are different, they *must* be overridden, otherwise the aggregation will generate an error.\n\nIf the aggregation sources contain the same artifact more than once in different versions, a conflict resolution override must be specified using the `\u003cartifactsOverride\u003e` tag. In most cases the desired result will only contain one version of the artifact, although it's also possible to state that all versions must be kept.\n\nThe following syntax is supported for `\u003cartifactsOverride\u003e`:\n\n``` xml\n    \u003cconfiguration\u003e\n        \u003caggregates\u003e\n            \u003caggregate\u003e\n                ...\n                \u003c!-- The overrides are processed in the specified order --\u003e\n                \u003cartifactsOverrides\u003e\n                    \u003c!-- To provide a conflict resolution for a specific artifact: --\u003e\n                    \u003cartifactsOverride\u003egroupid1:artifactid1:RESOLUTION\u003c/artifactsOverride\u003e\n\n                    \u003c!-- To apply the same override rule for all clashes, a wildcard using '*' for\n                         groupID and artifactID can be used; this can be used as a catch all --\u003e\n                    \u003cartifactsOverride\u003e*:*:RESOLUTION\u003c/artifactsOverride\u003e\n                \u003c/artifactsOverrides\u003e\n                ...\n```\n\nThe RESOLUTION is one of the following:\n\n* `ALL` - select all the artifacts, i.e. keep them side-by-side.\n* `HIGHEST` - select only the artifact with the highest version number.\n* `LATEST` - select only the artifact provided latest, so the version used in the last feature file merged in.\n* `FIRST` - select only the artifact provided first, the version used in the first feature\n* `\u003cversion\u003e` - selects this specific version.\n\nWhen comparing version numbers these are converted to OSGi version numbers and the OSGi version number ordering is applied.\n\n### Extension merging\n\nMerging of extensions is specific to the extension being merged. Handlers can be provided to implement the logic of extension merging. A handler needs to implement the `org.apache.sling.feature.builder.FeatureExtensionHandler` and is looked up via the Java ServiceLoader mechanism.\n\nTo provide additional handlers to the `slingfeature-maven-plugin`, list the artifacts in the `\u003cdependencies\u003e`\nsection of the plugin configuration:\n\n``` xml\n  \u003cplugin\u003e\n    \u003cgroupId\u003eorg.apache.sling\u003c/groupId\u003e\n    \u003cartifactId\u003eslingfeature-maven-plugin\u003c/artifactId\u003e\n    \u003cexecutions\u003e\n      ...\n    \u003c/executions\u003e\n    \u003cdependencies\u003e\n      \u003cdependency\u003e\n        \u003cgroupId\u003eorg.apache.sling\u003c/groupId\u003e\n        \u003cartifactId\u003emy-feature-extension-handler\u003c/artifactId\u003e\n        \u003cversion\u003e1.0.0\u003c/version\u003e\n      \u003c/dependency\u003e\n    \u003c/dependencies\u003e\n  \u003c/plugin\u003e\n```\n\n## Analyse Features (analyse-features)\n\nRun feature model analysers on the feature models in the project. Analysers are defined in the [Apache Sling Feature Analyser](https://github.com/apache/sling-org-apache-sling-feature-analyser) project and are selected by their ID, which is obtained from the `getId()` method in\n[Analyser Task](https://github.com/apache/sling-org-apache-sling-feature-analyser/blob/master/src/main/java/org/apache/sling/feature/analyser/task/AnalyserTask.java).\n\n``` xml\n\u003cexecution\u003e\n  \u003cid\u003eanalyze\u003c/id\u003e\n  \u003cgoals\u003e\n    \u003cgoal\u003eanalyse-features\u003c/goal\u003e\n  \u003c/goals\u003e\n  \u003cconfiguration\u003e\n    \u003cscans\u003e\n    \u003c!-- A list of scans, each creates a new analysis: --\u003e\n      \u003cscan\u003e\n        \u003c!-- specify which feature files to include --\u003e\n        \u003c!-- optional include for local files, this can be specified more than once --\u003e\n        \u003cfilesInclude\u003e**/*.json\u003c/filesInclude\u003e\n\n        \u003c!-- optional exclude for local files, this can be specified more than once --\u003e\n        \u003cfilesExclude\u003edontcheck.json\u003c/filesExclude\u003e\n\n       \u003c!-- optional classifier for aggregates, this can be specified more than once --\u003e\n       \u003cincludeClassifier\u003eaggregated\u003c/includeClassifier\n\n       \u003c!-- optional artifact for external features, this can be specified more than once --\u003e\n       \u003cincludeArtifact\u003e\n           \u003cgroupId\u003eorg.apache.sling\u003c/groupId\u003e\n          \u003cartifactId\u003esomefeature\u003c/artifactId\u003e\n          \u003cversion\u003e1.0.0\u003c/version\u003e\n          \u003ctype\u003eslingosgifeature\u003c/type\u003e\n      \u003c/includeArtifact\u003e\n\n        \u003c!-- if only a subset of tasks need to be run, specify them here --\u003e\n        \u003cincludeTask\u003eapi-regions-dependencies\u003c/includeTask\u003e\n\n        \u003c!-- can also exclude tasks --\u003e\n        \u003cexcludeTask\u003edo-not-run-this-task\u003c/excludeTask\u003e\n\n        \u003c!-- taskConfiguration is a String, Properties map --\u003e\n        \u003ctaskConfiguration\u003e\n          \u003c!-- the configuration is specific to the analyser tasks --\u003e\n\n          \u003c!-- each key represents an AnalyserTask ID --\u003e\n          \u003capi-regions-dependencies\u003e\n            \u003c!-- can use keyname-textvalue syntax to specify configuration for a task --\u003e\n            \u003cexporting-apis\u003eglobal\u003c/exporting-apis\u003e\n            \u003chiding-apis\u003einternal\u003c/hiding-apis\u003e\n          \u003c/api-regions-dependencies\u003e\n        \u003c/taskConfiguration\u003e\n      \u003c/scan\u003e\n    \u003c/scans\u003e\n  \u003c/configuration\u003e\n\u003c/execution\u003e\n```\n\n## Attaching Features to the Project (attach-features)\n\nAttach feature files found in the project to the projects produced artifacts. This includes features\nfound in `src/main/features` as well as features produce with the `aggregate-features` goal if no configuration is specified.\n\n## Create Feature Archives (attach-featurearchives)\n\nA [feature archive](https://github.com/apache/sling-org-apache-sling-feature/blob/master/docs/feature-archives.md) contains one or more features together with all artifacts referenced by the feature like bundles or other binary artifacts. With this goal such an archive can be created for features and attached to the project.\n\nBy default all features known to the project are used to create feature archive for each feature, this includes features which are part of the source of the project, features generated by other plugins and aggregates.\n\nIt is possible to refine which feature archives should be created by selecting features as well as creating multiple features. The below configuration creates two feature archives. The first one with the classifier *platformarchive* contains a single feature with the classifier *platform*. The second archive gets the classifier *uiarchive* and contains two features with the classifiers *uibase* and *ui*.\n\nBy default, a feature archive gets the type `far`. By specifying the optional `type` configuration this can be changed to another type.\n\n``` xml\n\u003cexecution\u003e\n    \u003cid\u003ecreate-feature-archives\u003c/id\u003e\n    \u003cgoals\u003e\n        \u003cgoal\u003eattach-featurearchives\u003c/goal\u003e\n    \u003c/goals\u003e\n    \u003cconfiguration\u003e\n        \u003carchives\u003e\n            \u003carchive\u003e\n                \u003cclassifier\u003eplatformarchive\u003c/classifier\u003e\n                \u003cincludeClassifier\u003eplatform\u003c/includeClassifier\u003e\n                // optional type\n                \u003ctype\u003ezip\u003c/type\u003e\n            \u003c/archive\u003e\n            \u003carchive\u003e\n                \u003cclassifier\u003euiarchive\u003c/classifier\u003e\n                \u003cincludeClassifier\u003euibase\u003c/includeClassifier\u003e\n                \u003cincludeClassifier\u003eui\u003c/includeClassifier\u003e\n            \u003c/archive\u003e\n        \u003c/archives\u003e\n    \u003c/configuration\u003e\n\u003c/execution\u003e\n```\n\n## Extract contents of an Extension (extract-extension)\n\nThis goal can be used to extract the contents of an extension into a local file, which may be useful for other tools that can work on the content of the extension.\n\nThe goal is configured as in the following example:\n\n``` xml\n\u003cexecution\u003e\n    \u003cid\u003eextract-apiregions\u003c/id\u003e\n    \u003cgoals\u003e\n        \u003cgoal\u003eextract-extension\u003c/goal\u003e\n    \u003c/goals\u003e\n    \u003cconfiguration\u003e\n        \u003cselection\u003e\n            \u003cfeaturesInclude\u003efeature-abc.json\u003c/featuresInclude\u003e\n            \u003cextension\u003eapi-regions\u003c/extension\u003e\n            \u003coutputDir\u003etarget/extracted\u003c/outputDir\u003e\n        \u003c/selection\u003e\n    \u003c/configuration\u003e\n\u003c/execution\u003e\n```\n\nThis example extracts the `api-region` extension from the feature files `feature-abc.json` and puts it in the `target/extracted` directory. Feature files are selected as described in the Global Configuration above.\n\nOutput files are written to the output directory follows where the file name is the classifier of the selected feature, followed by the extension name and a `.json` extension for JSON and `.txt` extension for others.\n\n* JSON extensions: the file contains the raw JSON text.\n* TEXT extensions: the file contains the text from the extension.\n* ARTIFACT extensions: the file contains the Maven IDs for each artifact. One ID per line.\n\n## Update artifact Versions (update-feature-versions)\n\nDependencies get out of date over time, with the `update-feature-versions` goal, all artifacts in a feature can be checked for available updates and updated to a newer version. By default all artifacts in all feature files in the project are checked and updated:\n\n``` bash\n    mvn slingfeature:update-feature-versions\n```\n\nTo first check which artifacts will be updated and to what version, it is possible to just do a dry runs which does not alter the feature files:\n\n``` bash\n    mvn slingfeature:update-feature-versions -DdryRun=true\n```\n\nThe selection of feature files can be further refined by specifying the `classifiers` parameter which selects feature files based on their classifier. The special token ':' can be used to select the main artifact (artifact without a classifier). The parameter takes a comma separated list:\n\n``` bash\n    mvn slingfeature:update-feature-versions -Dclassifiers=platform,:\n```\n\nBy default all artifacts in a feature file are checked for updates. By specifying `includes` and `excludes` based on Maven coordinates the selection of artifacts can be further refined. The most common use case is to specify the group id only. For example the following command just updates all artifacts with the Sling group id:\n\n``` bash\n    mvn slingfeature:update-feature-versions -Dincludes=org.apache.sling\n```\n\nBoth parameters, `includes` and `excludes`, take a comma separated list.\n\nIt is also possible to define the version scope, which means the policy how to update. By default *ANY* is used, meaning the latest found version (excluding snapshots) is used. You can also specify *MAJOR*, *MINOR*, *INCREMENTAL* and *SUBINCREMENTAL* by using the `versionScope` parameter.\n\nThis can also be combined with `includes` to specify different scopes for each include:\n\n``` bash\n    mvn slingfeature:update-feature-versions -Dincludes=org.apache.sling/MAJOR,org.apache.felix/INCREMENTAL\n```\n\nInstead of specifying a scope, `includes` can also be used to define a specific version:\n\n``` bash\n    mvn slingfeature:update-feature-versions -Dincludes=org.apache.jackrabbit.oak/4.0.2\n```\n\n## Create an artifact repository (repository)\n\nWith the repository goal, a directory with all artifacts from the selected features will be created.\n\n``` xml\n\u003cexecution\u003e\n  \u003cid\u003erepo\u003c/id\u003e\n  \u003cgoals\u003e\n    \u003cgoal\u003erepository\u003c/goal\u003e\n  \u003c/goals\u003e\n  \u003cconfiguration\u003e\n      \u003crepositories\u003e\n          \u003c!-- A list of repositories, each creates a new repository: --\u003e\n         \u003crepository\u003e\n              \u003crepositoryDir/\u003e \u003c!-- optional repository directory--\u003e\n              \u003cfilesInclude/\u003e \u003c!-- optional include for local files, this can be specified more than once --\u003e\n              \u003cfilesExclude/\u003e  \u003c!-- optional exclude for local files, this can be specified more than once --\u003e\n              \u003cincludeArtifact/\u003e       \u003c!-- optional artifact for external features, this can be specified more than once --\u003e\n              \u003cincludeClassifier/\u003e   \u003c!-- optional classifier for aggregates, this can be specified more than once --\u003e\n              \u003cembedArtifact/\u003e \u003c!-- optional artifact to be embedded in the repository. This can be specified more than once --\u003e\n         \u003c/repository\u003e\n     \u003c/repositories\u003e\n   \u003c/configuration\u003e\n \u003c/execution\u003e\n```\n\n## Extract Infos (info)\n\nThe `info` goal allows to extract information about one or more features and generate some reports. It can be used within a Maven project or standalone.\n\nThe `reports` configuration should be configured with a comma separated list of the reports to be generated. The `outputFormat` configuration can be configured with either *log* in which case all output goes to the log or *file* (the default) in which case files for each feature and report are generated or *singlefile* in which case a single file for all report across all features is generated.\n\n### Duplicates Report (duplicates)\n\nThis report is done across all specified features and reports duplicates (bundles, configurations, artifacts or framework properties)\n\n### Exported Packages (exported-packages)\n\nA text file with a list of exported packages is generated for each feature. If a feature does not export packages, no file is created.\n\n### Contents (contents)\n\nThis report is done across all features and list the contents (bundles and artifacts).\n\n### Imported Packages (imported-packages)\n\nA text file with a list of imported packages is generated for each feature. If a feature does not import packages, no file is created.\n\n### Usage in a Maven Project\n\nWhen used in a Maven project, the list of features for the input goal can be specified by defining the feature set for the goal. The features are configured as described in the global configuration section above. If no configuration is provided, all feature files from the project are used.\n\n``` xml\n\u003cexecution\u003e\n  \u003cid\u003einfo\u003c/id\u003e\n  \u003cgoals\u003e\n    \u003cgoal\u003einfo\u003c/goal\u003e\n  \u003c/goals\u003e\n  \u003cconfiguration\u003e\n    \u003cinfoFeatures\u003e\n        \u003c!-- specify which feature files to include --\u003e\n        \u003c!-- optional include for local files, this can be specified more than once --\u003e\n        \u003cfilesInclude\u003e**/*.json\u003c/filesInclude\u003e\n    \u003c/infoFeatures\u003e\n  \u003c/configuration\u003e\n\u003c/execution\u003e\n```\n\n### Standalone Usage\n\nThe `info` goal can also be used standalone without a Maven project. In this case the property `infoFeatureFiles` must be specified with a comma separated list of feature files:\n\n``` bash\n    mvn slingfeature:info -DinfoFeatureFiles=/path/to/my/feature.json\n```\n\nIf the `outputFormat` is set to *file*, by default the files are generated in the current directory. `outputDirectory` can be used to specify an alternative directory.\n\n### Example\n\nTo generate the `duplicates` report to the log use:\n\n``` bash\n    mvn slingfeature:info -Dreports=duplicates -DoutputFormat=log\n```\n\nIf the `outputFormat` is set to *file*, by default the files are generated a directory named *feature-reports* in the build directory. `outputDirectory` can be used to specify an alternative directory.\n\n## Feature Launcher (launch-features)\n\n**Attention**: This Mojo is BETA meaning under development and new released may change the way the Mojo is used.\n\nThis Mojo allows the user to launch a Feature(s) from a POM through a profile. This can look like this:\n\n``` xml\n\u003cprofile\u003e\n    \u003cid\u003elaunch\u003c/id\u003e\n    \u003cbuild\u003e\n        \u003cplugins\u003e\n            \u003cplugin\u003e\n                \u003cgroupId\u003eorg.apache.sling\u003c/groupId\u003e\n                \u003cartifactId\u003eslingfeature-maven-plugin\u003c/artifactId\u003e\n                \u003cextensions\u003etrue\u003c/extensions\u003e\n                \u003cdependencies\u003e\n                    \u003c!-- To Support the Deployment of Content Package the Extension Content\n                         must be added BEFORE the Feature Launcher --\u003e\n                    \u003cdependency\u003e\n                        \u003cgroupId\u003eorg.apache.sling\u003c/groupId\u003e\n                        \u003cartifactId\u003eorg.apache.sling.feature.extension.content\u003c/artifactId\u003e\n                        \u003cversion\u003eLATEST_VERSION\u003c/version\u003e\n                    \u003c/dependency\u003e\n                    \u003cdependency\u003e\n                        \u003cgroupId\u003eorg.apache.sling\u003c/groupId\u003e\n                        \u003cartifactId\u003eorg.apache.sling.feature.launcher\u003c/artifactId\u003e\n                        \u003cversion\u003eLATEST_VERSION\u003c/version\u003e\n                    \u003c/dependency\u003e\n                \u003c/dependencies\u003e\n                \u003cexecutions\u003e\n                    \u003cexecution\u003e\n                        \u003cid\u003elaunch-it\u003c/id\u003e\n                        \u003cphase\u003einstall\u003c/phase\u003e\n                        \u003cgoals\u003e\n                            \u003cgoal\u003elaunch-features\u003c/goal\u003e\n                        \u003c/goals\u003e\n                        \u003cconfiguration\u003e\n                            \u003cselection\u003e\n                                \u003cincludeClassifier\u003eexample-runtime\u003c/includeClassifier\u003e\n                            \u003c/selection\u003e\n                        \u003c/configuration\u003e\n                    \u003c/execution\u003e\n                \u003c/executions\u003e\n            \u003c/plugin\u003e\n        \u003c/plugins\u003e\n    \u003c/build\u003e\n\u003c/profile\u003e\n```\n\nDo avoid having to release this plugin every time a new Feature Launcher is released the two are decoupled and the Feature Launcher is loaded at runtime instead. For that the feature launcher must be added to the plugin as dependency. If missing this Mojo with fail as it cannot find the launcher.\n\n**Attention**: to deploy converted Content Packages the **Feature Content** Extension must added here as well and it must be place **AHEAD** of the feature launcher.\n\nBeside the Feature Files this Mojo for now supports all the parameters of the current Feature Launcher (1.0.7-SNAPSHOT). For more info see the FeautreLaucherMojoTest.testFullLaunch() test method.\n\n**Support for Feature Archives**: feature archives (FAR) are supported now and can be added to the project either:\n\n1. By its classifier if part of the project\n\n    ``` xml\n       \u003cfeatureArchiveClassifiers\u003e\n           \u003cfeatureArchiveClassifier\u003esling12archive\u003c/featureArchiveClassifier\u003e\n       \u003c/featureArchiveClassifiers\u003e\n    ```\n\n2. Or by its Artifact Id when installed in the local Maven Repo\n\n    ``` xml\n        \u003cfeatureArchiveIds\u003e\n            \u003cfeatureArchiveId\u003eorg.apache.sling.sample.far:sling-sample-far:far:samplefararchive:1.0.0-SNAPSHOT\u003c/featureArchiveId\u003e\n        \u003c/featureArchiveIds\u003e\n    ```\n\n## Create Feature Model Descriptor from POM (include-artifact)\n\nWith the **include-artifact** goal it is possible to generate a POM based Feature Model so that it later can be used to be incorporated into other Feature Models without having to reference or copy the Feature Model files.\n\nThis snippet is creating a POM based Feature Model (create-test) and then\nincorporates another Feature Model (feature-test-repoinit.json) which contains\nthe Repository Init instruction for that Feature Model.\nEventually the result is installed (attach-features) into the local Maven\nrepository.\n\n``` xml\n\u003c!-- Generates and Installs the Sling OSGi Feature Model file --\u003e\n\u003cplugin\u003e\n    \u003cgroupId\u003eorg.apache.sling\u003c/groupId\u003e\n    \u003cartifactId\u003eslingfeature-maven-plugin\u003c/artifactId\u003e\n    \u003cextensions\u003etrue\u003c/extensions\u003e\n    \u003cexecutions\u003e\n      \u003cexecution\u003e\n        \u003cid\u003ecreate-fm\u003c/id\u003e\n        \u003cphase\u003epackage\u003c/phase\u003e\n        \u003cgoals\u003e\n          \u003cgoal\u003einclude-artifact\u003c/goal\u003e\n        \u003c/goals\u003e\n        \u003cconfiguration\u003e\n          \u003cincludeArtifactClassifier\u003ecreate-test\u003c/includeArtifactClassifier\u003e\n        \u003c/configuration\u003e\n      \u003c/execution\u003e\n      \u003cexecution\u003e\n        \u003cid\u003eaggregate\u003c/id\u003e\n        \u003cphase\u003epackage\u003c/phase\u003e\n        \u003cgoals\u003e\n          \u003cgoal\u003eaggregate-features\u003c/goal\u003e\n        \u003c/goals\u003e\n        \u003cconfiguration\u003e\n          \u003caggregates\u003e\n            \u003caggregate\u003e\n              \u003c!-- This must reference the classifier fro the 'create-fm' execution above --\u003e\n              \u003cincludeClassifier\u003ecreate-test\u003c/includeClassifier\u003e\n              \u003cfilesInclude\u003efeature-test-repoinit.json\u003c/filesInclude\u003e\n            \u003c/aggregate\u003e\n          \u003c/aggregates\u003e\n        \u003c/configuration\u003e\n      \u003c/execution\u003e\n      \u003cexecution\u003e\n        \u003cid\u003eattach\u003c/id\u003e\n        \u003cphase\u003epackage\u003c/phase\u003e\n        \u003cgoals\u003e\n          \u003cgoal\u003eattach-features\u003c/goal\u003e\n        \u003c/goals\u003e\n      \u003c/execution\u003e\n    \u003c/executions\u003e\n```\n\nThe **aggregate** execution above is only necessary if additional Feature Model\nSnippets are added to the final Feature Model file.\nSee the **src/it/include-artifact** folders for more details.\n\nThe Feature Model Descriptor file name in the local Maven repository can be found here:\n\n``` xml\n\u003cgroup id as path\u003e/\u003cartifact-id\u003e/\u003cversion\u003e/\u003cartifact id\u003e-\u003cversion\u003e.slingosgifeature\n```\n\n## Features Diff (features-diff)\n\nThis MOJO compares different versions of the same Feature Model, producing the prototype\nFeature Model that shows the differences.\n\n``` xml\n\u003cexecution\u003e\n  \u003cid\u003ediff\u003c/id\u003e\n  \u003cgoals\u003e\n    \u003cgoal\u003efeatures-diff\u003c/goal\u003e\n  \u003c/goals\u003e\n  \u003cconfiguration\u003e\n    \u003cselection\u003e\n      \u003cincludeClassifier\u003ecloud-ready\u003c/includeClassifier\u003e\n      \u003cincludeClassifier\u003emain-jar\u003c/includeClassifier\u003e\n    \u003c/selection\u003e\n    \u003ccomparisonVersion\u003e1.0.0-beta\u003c/comparisonVersion\u003e \u003c!-- (,${project.version}) by default --\u003e\n  \u003c/configuration\u003e\n \u003c/execution\u003e\n```\n\nIt will produce `${project.classifier}.json` JSON output files under the `${project.build.directory}/features-diff` directory,\nwhere IDs will be composed by:\n\n``` text\n${project.groupId}:${project.artifactId}:${project.classifier}_updater:${project.version}\n```\n\nDiff JSON file will be attached to the project.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapache%2Fsling-slingfeature-maven-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapache%2Fsling-slingfeature-maven-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapache%2Fsling-slingfeature-maven-plugin/lists"}