I want to understand the differences between DefaultCopySpec and CopySpecWrapper. The follow code has a different behavior depending of the parameter instance class.
With a DefaultCopySpec_Decorated it will be executed immediate and with a CopySpecWrapper_Decorated it will executed on first access in the execution phase. It is used in a zip task like:
zip {
into( 'ikvm' ) with( ikvm( libs ) )
}
The problem with the immediate execution is that it will be execute on definition phase also if the task is not executed. If I do the declaration in a doFirst{} then the task is not executed because the zip is empty before. The result is a simple UP-TO-DATE. A workaround is a to use a task “beforeZip” and “zip” depends on it. But this is ugly for hundred of task.
But it work like expected if the “libs” parameter is a CopySpecWrapper_Decorated.
What is the difference between the both instances?
When I receive the one and one the other class?
Is there a secure solution to convert the one to another type?
This is an implementation Detail that shouldn’t make a difference while using Gradle. The only purpose of CopySpecWrapper is to hide some implementation details. From looking at the code project.copySpec always returns a DefaultCopySpec The snippet you listed above should definitely be evaluated lazy using default Gradle.
Can you create a reproducable small example so I can verify? I don’t know what ‘libs’ is in your snippet and how it is created etc. Maybe it is related to the problem you’re describing here. So a small reproducible gist would be great.
A simple sample is difficult because a small changes has different behavior. I also does not know if I receive a wrapper and when not. That my question here.
This produce the follow output:
************** IKVM start
:sample
************** IKVM pdfc-server-4.0-javadoc.jar
************** IKVM pdfc-server-4.0-sources.jar
The first println is executed in the definition phase. But the println in eachFile is evaluated on execution. If I remove the “width libs” line then the eachFile is never evaluated.
Ok, investigate more time I see now that I have "eachFile misunderstand completely. It is not an iterator over a copySpec. It is an callback event. Then the question is how can i iterate over a copySpec to create a second copySpec. And this lazzy.
We need a drop-in replacement to address the issues with the build-in Zip class. So we’ve modified zip4j and were hoping to write a custom task for it by extending the DefaultTask (Gradle API 7.6) but it’s quite challenging to deal with the pre-existing inputs specially the CopySpec.
I think I need a new subtype of AbstractArchiveTask (Gradle API 7.6) instead. Looks like getSource() in the AbstractArchiveTask can convert the CopySpec to a list of files and folders for us… I hope.
Yes, if you want to write an own zip-like task, I’d also create an AbstractArchiveTask subclass to get the common handling the same as for all other archive tasks.
I guess maybe the easiest is, if you look at the built-in Zip and / or Tar tasks and do your custom implementation after their example.
Unfortunately, we’re now running into this exception, the very thing we’ve locally fixed in zip4j. We run into this as a result of calling getSource().