You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@maven.apache.org by Jason van Zyl <jv...@sonatype.com> on 2008/12/17 09:41:41 UTC

Re: svn commit: r727314 - /maven/components/trunk/maven-project-spec.cfl

Shane,

I'm trying out the MathML support and flipping the document to  
Confluence. Edit the Tex as you like and I'll merge in the  
differences. I'm editing the document as I refactor the project  
builder and build up the spec tests here but don't worry about the  
Confluence for now as I'm not sure this will work well for the notation.

On 17-Dec-08, at 3:39 AM, jvanzyl@apache.org wrote:

> Author: jvanzyl
> Date: Wed Dec 17 00:39:07 2008
> New Revision: 727314
>
> URL: http://svn.apache.org/viewvc?rev=727314&view=rev
> Log:
> o trying to flip over to confluence, mathml support seems to not be  
> so great
>
> Added:
>    maven/components/trunk/maven-project-spec.cfl
>
> Added: maven/components/trunk/maven-project-spec.cfl
> URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-project-spec.cfl?rev=727314&view=auto
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- maven/components/trunk/maven-project-spec.cfl (added)
> +++ maven/components/trunk/maven-project-spec.cfl Wed Dec 17  
> 00:39:07 2008
> @@ -0,0 +1,334 @@
> +This document is the specification for POM construction in Maven
> +
> +h1. Model Transformations
> +
> +h2. Canonical Data Format
> +
> +Maven supports a canonical data format for the pom that includes  
> 465 model properties (we refer to each ordered pair of uri/values as  
> a model property).
> +
> +{code}
> +	http://apache.org/maven/project/modelVersion
> +	http://apache.org/maven/project/groupId
> +	http://apache.org/maven/project/artifactId
> +{code}
> +
> +So a valid set would contain ordered pairs:
> +
> +\begin{math}
> +	\mathcal{A}= \{\langle "http://apache.org/maven/project/groupId",  
> "org.apache.maven"\rangle,
> +	\langle "http://apache.org/maven/project/artifactId", "mavencore"\} 
> \rangle \ldots\}.
> +\end{math}
> +
> +Technically \begin{math}\mathcal{A}\end{math} is also ordered.
> +
> +Any one is free to create a transformer from any another format  
> (yaml, .NET projects files, etc) to this canonical data format,  
> giving them all the benefits of project inheritance and  
> interpolation that Maven uses in building a project.
> +
> +h3. Collections
> +A model property may  be specified as a collection, which allows  
> specialized join rules for adding model properties. Collections of  
> collections are allowed.
> +{code}
> +	http://apache.org/maven/project/build/plugins#collection
> +	http://apache.org/maven/project/build/plugins#collection/plugin/ 
> executions#collection
> +	http://apache.org/maven/project/profiles#collection
> +{code}
> +
> +There are 31 collections within the canonical data format.
> +
> +h3. Sets
> +A model property may  be specified as a set, which means that model  
> properties are not duplicated. Generally sets are only used on  
> configuration properties of the plugins.
> +
> +{code}
> +http://...pluginManagement/plugins#collection/plugin/ 
> configuration#set
> +http://...plugins#collection/plugin/configuration#set
> +{code}
> +
> +h3. Singletons
> +Any model property not defined as a collection or set is  a  
> singleton, This means that only one entry containing the model  
> property's URI is allowed in the transformed list.
> +
> +h1. General Inheritance Rules
> +General inheritance rules are those rules applied to a list of  
> model properties, independent of the domain context. The framework  
> delegates domain specific inheritance rules to ModelTransformers  
> provided to it by the invoking application. These will be covered in  
> the next section, under \emph{Maven Project Inheritance Rules}.
> +
> +h2. Constructing
> +Basic construction rules are as follows
> +
> +1. Let there be a collection of domain models (poms) denoted by set  
> \begin{math}\mathcal{D}_{i}\end{math}, where for some \begin{math} n  
> \in \mathbb{N} \end{math} the collection is ordered from most  
> specific to least specific \begin{math}\mathcal{C} = \ 
> {\mathcal{D}_{0}, \mathcal{D}_{1},...,\mathcal{D}_{n} \}  
> \end{math}.  \begin{math}\mathcal{D}_{n}\end{math} is the SuperPom  
> and must be contained within \begin{math}\mathcal{C}\end{math}, even  
> if it is the only element.
> +2. Let \begin{math}p_j\end{math} be an ordered pair (or model  
> property). In the case of the pom, \begin{math}j=nodes + properties 
> \end{math} of the pom. Define t as a function operating on elements  
> of \begin{math}\mathcal{C}\end{math} that transforms each element to  
> a set of model properties.  \begin{math} 
> \mathcal{D}'_{i}=t(\mathcal{D}_{i})=\{p_0,p_1,...p_m\}\end{math}. We  
> end up with a transformed collection of domain models: \begin{math} 
> \mathcal{C'} = \{\mathcal{D'}_{0}, \mathcal{D'}_{1},..., 
> \mathcal{D'}_{n} \} \end{math}.
> +3. Next domain specific rules are applied (See section 3). Let tr  
> be a domain transform rule: \begin{math}
> +\forall_j \forall_i \mathcal{A}_{i,j}  \subseteq \mathcal{D'}_{i}  
> \end{math} such that \begin{math}  \mathcal{A'}_{i,j} = \{tr(p_0),  
> tr(p_1),...,tr(p_n))\}. \end{math} tr may change either the model  
> property URI or value or may transform the property to a null value  
> (remove it) or it could add additional model properties not from the  
> original set.  We are left with \begin{math}
> +\mathcal{C''} =  \forall_j \forall_i \bigcup_{i,j}(\mathcal{D'}_{i}  
> \cup \mathcal{A'}_{i,j} - (\mathcal{D'}_{i} \cap\mathcal{A}_{i,j}))  
> \end{math}. Thus \begin{math}\mathcal{C''} \end{math} is just a set  
> of transformed and untransformed model properties from all of the  
> domain models \begin{math}
> +\mathcal{D}_{i} \end{math}. These model properties are still  
> ordered from most specialized model to least.
> +4. Model properties are now sorted (see section 2.2). Collections  
> and sets are left in reverse order.
> +5. Model container rules are applied for collections and sets. The  
> general sorting in the previous step doesn't know how to handle  
> collections and sets and needs to delegate back to the domain  
> specific model containers (Sections 3.4 and 3.5)
> +6. Model properties are sorted (see section 2.2) again. This is to  
> maintain the original order of collections.
> +7. Interpolates the model properties (Section 5)
> +8. Applies dependency management rules
> +9. Applies plugin management rules
> +
> +
> +h2. Sorting
> +Let \begin{math}\mathcal{C''}\end{math} be the original set of  
> model properties and let \begin{math}\mathcal{C'''}\end{math} be the  
> new set, which is initially empty. Now iterate over each element  
> (model property) of \begin{math}\mathcal{C''}\end{math} placing the  
> model property into set  \begin{math}\mathcal{C'''}\end{math}   
> according to the following rules:
> +
> +1. Let \begin{math}u_{i}\end{math} be the uri from  model property  
> \begin{math}\langle uri, value\rangle_{i} \end{math} If   
> \begin{math}u_{i}\end{math} = baseUri, then it is placed first in  
> the list. In the case of Maven, http://apache.org/maven/project is  
> the baseUri and defines the top node name.
> +2. If \begin{math}u_{i}\end{math} is not within any of the model  
> properties contained within \begin{math}\mathcal{C'''}\end{math}  
> then place the model property into \begin{math}\mathcal{C'''} 
> \end{math}. This rule only allows one singleton into the set:  
> \emph{http://.../project/groupId} and since \begin{math}\mathcal{C''} 
> \end{math} is sorted in order of most specialized to least  
> specialized, only the most specialized pom values will be maintained.
> +3. If \begin{math}u_{i}\end{math} contains a value of \#collection  
> or \#set but does not end with  \#collection or \#set then  then  
> place the model property into \begin{math}\mathcal{C'''}\end{math},  
> at the position of its first (and only) parent. For example, 
> \emph{ http://.../project/build/plugins\#collection }would have been  
> added in the previous step (because it was not contained in  
> \begin{math}\mathcal{C'''}\end{math}) but this step would exclude  
> any additional model properties containing \emph{http://.../project/ 
> build/plugins\#collection}.  However, all model properties  
> containing uri \emph{http://apache.org/maven/project/build/plugins 
> \#collection/plugin} would be added just below its collection. Only  
> one node of a collection type is maintained but multiple children  
> within that collection are allowed.
> +
> +h2. Mixins and Multiple Inheritance
> +Currently, Maven 3.0 supports linearlized inheritance, making  
> mixins and multiple inheritance easy. Support for multiple  
> inheritance would require an addition to the pom, within the parents  
> section.
> +
> +{code}
> +<parents>
> +  <parent>
> +    <groupId>org.apache.maven.shared</groupId>
> +    <artifactId>maven-shared-components</artifactId>
> +    <version>9</version>
> +  </parent>
> +  <parent>
> +    <artifactId>maven</artifactId>
> +    <groupId>org.apache.maven</groupId>
> +    <version>3.0-SNAPSHOT</version>
> +  </parent>
> +  </parents>
> +{code}
> +
> +In the case above, the child pom's model properties would be first  
> in the set, followed by the model properties of \emph{maven-shared- 
> components}; then \emph{maven} project's model properties and  
> finally by the SuperPom's model properties. So from the framework's  
> perspective there is little difference between multiple inheritance  
> and single inheritance.
> +
> +Mixins would function the same as multiple/single inheritance:
> +
> +{code}
> +<mixins>
> +  <mixin>
> +    <groupId>org.apache.maven</groupId>
> +    <artifactId>dependency-mixin</artifactId>
> +    <version>1</version>
> +  </mixin>
> +  <mixin>
> +    <groupId>org.apache.maven</groupId>
> +    <artifactId>repository-mixin</artifactId>
> +    <version>2</version>
> +  </mixin>
> + </mixins>
> +{code}
> +
> +The only difference between a parent project and a mixin is that  
> the mixin is abstract (not a complete model).
> +
> +h1. Maven Project Inheritance Rules
> +These rules outlined in this section are provided in the  
> PomClassicTransformer class. The shared-model framework will  
> delegate to this transformer for the processing of the Maven  
> specific domain model rules.
> +
> +h2. Inheriting Version and Group Ids
> +If \emph{project.version} is not specified within the child pom,  
> the child pom will use the \emph{project.parent.version} as its own  
> version. Similarly, if \emph{project.groupId} is not within the  
> child pom, the child pom will use the \emph{project.parent.groupId}  
> as its own \emph{project.groupId}.
> +
> +h2. Properties Excluded From Inheritance
> +A child project does not inherit the following properties from its  
> specified parent project. All other properties are inherited, unless  
> otherwise noted below.
> +
> +1. project.parent
> +2. project.modules
> +3. project.name
> +4. project.packaging
> +5. project.profiles
> +6. project.version
> +7. project.groupId
> +8. project.build.resources
> +9. project.build.testResources
> +10. project.pluginRepositories
> +
> +
> +A parent project can set an inherited property within the  
> \emph{project.build.plugins.plugin} or  
> \emph{project.build.plugins.plugin.executions.execution} section of  
> the pom to mark the member as private, thus preventing inheritance.
> +
> +{code}
> +    <plugin>
> +        <groupId>org.apache.maven</groupId>
> +        <artifactId>sample</artifactId>
> +        <version>1.0</version>
> +        <inherited>false</inherited>
> +    </plugin>
> +{code}
> +
> +{code}
> +    <plugin>
> +        <groupId>org.apache.maven</groupId>
> +        <artifactId>sample</artifactId>
> +        <version>1.0</version>
> +        <executions>
> +            <execution>
> +                <inherited>false</inherited>
> +           </execution>
> +        </executions>
> +    </plugin>
> +{code}
> +
> +h2. Super Pom Rules
> +The super pom is implicitly  the parent of every project and  
> functions as a normal parent project except that it allows the child  
> project to inherit the following properties, which are normally  
> excluded. If the child project defines the property,  it overrides  
> all elements of the respective super pom property. There is no join  
> of these three superPom-child collections.
> +\begin{itemize}
> +* project.build.resources
> +* project.build.testResources
> +* project.pluginRepositories
> +\end{itemize}
> +
> +h2. Artifact Inheritance (Model Container)
> +h3. Defined Nodes}
> +Within the project there are a number of nodes which contain  
> artifactId, groupId and version. These nodes may be inherited or  
> even joined.
> +
> +1. project.dependencies.dependency
> +2. project.build.plugins.plugin
> +3. project.build.plugins.plugin.dependencies.dependency
> +4.  
> project 
> .build.plugins.plugin.dependencies.dependency.exclusions.exclusion
> +5. project.dependencyManagement.dependencies.dependency
> +6. project.build.pluginManagement.plugins.plugin
> +7.  
> project.build.pluginManagement.plugins.plugin.dependencies.dependency
> +
> +h3. Rules}
> +Let the parent project be \begin{math}\mathcal{A}\end{math} and the  
> child project be  \begin{math}\mathcal{B}\end{math} . Let both  
> \begin{math}\alpha_i \subset \mathcal{A}\end{math} and \begin{math} 
> \beta_i \subset \mathcal{B}\end{math} be one of the elements listed  
> above. For example,  \begin{math}\alpha_1\end{math} would contain  
> all the elements of a project dependency within the parent project.
> +
> +Both \begin{math}\alpha_i \subset \mathcal{A}\end{math} and  
> \begin{math}\beta_i \subset \mathcal{A}\end{math}, contain at least  
> the elements groupId and artifactId, with an implied version value  
> of null, if version is not specified within the pom. Also note that  
> only (1), (3), (5) and (7) have an element of type, otherwise the  
> type value is considered null. More precisely we have:
> +
> +\begin{math} \forall_i  \forall_j \alpha_i = \{\langle groupId,  
> value_j \rangle_i, \langle artifactId, value_{j+1}\rangle_i, \langle  
> version, value_{j+2}\rangle_i, \ldots\}.\end{math}
> +
> +The inheritance rules are:
> +
> +
> +1.
> +\begin{math}
> +groupId(value)^{\alpha_i} \neq groupId(value)^{\beta_i} \vee  
> artifactId(value)^{\alpha_i} \neq artifactId(value)^{\beta_i}   
> \Rightarrow \mathcal{B}_{new} = \mathcal{B} \cup \alpha_i
> +\end{math}
> +2.
> +\begin{math}
> +groupId(value)^{\alpha_i} = groupId(value)^{\beta_i}  \wedge  
> artifactId(value)^{\alpha_i} = artifactId(value)^{\beta_i}  \wedge  
> version(value)^{\alpha_i} \neq version(value)^{\beta_i}  \wedge   
> type(value)^{\alpha_i} = type(value)^{\beta_i} \Rightarrow  
> \mathcal{B}_{new} = \mathcal{B} - \alpha_i
> +\end{math}
> +3.
> +\begin{math}
> +groupId(value)^{\alpha_i} = groupId(value)^{\beta_i}  \wedge  
> artifactId(value)^{\alpha_i} = artifactId(value)^{\beta_i}  \wedge  
> version(value)^{\alpha_i} \neq version(value)^{\beta_i}  \wedge   
> type(value)^{\alpha_i} \neq type(value)^{\beta_i} \Rightarrow  
> \mathcal{B}_{new} = \mathcal{B} \cup \alpha_i
> +\end{math}
> +4.
> +\begin{math}
> +groupId(value)^{\alpha_i} = groupId(value)^{\beta_i}  \wedge  
> artifactId(value)^{\alpha_i} = artifactId(value)^{\beta_i}  \wedge  
> version(value)^{\alpha_i} = version(value)^{\beta_i}  \wedge  
> type(value)^{\alpha_i} = type(value)^{\beta_i} \Rightarrow  
> \mathcal{B}_{new} = \mathcal{B} \cup \alpha_i - (\alpha_i \cap  
> \beta_i)
> +\end{math}
> +4.
> +\begin{math}
> +groupId(value)^{\alpha_i} = groupId(value)^{\beta_i}  \wedge  
> artifactId(value)^{\alpha_i} = artifactId(value)^{\beta_i}  \wedge  
> version(value)^{\alpha_i} = version(value)^{\beta_i}  \wedge  
> type(value)^{\alpha_i} \neq type(value)^{\beta_i} \Rightarrow  
> \mathcal{B}_{new} = \mathcal{B} \cup \alpha_i
> +\end{math}
> +
> +
> +
> +Or more simply:
> +
> +
> +1. if either groupId or artifactId is different, then inherit the  
> node.
> +2. if groupId, artifactId and type match but the version doesn't,  
> then don't inherit the node.
> +3. if groupId and artifactId  match but the version and types  
> don't, then inherit the node.
> +4. if groupId, artifactId, version and type match, then inherit and  
> join the node.
> +5. if groupId, artifactId, version match but type doesn't, then  
> inherit the node
> +
> +
> +
> +h2. Id Inheritance (Model Container)
> +
> +h3. Defined Nodes
> +Within the project there are a number of nodes which contain id.  
> These nodes may be inherited or even joined.
> +
> +1. project.pluginRepositories.pluginRepository
> +2. project.repositories.repository
> +3. project.reporting.plugins.plugin.reportSets.reportSet
> +4. project.build.plugins.plugin.executions.execution
> +
> +
> +h3. Rules
> +If an id exists in both the parent and child pom and the ids are  
> equal, then join the nodes, otherwise inherit the node.
> +
> +h2. Plugin Configuration Inheritance
> +Plugin nodes are treated as a set. If a child pom contains the same  
> element as a parent pom, then the parent pom element will not be  
> inherited/joined unless the child element contains a property  
> combine.children="append". In this case, it will treat the element  
> as a collection.
> +
> +{code}
> +      <plugin>
> +        <groupId>org.apache.maven.plugins</groupId>
> +        <artifactId>maven-compiler-plugin</artifactId>
> +        <configuration>
> +          <testExcludes combine.children="append">
> +            <testExclude implementation="java.lang.String">
> +               **/PersonThreeTest.java
> +            </testExclude>
> +          </testExcludes>
> +        </configuration>
> +      </plugin>
> +{code}
> +
> +If the parent pom contains an element that the child pom does not  
> have, the element will be inherited.
> +
> +h1. Management Rules
> +h2. Dependency/Plugin Management
> +Dependency and plugin management are treated the same, so we will  
> only cover dependency management. Our initial set has already been  
> processed for inheritance and interpolated by the time these rules  
> are applied.
> +
> +Let \begin{math}\mathcal{A}\end{math} be the set of  
> \emph{project.dependencies.dependency} model containers (model  
> containers are themselves sets of model properties).
> +
> +Let \begin{math}\mathcal{B}\end{math} be the set of
> +\emph{project.dependencyManagement.dependencies.dependency }model  
> containers. \begin{math}\mathcal{B}\end{math} is processed such that  
> each dependencyManagement reference within its uris is removed. Thus  
> the uris exactly match those contained within \begin{math}\mathcal{A} 
> \end{math}. Call this transformed set \begin{math} \mathcal{B'} 
> \end{math}.
> +
> +Now we can apply the same artifact container rules between each   
> \begin{math} \mathcal{B'}_{i} \end{math} and  \begin{math}  
> \mathcal{A}_{j}\end{math}.  as those defined in section 3.4.
> +
> +h1. Interpolation Rules
> +h2. Type of Properties
> +There are four types of properties in the following order of  
> precedence: maven properties, system (user) properties, project  
> properties, environment (execution) variables.
> +
> +h3. Maven Properties
> +There are two maven specific properties that can be used: \$\ 
> {basedir\} (or \$\{pom.basedir\} or \$\{project.basedir\}) and \$\ 
> {build.timestamp\}. \emph{basedir} denotes the project directory of  
> the executing pom, while\emph{ build.timestamp} denotes the time  
> that the build started.
> +
> +{code}
> + <build>
> +    <directory>${project.basedir}/target</directory>
> +    <sourceDirectory>${project.basedir}/src/main/java</ 
> sourceDirectory>
> + </build>
> +{code}
> +
> +
> +h3. System Properties
> +These properties are defined on the command line through -D option.  
> For instance, \emph{-DjunitVersion=3.8}. These property values take  
> precedence over project and environment properties and will override  
> them.
> +
> +h3. Project Properties
> +These properties are derived directly from the pom itself: \$\ 
> {project.version\}, \$\{project.artifactId\}... So in the code  
> snippet below, \emph{project.build.finalname} will be resolved to 
> \emph{ maven-3.0-SNAPSHOT}.
> +
> +Note \emph{pom} is an alias for\emph{ project}, so you can also  
> reference the properties through \$\{pom.version\}, \$\ 
> {pom.artifactId\}... , although \emph{project} is preferred.
> +
> +These types of properties also include special rules for the  
> \emph{project.properties }section of the pom. The elements under the  
> properties section can directly be referenced, by name, from within  
> other elements of the pom. For example, the  
> \emph{project.properties }section defines \emph{junitVersion},  
> allowing the
> +\emph{ project.build.dependencies.dependency.version} to reference  
> the value by inserting \$\{junitVersion\}
> +
> +{code}
> +<project>
> +  <groupId>org.apache.maven</groupId>
> +  <artifactId>maven</artifactId>
> +  <version>3.0-SNAPSHOT</version>
> +  <build>
> +      <finalName>${project.artifactId}-${project.version}</finalName>
> +  </build>
> +  <dependencies>
> +    <dependency>
> +      <groupId>junit</groupId>
> +      <artifactId>junit</artifactId>
> +      <version>${junitVersion}</version>
> +      <scope>test</scope>
> +    </dependency>
> +  </dependencies>
> +  <properties>
> +    <junitVersion>3.8.1</junitVersion>
> +  </properties>
> +  </project>
> +{code}
> +
> +Keep in mind that if you set  \emph{-DjunitVersion=3.8} on the  
> command line, then this value would be used for interpolation, not  
> the pom specified one.
> +
> +h3. Environment Properties
> +The properties are taken from the environment and hold the lowest  
> level of precedence.
> +
> +h2. Processing Rules
> +The pom XML is flattened to a list of model properties (this is  
> part of the inheritance processing). The interpolator property list  
> will be referred to as interpolator properties.
> +
> +h3. Preprocessing
> +The initial interpolator property list is constructed and sorted in  
> order of maven properties, system properties, project properties and  
> environment properties. Being a list, it contains duplicate property  
> keys that may reference different values. A common example occurs  
> when overriding a pom property through the command line -D. So all  
> lower duplicate key values are eliminated, resulting in a set of  
> interpolator properties, where order does not matter.
> +
> +The maven property \$\{project.basedir\} is only added to the  
> initial list if the pom being interpolated is within the build (not  
> a dependency within the repository).
> +
> +h3. Pass 1 -withhold using build directories as interpolator  
> properties} In this pass, the list is preprocessed into a set, but  
> excludes  any of the build directories from the interpolator list.  
> In other words, the build directories can be interpolated but they  
> can't be used to interpolate other properties. Interpolating is  
> simply the iteration of all interpolator properties over model  
> properties.
> +
> +h3. Pass 2 - set absolute paths on build directories} At this  
> point, the build directories are completely interpolated but they  
> may or may not contain absolute paths. So each build model property  
> is checked and if it contains a relative path, the absolute path is  
> set based on the \$\{project.basedir\} location.
> +
> +h3. Pass 3- use build directories as interpolator properties} In  
> this pass, all model properties that contain a build directory  
> reference are interpolated with the build directory interpolator  
> properties, which were withheld from pass 1. Now all directory paths  
> within the pom contain absolute references.
> +
> +h2. Interpolation and Profiles}
> +Active profiles are applied prior to interpolation so that any  
> \emph{project.profiles.profile.properties} defined within an active  
> profile can be used as an interpolation property [Still to be  
> implemented]
> \ No newline at end of file
>
>

Thanks,

Jason

----------------------------------------------------------
Jason van Zyl
Founder,  Apache Maven
jason at sonatype dot com
----------------------------------------------------------

Simplex sigillum veri. (Simplicity is the seal of truth.)


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org