[GRADLE-456] Configuration.copy does not copy all attributes of the configuration Created: 18/Apr/09  Updated: 04/Jan/13  Resolved: 22/Apr/09

Status: Resolved
Project: Gradle
Affects Version/s: None
Fix Version/s: 0.6

Type: Bug
Reporter: Steve Appling Assignee: Hans Dockter
Resolution: Fixed Votes: 0

Attachments: Text File ConfigurationCopy.patch    

 Description   

Configuration.copy (and friends) only copies the list of dependencies and the name (appropriately modified). It does not copy other important fields (like transitive) so for Configuration a, a.resolve() != a.copy().resolve().

I have included a patch with a fix for this, updated the unit test to exercise the fix, and added more javadoc to the Configuration interface for some of the methods that were unclear to me without reading the code.

A few notes:
I performed a shallow copy of the artifacts and excludeRules. I'm not sure whether the artifacts should be cloned or not. Someone who understands the usage better might investigate this. I feel better about shallow copying the excludeRules since they appear to be immutable. I'm not really sure how they are used, though, since there doesn't seem to be any way to set them in the Configuration interface (read only).

Also, I intentionally didn't copy extendsFrom and I noted this in the JavaDoc. While it is strange to have a.getHierarchy() != a.copy().getHierarchy(), copying this would mess up the intended distinction between copy and copyRecursive when resolve was called on the copy.



 Comments   
Comment by Hans Dockter [ 22/Apr/09 ]

I have applied your patch (with a slight modification, see below).

I performed a shallow copy of the artifacts and excludeRules. I'm not sure whether the artifacts should be cloned or not. Someone who understands the usage better might investigate this. I feel better about shallow copying the excludeRules since they appear to be immutable. I'm not really sure how they are used, though, since there doesn't seem to be any way to set them in the Configuration interface (read only).

Artifacts are value objects. They don't have a lifecycle. So a shallow copy is the right thing. The same is basically true for excludeRules. The only change I have made in your patch is to change copiedConfiguration.setExcludeRules(getExcludeRules()) to use a new set in the copiedConfigurations.

Also, I intentionally didn't copy extendsFrom and I noted this in the JavaDoc. While it is strange to have a.getHierarchy() != a.copy().getHierarchy(), copying this would mess up the intended distinction between copy and copyRecursive when resolve was called on the copy.

The intended main use case is to have a stand alone configuration, that is a configuration that lives not in the same ConfigurationContainer. For example such a configuration should not show up in an ivy.xml produced by this project. Therefore we want to flatten the hierarchy for the copy.

Another use case would be to copy the configuration within the same container. This is not supported yet. A possible notation for that could be (this would only copy the dependencies):

dependencies {
   conf1 "junit:junit:4.4"
   conf2 conf1, "commons-logging:commons-logging:1.0"
}

I don't know whether we should support a real copy in the same container. What is your use case?

Comment by Steve Appling [ 22/Apr/09 ]

My use case was actually to pull out the list of external dependencies for a configuration so I could copy them to a special location. The copied configuration is standalone and did not need to be in the ConfigurationContainer.

configurations.webinflibruntime.copyRecursive(DependencySpecs.type(Type.EXTERNAL)).resolve()

previously (0.5), this was done with:
dependencies.findConfiguration('webinflibruntime').resolve

{ setDependencySpec(DependencySpecs.type(Type.EXTERNAL)) }

BTW, I like it better the way it is now. This should be copied before resolving. I just needed the transitive attribute to get copied too.

Generated at Wed Jun 30 11:30:34 CDT 2021 using Jira 8.4.2#804003-sha1:d21414fc212e3af190e92c2d2ac41299b89402cf.