[
https://issues.apache.org/jira/browse/MCLEAN-125?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Peter De Maeyer updated MCLEAN-125:
-----------------------------------
Description:
In complex multi-module projects with custom plugins, there is often a
situation where one module populates the {{target/}} directory of _another_
(typically sibling or parent) module. While I agree that is not ideal and not
recommended practice, it is sometimes the only way to work around limitations
in plugins or build setups. Because of its design, the current
{{maven-clean-plugin}} deletes these files too, breaking the build when doing a
{{mvn clean verify}}.
The workaround in such a case is to use {{mvn clean; mvn verify}} instead, note
the semicolon. The reason is that in the first case the {{target/}} directory
is cleared at the start of every module's build life cycle, clearing any needed
files that a previous module has put there. The workaround {{mvn clean; mvn
verify}} works, but it requires understanding of the user to correctly build
the multi-module project, which is suboptimal. It would be better if that
knowledge were embedded in the build script.
h3. Idea 1
To better support these situations, it would be useful to have for example a
{{cleanAtStart}} option to the {{maven-clean-plugin}} that would clean _all_
modules during the "clean" phase of the first one. It would be similar and
complementary to the {{installAtEnd}} option of the {{maven-install-plugin}},
or the {{deployAtEnd}} option of the {{maven-deploy-plugin}}. This would move
the responsibility for correctly cleaning the project from the user to the
build, where it belongs. Then users could do a plain {{mvn clean install}}
while trusting the build script to take care of any of its own multi-module
intricacies.
I did some preliminary analysis of what it would take to implement this, using
the {{maven-invoker-plugin}}'s {{installAtEnd}} as inspiration, but it's not so
simple. The advantage that the {{maven-install-plugin}} has is that it can
visit all the plugin executions of all the modules in a normal way and merely
needs to defer the actual installation. And even that is a hack to work around
the fundamental limitation that Maven itself has no support for this. Here, for
the {{maven-clean-plugin}}, it is different: it needs to clean modules at the
very start, before anything else, based on information that is not available
yet 'coz the executions of the next modules hasn't been visited yet.
Conclusion: it is impossible to implement due to lack of support from the Maven
framework.
h3. Idea 2
Another idea is to only delete files based on modification time < build time,
for example by configuring the Clean plugin with an {{excludeBuildFiles}}
parameter. This would effectively delete files which were the result of
_previous_ builds, but _not_ files which are the result of the _current_ build.
This works assuming that:
* Modification times of files produced in output directories are not
manipulated. _If_ they are manipulated, this breaks the feature and files may
be deleted while they're not supposed to, or the other way around.
* Modification time is enabled on the file system and are granular enough to
separate consecutive builds. Imagine for example the modification times are not
granular enough so that two consecutive builds have the same build timestamp.
That would mean files are not deleted when they're supposed to. Generally, on
Linux timestamps have millisecond, and on Windows at least second precision
AFAIK, which is generally good enough.
Conclusion: this works quite well in practice. I'll create a PR for this.
was:
In complex multi-module projects with custom plugins, there is often a
situation where one module populates the {{target/}} directory of _another_
(typically sibling or parent) module. While I agree that is not ideal and not
recommended practice, it is sometimes the only way to work around limitations
in plugins or build setups.
In such a case, one sooner or later bumps into the situation where {{mvn clean
verify}} fails while {{mvn clean; mvn verify}} (note the semicolon) succeeds.
The reason is that in the first case the {{target/}} directory is cleared at
the start of every module's build life cycle, clearing any needed files that a
previous module has put there. The workaround {{mvn clean; mvn verify}} works,
but it requires understanding of the user to correctly build the multi-module
project, which is suboptimal. It would be better if that knowledge were
embedded in the build script.
To better support these situations, it would be useful to have for example a
{{cleanAtStart}} option to the {{maven-clean-plugin}} that would clean _all_
modules during the "clean" phase of the first one. It would be similar and
complementary to the {{installAtEnd}} option of the {{maven-install-plugin}},
or the {{deployAtEnd}} option of the {{maven-deploy-plugin}}. This would move
the responsibility for correctly cleaning the project from the user to the
build, where it belongs. Then users could do a plain {{mvn clean install}}
while trusting the build script to take care of any of its own multi-module
intricacies.
I did some preliminary analysis of what it would take to implement this, using
the {{maven-invoker-plugin}}'s {{installAtEnd}} as inspiration, but it's not so
simple. The advantage that the {{maven-install-plugin}} has is that it can
visit all the plugin executions of all the modules in a normal way and merely
needs to defer the actual installation. Here, for the {{maven-clean-plugin}},
it is different: it needs to clean modules at the very start, before anything
else, based on information that is not available yet 'coz the executions of the
next modules hasn't been visited yet.
Another idea for an implementation I had was to monitor the file system for
files that were added during the build (by other modules) and exclude those
from cleaning, but that is also (too) complicated to implement.
Anyway, difficulty of implementation aside, I think this would be a good
feature that would complement existing features such as {{installAtEnd}} and
{{deployAtEnd}}. Ideally in a 3.x version.
> Don't clean files put in the output directory by previous modules during the
> same build
> ---------------------------------------------------------------------------------------
>
> Key: MCLEAN-125
> URL: https://issues.apache.org/jira/browse/MCLEAN-125
> Project: Maven Clean Plugin
> Issue Type: Improvement
> Affects Versions: 3.4.0
> Reporter: Peter De Maeyer
> Priority: Major
>
> In complex multi-module projects with custom plugins, there is often a
> situation where one module populates the {{target/}} directory of _another_
> (typically sibling or parent) module. While I agree that is not ideal and not
> recommended practice, it is sometimes the only way to work around limitations
> in plugins or build setups. Because of its design, the current
> {{maven-clean-plugin}} deletes these files too, breaking the build when doing
> a {{mvn clean verify}}.
> The workaround in such a case is to use {{mvn clean; mvn verify}} instead,
> note the semicolon. The reason is that in the first case the {{target/}}
> directory is cleared at the start of every module's build life cycle,
> clearing any needed files that a previous module has put there. The
> workaround {{mvn clean; mvn verify}} works, but it requires understanding of
> the user to correctly build the multi-module project, which is suboptimal. It
> would be better if that knowledge were embedded in the build script.
> h3. Idea 1
> To better support these situations, it would be useful to have for example a
> {{cleanAtStart}} option to the {{maven-clean-plugin}} that would clean _all_
> modules during the "clean" phase of the first one. It would be similar and
> complementary to the {{installAtEnd}} option of the {{maven-install-plugin}},
> or the {{deployAtEnd}} option of the {{maven-deploy-plugin}}. This would move
> the responsibility for correctly cleaning the project from the user to the
> build, where it belongs. Then users could do a plain {{mvn clean install}}
> while trusting the build script to take care of any of its own multi-module
> intricacies.
> I did some preliminary analysis of what it would take to implement this,
> using the {{maven-invoker-plugin}}'s {{installAtEnd}} as inspiration, but
> it's not so simple. The advantage that the {{maven-install-plugin}} has is
> that it can visit all the plugin executions of all the modules in a normal
> way and merely needs to defer the actual installation. And even that is a
> hack to work around the fundamental limitation that Maven itself has no
> support for this. Here, for the {{maven-clean-plugin}}, it is different: it
> needs to clean modules at the very start, before anything else, based on
> information that is not available yet 'coz the executions of the next modules
> hasn't been visited yet.
> Conclusion: it is impossible to implement due to lack of support from the
> Maven framework.
> h3. Idea 2
> Another idea is to only delete files based on modification time < build time,
> for example by configuring the Clean plugin with an {{excludeBuildFiles}}
> parameter. This would effectively delete files which were the result of
> _previous_ builds, but _not_ files which are the result of the _current_
> build. This works assuming that:
> * Modification times of files produced in output directories are not
> manipulated. _If_ they are manipulated, this breaks the feature and files may
> be deleted while they're not supposed to, or the other way around.
> * Modification time is enabled on the file system and are granular enough to
> separate consecutive builds. Imagine for example the modification times are
> not granular enough so that two consecutive builds have the same build
> timestamp. That would mean files are not deleted when they're supposed to.
> Generally, on Linux timestamps have millisecond, and on Windows at least
> second precision AFAIK, which is generally good enough.
> Conclusion: this works quite well in practice. I'll create a PR for this.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)