[ 
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)

Reply via email to