Index: src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorWriter.java =================================================================== --- src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorWriter.java (revision 963973) +++ src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorWriter.java (working copy) @@ -400,6 +400,9 @@ } out.print("\""); } + if (!confs[i].isTransitive()) { + out.println(" transitive=\"false\""); + } if (confs[i].getDeprecated() != null) { out.print(" deprecated=\"" + XMLHelper.escape(confs[i].getDeprecated()) + "\""); } Index: test/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorWriterTest.java =================================================================== --- test/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorWriterTest.java (revision 963973) +++ test/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorWriterTest.java (working copy) @@ -22,12 +22,16 @@ import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; +import java.util.Date; import java.util.GregorianCalendar; import junit.framework.TestCase; +import org.apache.ivy.core.module.descriptor.Configuration; import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor; import org.apache.ivy.core.module.descriptor.ModuleDescriptor; +import org.apache.ivy.core.module.descriptor.Configuration.Visibility; +import org.apache.ivy.core.module.id.ModuleId; import org.apache.ivy.core.module.id.ModuleRevisionId; import org.apache.ivy.core.settings.IvySettings; import org.apache.ivy.util.FileUtil; @@ -105,7 +109,57 @@ '\r', '\n'); assertEquals(expected, wrote); } + + /** + * Test that the transitive attribute is written for non-transitive configurations. + * + * + * + * @see IVY-1207 + * @throws Exception + */ + public void testTransitiveAttributeForNonTransitiveConfs() throws Exception { + // Given a ModuleDescriptor with a non-transitive configuration + DefaultModuleDescriptor md = new DefaultModuleDescriptor(new ModuleRevisionId(new ModuleId( + "myorg", "myname"), "1.0"), "integration", new Date()); + Configuration conf = new Configuration("conf", Visibility.PUBLIC, "desc", null, false, null); + md.addConfiguration(conf); + + // When the ModuleDescriptor is written + XmlModuleDescriptorWriter.write(md, LICENSE, _dest); + + // Then the transitive attribute must be set to false + String output = FileUtil.readEntirely(_dest); + String writtenConf = output.substring(output.indexOf("") + 16, output.indexOf("")).trim(); + assertTrue("Transitive attribute not set to false: " + writtenConf, writtenConf.contains("transitive=\"false\"")); + } + + /** + * Test that the transitive attribute is not written when the configuration IS transitive. + * + * This is the default and writing it will only add noise and cause a deviation from the known + * behavior (before fixing IVY-1207). + * + * @see IVY-1207 + * @throws Exception + */ + public void testTransitiveAttributeNotWrittenForTransitiveConfs() throws Exception { + // Given a ModuleDescriptor with a transitive configuration + DefaultModuleDescriptor md = new DefaultModuleDescriptor(new ModuleRevisionId(new ModuleId( + "myorg", "myname"), "1.0"), "integration", new Date()); + Configuration conf = new Configuration("conf", Visibility.PUBLIC, "desc", null, true, null); + md.addConfiguration(conf); + + // When the ModuleDescriptor is written + XmlModuleDescriptorWriter.write(md, LICENSE, _dest); + + // Then the transitive attribute must NOT be written + String output = FileUtil.readEntirely(_dest); + String writtenConf = output.substring(output.indexOf("") + 16, output.indexOf("")).trim(); + assertFalse("Transitive attribute set: " + writtenConf, writtenConf.contains("transitive=")); + } + private String readEntirely(String resource) throws IOException { return FileUtil.readEntirely(new BufferedReader(new InputStreamReader( XmlModuleDescriptorWriterTest.class.getResource(resource).openStream())));