• messages

    It is quite difficult to know exactly what messages should be output to the console or not, and it often depends on the user profile: beginner, expert, build manager, simple user, …​

    Being able to define the messages output in a single and homogeneous way could be a good thing.

    To allow this, maybe a solution could be to output messages in the code only by using keys: LOGGER.debug("unhandled.revision", mrid.getRevision());

    The LOGGER would be a constant initialised with the class name.

    A profile wold consist in a message.properties file, associating each key (prefixed by the FQCN) to a message for the given profile. A key with no mapping result in no message at all.

    It would be possible to disable all messages of a class or activate only a certain level per class (as in log4j for instance) to customize a profile at runtime

    Shifting is costly, about 400 calls to messages

  • promote task to update an already published module with a new status

    This task would also automatically update compatibility data (see below)

  • tag task to add one or several tags to an already published module

    Tag could be added in a simple properties file next to the module Ivy file this properties would be updated by this task every time Ivy parses an Ivy file, it would try to locate corresponding tag file, and if any load tags in the module descriptor instance

  • compatibility data

    Tags could be used for to indicate that a module has some compatibility level with another one: if module A 2.0 has been tested successfully with B 1.0 and thus obtain status milestone, then a tag compatible.with.A.2.0=milestone is put on B 1.0 then latest version matcher code could be updated to handle something like this: latest.compatible.milestone to be able to get the latest version of a dependency with at least a tag like compatible.with.A.[any revision]=milestone

    Since all tags should be inspected to know that, maybe using an xml file like this would be better:

    	<module org="orga" name="A">
    		<revision name="2.0" status="milestone"/>

    This would be cleaner, but less simple, and less flexible than using a tags system, which could be used for other use cases.

    Another solution would be to put two tags on B 1.0: one with A revision, and one without. The tag without the revision could be used for latest.compatible.*, meaning that the last compatibility status only would be used. For instance, A 2.0 is said to be release compatible with B 1.0. using latest.compatible.release is thus resolved to B 1.0. But now A 2.1 is built, and a first test tell that it is (at least) milestone compatible with B 1.0. The compatibility status of B is thus decreased to milestone, and latest.compatible.release is not resolved anymore to B 1.0, but maybe B 0.9…​ at least until the release compatibility tests are done on A. Then if it is release compatible, the tag is put back to the good status, and if it isn’t compatible, the compatibility status is left to milestone, which is ok. Consequently the main problem with this solution is the time before all the tests are run. So maybe a module should be promoted (and thus compatibility status updated) only when all tests are done, or when an incompatible level is reached. Note that this solution is only acceptable in case of automatic tests. When the promotion is done by a QA team several days or even weeks after the previous status, maybe we can’t wait for these tests to be done…​

    Another solution would be to promote the module at each step, but only update the tag if the compatibility level is better than the previous one. Another task would then allow to indicate an incompatibility, if some level of tests then fails.

    Switching between latest compatible and latest version could also be done without any modification in Ivy file: use latest.* dependency revision, and configure your resolve task to use compatible only versions.

    This way testing absolute latest version for a continuous integration server would be easy, and if the latest version fails, latest compatible could be used easily, to test the module in a relative isolation of dependency changes. In this case the continuous integration server should notify of the first failure before notifying of the success of the compatible build: integration of latest modules has failed, but not the module itself. It would thus allow to have more often a latest successful build, even in case of API breaks.