Jump to: navigation, search

Difference between revisions of "Equinox/p2/Customizing Metadata"

< Equinox‎ | p2
m
(Nested categories)
 
(5 intermediate revisions by 4 users not shown)
Line 11: Line 11:
  
 
For the 3.5 release the p2.inf file can be used to augment Installable Units: capabilities, properties, and instructions. In addition support is provided for defining additional installable units that are in some way related to the container IU.
 
For the 3.5 release the p2.inf file can be used to augment Installable Units: capabilities, properties, and instructions. In addition support is provided for defining additional installable units that are in some way related to the container IU.
 +
 +
 +
Properties in this file often contain <tt>&lt;#&gt;</tt> index segments.  These index segments serve to separate groups of similar properties from each other.  The actual value of these indexes are not important, only that a given set of properties which all refer to the same logical item all use the same index.  The following example is talking about two seperate properties, each uses a different index to distinguish it from the other.
 +
<pre>
 +
properties.0.name = testName1
 +
properties.0.value = testValue1
 +
properties.1.name = testName2
 +
properties.1.value = testValue2
 +
</pre>
  
 
== Capability Advice: ==
 
== Capability Advice: ==
Line 26: Line 35:
 
   requires.<#>.name = <name>
 
   requires.<#>.name = <name>
 
   requires.<#>.range = <range> ''(optional / default: 0.0.0)]
 
   requires.<#>.range = <range> ''(optional / default: 0.0.0)]
 +
  requires.<#>.matchExp = <p2QL expression> (note that in this case the namespace, name and range attributes are not
 
   requires.<#>.greedy = <true|false> ''(optional / default: true)''
 
   requires.<#>.greedy = <true|false> ''(optional / default: true)''
 
   requires.<#>.optional = <true|false> ''(optional / default: false)''
 
   requires.<#>.optional = <true|false> ''(optional / default: false)''
 
   requires.<#>.multiple = <true|false>  ''(optional / default: false)''
 
   requires.<#>.multiple = <true|false>  ''(optional / default: false)''
 
   requires.<#>.filter = <ldap filter> ''(optional)''
 
   requires.<#>.filter = <ldap filter> ''(optional)''
 +
 +
Negative requirements can be published by setting min and max values on the requirement to 0. For example
 +
  requires.<#>.namespace = org.eclipse.equinox.p2.iu
 +
  requires.<#>.name = some.feature.feature.group
 +
  requires.<#>.min = 0
 +
  requires.<#>.max = 0
  
 
   metaRequirements.<#>.namespace = <namespace>
 
   metaRequirements.<#>.namespace = <namespace>
 
   metaRequirements.<#>.name = <name>
 
   metaRequirements.<#>.name = <name>
 
   metaRequirements.<#>.range = <range> ''(optional / default: 0.0.0)''
 
   metaRequirements.<#>.range = <range> ''(optional / default: 0.0.0)''
 +
  metaRequirements.<#>.matchExp = {p2QL expression} (note that in this case the namespace, name and range attributes are not used)
 
   metaRequirements.<#>.greedy = <true|false> ''(optional / default: true)''
 
   metaRequirements.<#>.greedy = <true|false> ''(optional / default: true)''
 
   metaRequirements.<#>.optional = <true|false> ''(optional / default: false)''
 
   metaRequirements.<#>.optional = <true|false> ''(optional / default: false)''
Line 69: Line 86:
 
   metaRequirements.1.range = $version$
 
   metaRequirements.1.range = $version$
 
   metaRequirements.1.greedy = false
 
   metaRequirements.1.greedy = false
 +
 +
== Update descriptor advice: ==
 +
The update descriptor advice allows to override the default update descriptor generated by p2. Typically this is useful if an IU has been renamed and automatic update detection is still desired.
 +
 +
  update.id = <id of IU>
 +
  update.range = <range of the IU being updated>
 +
  update.matchExp = {a match expression identifying the IU being updated}. (When this is specified the values of id and range are ignored)
 +
  update.severity = <0|1>
 +
  
 
== Property Advice: ==
 
== Property Advice: ==
Line 95: Line 121:
 
   instructions.install = \
 
   instructions.install = \
 
     ln(targetDir:@artifact,linkTarget:foo/lib.1.so,linkName:lib.so);\
 
     ln(targetDir:@artifact,linkTarget:foo/lib.1.so,linkName:lib.so);\
     chmod(targetDir:@artifact,targetFile:lib/lib.so,permissions:755);
+
     chmod(targetDir:${artifact.location},targetFile:lib/lib.so,permissions:755);
 
   instructions.install.import= \
 
   instructions.install.import= \
 
     org.eclipse.equinox.p2.touchpoint.natives.ln,\
 
     org.eclipse.equinox.p2.touchpoint.natives.ln,\
 
     org.eclipse.equinox.p2.touchpoint.natives.chmod
 
     org.eclipse.equinox.p2.touchpoint.natives.chmod
 
  
 
== Additional Installable Unit Advice: ==
 
== Additional Installable Unit Advice: ==
Line 138: Line 163:
 
   units.1.touchpoint.id = testTouchpointId
 
   units.1.touchpoint.id = testTouchpointId
 
   units.1.touchpoint.version = 1.2.5
 
   units.1.touchpoint.version = 1.2.5
 +
  units.1.update.match = p2QL expression describing the update. When this is specified update.id and update.range are ignored.
 
   units.1.update.id = testid1
 
   units.1.update.id = testid1
 
   units.1.update.range = (1,2)
 
   units.1.update.range = (1,2)
Line 191: Line 217:
 
   units.1.hostRequirements.0.optional = true
 
   units.1.hostRequirements.0.optional = true
 
   units.1.hostRequirements.0.multiple = true
 
   units.1.hostRequirements.0.multiple = true
 
  
 
= Category Generation Using p2.inf =
 
= Category Generation Using p2.inf =
Line 220: Line 245:
  
 
== Nested categories ==
 
== Nested categories ==
The following file contains a number of projects showing how to create nested categories [[Image:NestedCategories.zip]].
+
'''Work in Progress'''
 +
* p2 parser and publisher for category.xml to support nested categories: https://bugs.eclipse.org/bugs/show_bug.cgi?id=406902
 +
* PDE category editor to support nested categories: https://bugs.eclipse.org/bugs/show_bug.cgi?id=296392
 +
'''Current workaround''' The following file containss a number of projects showing how to create nested categories [[Image:NestedCategories.zip]].
  
 
[[Category:Equinox_p2|Customizing Metadata]]
 
[[Category:Equinox_p2|Customizing Metadata]]

Latest revision as of 04:01, 8 May 2013

Customizing Installable Unit Metadata

Advice file format

An Installable Unit can be augmented at generation time by writing a p2 advice file (p2.inf). The format of this file is java properties file containing key=value pairs. In Eclipse 3.5, touchpoint advice files can be placed:

  • In bundles (META-INF/p2.inf): The instructions are added to the installable unit for the bundle
  • In features (a p2.inf file co-located with the feature.xml): The instructions are added to the installable unit for the feature group
  • In products (a p2.inf file co-located with the .product file): The instructions are added to the root installable unit for that product.

Two special value parameters are supported:

  • $version$ - returns the string form of the containing IU's version
  • $qualifier$ - returns just the string form of the qualifier of the containing IU's version

For the 3.5 release the p2.inf file can be used to augment Installable Units: capabilities, properties, and instructions. In addition support is provided for defining additional installable units that are in some way related to the container IU.


Properties in this file often contain <#> index segments. These index segments serve to separate groups of similar properties from each other. The actual value of these indexes are not important, only that a given set of properties which all refer to the same logical item all use the same index. The following example is talking about two seperate properties, each uses a different index to distinguish it from the other.

 properties.0.name = testName1
 properties.0.value = testValue1
 properties.1.name = testName2
 properties.1.value = testValue2

Capability Advice:

There are three different type of capability advice:

  • "provides" - these are capabilities that an IU will offer to satisfy the needs of other IUs
  • "requires" - these are the capabilities that an IU requires from other IUs in order to resolve correctly
  • "metaRequirements" - these are capabilities that the IU puts on the profile that must already be installed before this IU can be installed.

Capability advice will "replace" an existing capability of the same type on the IU if the name/namespace match.

 provides.<#>.namespace = <namespace>
 provides.<#>.name = <name>
 provides.<#>.version = <version> (optional / default: 1.0.0)
 requires.<#>.namespace = <namespace>
 requires.<#>.name = <name>
 requires.<#>.range = <range> (optional / default: 0.0.0)]
 requires.<#>.matchExp = <p2QL expression> (note that in this case the namespace, name and range attributes are not 
 requires.<#>.greedy = <true|false> (optional / default: true)
 requires.<#>.optional = <true|false> (optional / default: false)
 requires.<#>.multiple = <true|false>  (optional / default: false)
 requires.<#>.filter = <ldap filter> (optional)

Negative requirements can be published by setting min and max values on the requirement to 0. For example

 requires.<#>.namespace = org.eclipse.equinox.p2.iu
 requires.<#>.name = some.feature.feature.group
 requires.<#>.min = 0
 requires.<#>.max = 0
 metaRequirements.<#>.namespace = <namespace>
 metaRequirements.<#>.name = <name>
 metaRequirements.<#>.range = <range> (optional / default: 0.0.0)
 metaRequirements.<#>.matchExp = {p2QL expression} (note that in this case the namespace, name and range attributes are not used)
 metaRequirements.<#>.greedy = <true|false> (optional / default: true)
 metaRequirements.<#>.optional = <true|false> (optional / default: false)
 metaRequirements.<#>.multiple = <true|false>  (optional / default: false)

Where <#> is an index for the property, <namespace>, and <name> are the associated named strings, <version> and <range> are version and version range strings respectively.

For example:

 provides.0.namespace = testNamespace1
 provides.0.name = testName1
 provides.0.version = 1.2.3.$qualifier$
 provides.1.namespace = testNamespace2
 provides.1.name = testName2
 provides.1.version = $version$
 requires.0.namespace = testNamespace1
 requires.0.name = testName1
 requires.0.range = [1.2.3.$qualifier$, 2)
 requires.0.greedy = true
 requires.0.optional = true
 requires.0.multiple = true
 requires.1.namespace = testNamespace2
 requires.1.name = testName2
 requires.1.range = [$version$, $version$]
 requires.1.greedy = false
 metaRequirements.0.namespace = testNamespace1
 metaRequirements.0.name = testName1
 metaRequirements.0.range = [1.2.3, 2)
 metaRequirements.0.greedy = true
 metaRequirements.0.optional = true
 metaRequirements.0.multiple = true
 metaRequirements.1.namespace = testNamespace2
 metaRequirements.1.name = testName2
 metaRequirements.1.range = $version$
 metaRequirements.1.greedy = false

Update descriptor advice:

The update descriptor advice allows to override the default update descriptor generated by p2. Typically this is useful if an IU has been renamed and automatic update detection is still desired.

 update.id = <id of IU>
 update.range = <range of the IU being updated>
 update.matchExp = {a match expression identifying the IU being updated}. (When this is specified the values of id and range are ignored) 
 update.severity = <0|1>


Property Advice:

 properties.<#>.name = <propertyName>
 properties.<#>.value = <propertyValue>

Where <#> is an index for the property, <propertyName>, and <propertyValue> hold the name and value strings for the property.

For example:

 properties.0.name = testName1
 properties.0.value = testValue1
 properties.1.name = testName2
 properties.1.value = testValue2

Touchpoint Instruction Advice:

 instructions.<phase> = <raw actions>
 instructions.<phase>.import = <qualified action name> [,<qualified action name>]* (optional)

Where <phase> is a p2 phases (collect, configure, install, uninstall, unconfigure, etc).

Note:

  • The <raw actions> will be "appended" to the end of any instructions already being generated.
  • The qualified action names for the IU's touchpoint type are implicitly imported. All other actions need to be imported.

For example:

 instructions.install = \
    ln(targetDir:@artifact,linkTarget:foo/lib.1.so,linkName:lib.so);\
    chmod(targetDir:${artifact.location},targetFile:lib/lib.so,permissions:755);
 instructions.install.import= \
    org.eclipse.equinox.p2.touchpoint.natives.ln,\
    org.eclipse.equinox.p2.touchpoint.natives.chmod

Additional Installable Unit Advice:

In addition to customizing attributes of the containing IU one can also author addtional installable units that work with the container IU. Typically this mechanism is used to author an IUFragment that customizes the containing IU or one of it's dependencies.

 iu.<#>.id= <identifier> 
 iu.<#>.version= <version> (optional)

Where <#> is an index for the Installable Unit, so multiple Installable Units can be declared. A fairly full range of IU customizations are supported including:

 id
 version
 singleton
 copyright
 licenses
 filter
 touchpoint
 update
 artifacts
 properties
 provides
 requires
 metaRequirements
 hostRequirements
 instructions

To illustrate all the various settings for these customizations here's a more complete example of: (unit.0) a minimal IU and (unit.1) a full featured IU:

 units.0.id = testid0
 units.0.version = 1.2.3
 units.1.id = testid1
 units.1.version = 1.2.4
 units.1.singleton = true
 units.1.copyright = testCopyright
 units.1.copyright.location = http://localhost/test
 units.1.filter = test=testFilter
 units.1.touchpoint.id = testTouchpointId
 units.1.touchpoint.version = 1.2.5
 units.1.update.match = p2QL expression describing the update. When this is specified update.id and update.range are ignored.
 units.1.update.id = testid1
 units.1.update.range = (1,2)
 units.1.update.severity = 2
 units.1.update.description = some description
 units.1.artifacts.0.id = testArtifact1
 units.1.artifacts.0.version = 1.2.6
 units.1.artifacts.0.classifier = testClassifier1
 units.1.artifacts.1.id = testArtifact2
 units.1.artifacts.1.version = 1.2.7
 units.1.artifacts.1.classifier = testClassifier2
 units.1.licenses.0 = testLicense
 units.1.licenses.0.location = http://localhost/license
 units.1.properties.0.name = testName1
 units.1.properties.0.value = testValue1
 units.1.properties.1.name = testName2
 units.1.properties.1.value = testValue2
 units.1.requires.0.namespace = testNamespace1
 units.1.requires.0.name = testName1
 units.1.requires.0.range = [1.2.3.$qualifier$, 2)
 units.1.requires.0.greedy = true
 units.1.requires.0.optional = true
 units.1.requires.0.multiple = true
 units.1.requires.1.namespace = testNamespace2
 units.1.requires.1.name = testName2
 units.1.requires.1.range = $version$
 units.1.requires.1.greedy = false
 units.1.requires.1.optional = false
 units.1.metaRequirements.0.namespace = testNamespace1
 units.1.metaRequirements.0.name = testName1
 units.1.metaRequirements.0.range = [1.2.3.$qualifier$, 2)
 units.1.metaRequirements.0.greedy = true
 units.1.metaRequirements.0.optional = true
 units.1.metaRequirements.0.multiple = true
 units.1.metaRequirements.1.namespace = testNamespace2
 units.1.metaRequirements.1.name = testName2
 units.1.metaRequirements.1.range = $version$
 units.1.metaRequirements.1.greedy = false
 units.1.metaRequirements.1.optional = false
 units.1.provides.0.namespace = testNamespace1
 units.1.provides.0.name = testName1
 units.1.provides.0.version = 1.2.3.$qualifier$
 units.1.provides.1.namespace = testNamespace2
 units.1.provides.1.name = testName2
 units.1.provides.1.version = $version$
 units.1.instructions.configure = addProgramArg(programArg:-startup); addProgramArg(programArg:@artifact);
 units.1.instructions.unconfigure = removeProgramArg(programArg:-startup); removeProgramArg(programArg:@artifact);)
 units.1.instructions.unconfigure.import = some.removeProgramArg
 units.1.hostRequirements.0.namespace = testNamespace1
 units.1.hostRequirements.0.name = testName1
 units.1.hostRequirements.0.range = [1.2.3.$qualifier$, 2)
 units.1.hostRequirements.0.greedy = true
 units.1.hostRequirements.0.optional = true
 units.1.hostRequirements.0.multiple = true

Category Generation Using p2.inf

The p2 UI allows for hierarchical organization of Installable Units based on the concept of "categories" where the children of categories are what's installable. On occasion we might want to take finer grained control of the contents of a category and what it contains. For example we might want to support further categorization of a features contents to allow individual plugins to be installed instead of the more typical features.

To support this we can tag a feature as a category as follows:

 properties.1.name=org.eclipse.equinox.p2.type.category
 properties.1.value=true

Another possibility is to use "additional IU advice" to create a specialized category IU like this:

 units.1.id=my.product.category
 units.1.version=1.0.0
 units.1.provides.1.namespace=org.eclipse.equinox.p2.iu
 units.1.provides.1.name=my.product.category
 units.1.provides.1.version=1.0.0
 units.1.properties.1.name=org.eclipse.equinox.p2.type.category
 units.1.properties.1.value=true
 units.1.properties.2.name=org.eclipse.equinox.p2.name
 units.1.properties.2.value=My Category Name
 requires.1.namespace=org.eclipse.equinox.p2.iu
 requires.1.name=my.product
 requires.1.range=[1.0.0,1.0.0]
 requires.1.greedy=true

Categorizing plug-ins

The following file contains two projects showing how to create a category to show plug-ins File:CategorizedPlugins.zip.

Nested categories

Work in Progress

Current workaround The following file containss a number of projects showing how to create nested categories File:NestedCategories.zip.