Hi,

This has been eating at me a while, so I wanted to start a discussion
and see what others thought. After the problem statement, feel free to
skip to proposed solution if you don't care about my reasoning. You
don't have to spend oodles of time crafting a response/alternative
solution - just throw me some indication of where you like it, where you
don't, any counter examples you have to solutions, and any additional
ideas. I will capture the result in confluence in a more distilled
format. Thanks.

Problem Statement
-----------------

I'm seeing a few problems with the current model - while it is a perfect
representation inside Maven after assembly, there are a couple of
usability issues from the user's end (this isn't about verbosity, but
things that can't be done).

To break it down, the POM has two types of information:
- versioned
- transient

Here are some of the problems we've seen:
- inheritance parent versioning - having to select a version
- I want to separate inheritance of my versioned and transient info
- size of POM inside a JAR - really only need a subset of information
and needs to be resolved
- what gets deployed to the repository during release
- I don't want to change a version when metadata changes

Reasoning
---------

I'm still unsure of what constitutes versioned and transient. Some
things I feel need to be current, no matter what version you are
building. Things like:
- SCM URL base, in case it moves
- perhaps some plugin configuration related to preferences
- CI settings
- deployment settings
- reporting used on the site

The SCM URL is hairy because it is both versioned (tag part) and
transient (server changes location). I'm happy to keep it versioned and
use a profile to override if the server moves.

Preferences in plugin configuration can be dealt with by profiles, no
big deal.

The last 3 actually lead to a different way in which the elements of the
POM can be categorised which also helps with other issues:
- project information (developers, url, scm info, etc) - this is all
that other formats like DOAP provide.
- build information (plugins, layout, ci settings, deployment settings,
reporting)
- dependencies (this fits both categories above)

The project information and dependencies are the things that should go
into JARs and be published to the repository, as it is information used
by other projects depending on it. Build information is not used by
other projects (except for inheritance, see later) - it is local.

Should build info be in the repository? Yes, for more information,
checking dependency closures on plugins, and for inheritance. So we can
stick with that. However I think only the project information belongs in
the JAR.

Where do repositories belong? These belong in project information and
relate to location of information like the SCM stuff does. So does
relocation information which probably should not be in
distributionManagement - instead a repositoryManagement section or such.

Proposed Solutions
------------------

Having worked it through, I see this comes down to inheritance, and
really is just the same issue we've looked at before of how to easily
version a parent.

I want to strictly version the inheritance of my dependencies. I always
want the latest of the project information (but I want it locked in to
that version when deployed). For build information, I also want the
latest, locked in to that version when deployed.

Here's how I think we can address each of the problems:

1) I don't want to change a version when the metadata changes

A: add <metadataRevision> to <parent> and <dependency>

This solves a bunch of issues including some of the stuff about
reproducibility when metadata is changed in the repository because it is
"bad". So like everything else, when omitted you get the latest. The
frequency of checks for updates is driven a combination of the
configuration of the repository, and the status of the metadata you have
(if it is verified in some way then it does not need to look for
updates, though the release process might prompt to check). When
deployed, the version gets locked in. Instead of doing svn commits of
changes to poms, a new version of the metadata can be deployed (this
would entail doing a pom-only deploy and would usually be managed by the
repository manager). I would suggest a filename of
artifactId-version.r1.pom, artifactId-version.r2.pom, etc. where no .rX
is r0, the original.

2) inheritance parent versioning - having to select a version

A: automatic versionining of the parent, and always use latest from children

I think there are 2 types of inheritance:
- generic POM inheritance (plugin parent, mojo parent, company wide
parent, etc)
- multi module build where version is shared

I don't think (1) above applies to the multi module build, as once its
released, its released, and you always want everything from it (see (3)
below). Children should reference the parent version and rely on tools
to do any updating.

In generic POM inheritence, I think that it needs to be versioned, but
you don't need to specify it - just get the latest always. In that case,
it would be best to automatically number the parent - ie no version is
given in the POM, and the technique from (1) is used. Children do not
specify a parent version.

The parent POM may not even exist anywhere in source control - instead
being in a database or visually edited and winding up in the repository.

3) Separating inheritance of versioned and transient info

A: Deprecate dependency inheritance (bare with me :)

The problem of separation only seems to appear in generic pom
inheritance, and then it is only the dependencies used that are of issue.

For starters, in that case, we can just say its is best practice not to
inherit the dependency, then the parent becomes completely project/build
info which we are happy to have the auto versioning for.

But that raises the question - is dependency inheritance worthwhile at
all any more?
- you can achieve the same thing with a transitive dependency, and in
fact can get "multiple inheritance" that way by selecting "dependency
packs" of related pieces when you use them all.
- this will be more likely with specification dependencies, again
removing the need.

The issue I see here is the dependencyManagement, but that too I'd like
to de-emphasise in favour of better conflict resolution (ie, you should
be getting the same version anyway, so do you really need to have the
top level element?)

Possibly a separate discussion, but I'd like to hear thoughts.

4) Size of POM in JAR

A: This is easily fixed by just including relevant information (exclude
all the build, reporting, profiles, etc).

5) What gets deployed to the repository

A: I think its fine to push up the whole pom profiles and all as is now.
I'm concerned a bit about the size when you only need a subset of the
information - however long term I'd like to look into grouping the
metadata downloads and maybe using the index anyway so that probably
isn't relevant.

Cheers,
Brett

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to