Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/t1/pomx
Extended Maven POM file format
https://github.com/t1/pomx
build-tool maven maven-extension polyglot pom pomx-profile xml xsd
Last synced: about 7 hours ago
JSON representation
Extended Maven POM file format
- Host: GitHub
- URL: https://github.com/t1/pomx
- Owner: t1
- License: apache-2.0
- Created: 2017-02-17T07:32:34.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2022-01-01T10:25:31.000Z (almost 3 years ago)
- Last Synced: 2023-10-20T23:19:19.605Z (about 1 year ago)
- Topics: build-tool, maven, maven-extension, polyglot, pom, pomx-profile, xml, xsd
- Language: Java
- Homepage:
- Size: 105 KB
- Stars: 8
- Watchers: 4
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Xml Is Not The Problem
There's a lot of complaining about [Maven](http://maven.apache.org) being too verbose.
The Maven developers listened and started [Polyglot Maven](https://github.com/takari/polyglot-maven/tree/master/polyglot-xml)
to address the issue.
They support Groovy, Scala, Ruby, Yaml or other file formats, and they may be beneficial to some people,
but I don't think that XML is the problem, so those other file formats are not guaranteed to be a cure.XML has reputation for being verbose, because it requires you to repeat the name of the opening tag when closing it.
This actually does add a bit of verbosity, but it's also quite useful to orient in large blocks.
XML also supports attributes, which actually require a little bit less overhead than JSON!
Maven POM files just never use them!
Instead of expressing a dependency like this:```xml
ch.qos.logback
logback-classic
1.2.1```
A POM could use attributes like this:
```xml
```
The Polyglot project has an XML format that goes exactly this way.
The other file formats use an even more compact format by simply separating the GAV fields with colons.
This is less explicit, but the GAV coordinates are ubiquitous enough, nowadays, so everybody will easily understand them.
Such a compact notation could be used in XML, too, and it would look like this:```xml
ch.qos.logback:logback-classic:1.2.1
```While this makes the syntax more concise, the real benefit other languages _can_ provide (if used properly),
is to reduce the repetition in you build files - Don't Repeat Yourself or DRY.
By leveraging reuse, build files don't just get more concise,
they also get more uniform (by reducing the snowflake effect: every snow crystal is different)
and more expressive (if you can find a solid abstraction with a clear name).
I.e. if you want e.g. a Java EE 7 WAR, you should only specify that this is what you want,
and the know-how required to build it, the dependencies, the Java compiler setting, the properties, etc.
is expressed once-and-only-once in a file in the repository. We can do that with XML.
POMX does so by allowing profiles to be defined in Maven repository files.Xml is not the problem.
## Quick-Start
Add a directory `.mvn` to your project.
Create a file `extensions.xml` in `.mvn` containing:```xml
com.github.t1
pomx
VERSION
```
Copy your `pom.xml` to `pomx.xml` and stop using the old file... it will be overwritten with every build.
It's required by your IDE and other tools and Maven will install and deploy it normally,
so Repository managers etc. can use it.
You don't have to put it under version control, but a fresh checkout would not be properly recognized by your IDE;
and the generated `pom.xml` is the only place to see build differences when external SNAPSHOT profiles change.
So it's a good practice to check the `pom.xml` into your SCM.## Setup
I took a look at the code of the Polyglot project, but I absolutely need a classic POM to be generated
for other tools to work correctly; Polyglot still works on this.
And my code is much smaller and easier to understand.The XSD is in `https://raw.githubusercontent.com/t1/pomx/master/src/main/resources/schemas/pom-5.0.0.xsd`
and I boldly name the namespace `urn:xsd:maven:pomx:5.0.0`.## Features
### Include `modelVersion` & New XSD
old:
```xml
4.0.0
```
new:
```xml
```
### Compact GAV with packaging as element
old:
```xml
com.github.t1
deployer
2.7.3-SNAPSHOT
war```
new:
```xml
com.github.t1:deployer:2.7.3-SNAPSHOT
```schema: `groupId:artifactId:version`
or: `groupId:artifactId:classifier:version`### Compact GAV of Build Plugins
old:
```xml
org.apache.maven.plugins
maven-jar-plugin
2.4
false
```
new:
```xml
false
```
### Compact Dependency Management
old:
```xml
org.jboss.arquillian
arquillian-bom
1.1.11.Final
import
pom
```new:
```xml
org.jboss.arquillian:arquillian-bom:1.1.11.Final
```### Compact Dependencies Grouped By Scope
old:
```xml
javax
javaee-api
7.0
provided
```new:
```xml
javax:javaee-api:7.0
````optional`:
```xml
javax:javaee-api:7.0
```### External Profiles
Profiles can be stored in a repository and referenced in the POMX:
```xml
javax:javaee-api:7.0
```The profile xml file is resolved like a maven dependency, included into the POM, and activated when run.
This feature is similar to [maven tiles](https://github.com/repaint-io/maven-tiles).
Even though it is a `profile`, the file can have a `project` namespace like a `pomx`, i.e.:
```xml
my.group:my.artifact:1.0
...```
In the generated POM, this profile would have the `my.group:my.artifact` so you can disable it like this:
`mvn clean install -P-my.group:my.artifact`
(The colon was chosen for clarity, as '.' and '-' are too common in group and artifact ids)
Note: This will probably change in the future! As the profile may have to be merged completely.
Some profile elements are removed and not copied into the target profile: `modelVersion`, `groupId`, `artifactId`, `version`, `packaging`, `name`, `description`
Some profile elements are merged into the target `project`, not copied into the target profile: `licenses`, `repositories`, `distributionManagement`, `scm`, and `profiles`
You can't deactivate these elements by deactivating the profile.Finally, a property `..version` is set to the version of every external profile.
For a use case see the [t1-profile](https://github.com/t1/pomx-profile-t1).# Quirks
The order of the elements in a POM xml file is normally free.
But I wanted to have multiple `profile` elements on the top level,
and XSDs don't seem to allow `maxOccurs="unbound"` for `xs:any`, so I provisionally used `xs:sequence`,
which requires the elements to have a fixed order.
I'm not an XSD expert, so I had planned to learn how to fix this,
but before I did, I thought that this might be even better.
It makes orientation in big POMs easier, so ordered the elements supposedly usefully, and still like it.
It's irritating at times, esp. when you migrate to the new format, but I won't investigate any further.# Major TODOs
### Download External Profiles
External profiles are yet expanded only from your local repository (`~/.m2/repository`).
So you'll have to fetch them manually before you start the first build:`mvn dependency:get -DgroupId=my.group -DartifactId=my.artifact -Dpackaging=xml -Dversion=1.0`
### Compensate For External Changes
E.g. the maven release plugin manipulates the `pom.xml`, not the source of truth `pomx`, by setting the version, e.g., `1.2.3-SNAPSHOT` to `1.2.3`. When it starts the actual build, pomx overwrites the `pom.xml` reverting the version change.
The build won't properly run.Im currently unsure how to fix it. We could hook into the plugins, or we could check the change date and when the pom is newer than the pomx, we could create a diff and apply it to the pomx.
As a manual workaround, I do the following steps:
- disable the extension (renaming the `.mvn` directory is generally good enough)
- commit my changes
- do the release
- re-enable the extension
- manually update my `pomx.xml` (mostly update the version)
- commit these changes# Ideas
- Scan for `modules`, i.e. look at all direct directories, if they include a `pomx.xml`,
and add them to the `modules` in the parent. This is then recursive for those modules.