Author: olamy Date: Wed Jul 24 10:23:08 2013 New Revision: 1506482 URL: http://svn.apache.org/r1506482 Log: [MASSEMBLY-637] fileSet <lineEnding>unix</lineEnding> strips last newline of file Submitted by Stephen Colebourne
Modified: maven/plugins/trunk/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/format/FileFormatter.java maven/plugins/trunk/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/utils/AssemblyFileUtils.java maven/plugins/trunk/maven-assembly-plugin/src/test/java/org/apache/maven/plugin/assembly/utils/AssemblyFileUtilsTest.java Modified: maven/plugins/trunk/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/format/FileFormatter.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/format/FileFormatter.java?rev=1506482&r1=1506481&r2=1506482&view=diff ============================================================================== --- maven/plugins/trunk/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/format/FileFormatter.java (original) +++ maven/plugins/trunk/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/format/FileFormatter.java Wed Jul 24 10:23:08 2013 @@ -31,11 +31,10 @@ import org.codehaus.plexus.util.StringUt import javax.annotation.Nonnull; import javax.annotation.Nullable; + import java.io.File; -import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; -import java.io.InputStreamReader; import java.io.Reader; import java.util.Locale; @@ -120,20 +119,9 @@ public class FileFormatter Reader contentReader = null; try { - if ( encoding == null ) - { - // Use default encoding - contentReader = new InputStreamReader( new FileInputStream( source ) ); - } - else - { - // MASSEMBLY-371 - contentReader = new InputStreamReader( new FileInputStream( source ), encoding ); - } - File target = FileUtils.createTempFile( source.getName() + ".", ".formatted", tempRoot ); - AssemblyFileUtils.convertLineEndings( contentReader, target, lineEndingChars, encoding ); + AssemblyFileUtils.convertLineEndings( source, target, lineEndingChars, null, encoding ); return target; } Modified: maven/plugins/trunk/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/utils/AssemblyFileUtils.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/utils/AssemblyFileUtils.java?rev=1506482&r1=1506481&r2=1506482&view=diff ============================================================================== --- maven/plugins/trunk/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/utils/AssemblyFileUtils.java (original) +++ maven/plugins/trunk/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/utils/AssemblyFileUtils.java Wed Jul 24 10:23:08 2013 @@ -22,11 +22,12 @@ package org.apache.maven.plugin.assembly import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; +import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.RandomAccessFile; -import java.io.Reader; import java.nio.channels.FileChannel; import org.apache.maven.plugin.assembly.archive.ArchiveExpansionException; @@ -134,53 +135,94 @@ public final class AssemblyFileUtils } /** - * NOTE: It is the responsibility of the caller to close the source Reader instance. - * The file content is written using platform encoding. + * Converts the line endings of a file, writing a new file. + * The encoding of reading and writing can be specified. + * + * @param source The source file, not null + * @param dest The destination file, not null * @param lineEndings This is the result of the getLineEndingChars(..) method in this utility class; the actual - * line-ending characters. + * line-ending characters, not null. + * @param atEndOfFile The end-of-file line ending, + * if true then the resulting file will have a new line at the end even if the input didn't have one, + * if false then the resulting file will have no new line at the end even if the input did have one, + * null to determine whether to have a new line at the end of the file based on the input file + * @param encoding The encoding to use, null for platform encoding */ - public static void convertLineEndings( @Nonnull Reader source, File dest, String lineEndings, String encoding ) + public static void convertLineEndings( @Nonnull File source, @Nonnull File dest, String lineEndings, Boolean atEndOfFile, String encoding ) throws IOException { - BufferedWriter out = null; - BufferedReader bufferedSource; - try - { - if ( source instanceof BufferedReader ) - { - bufferedSource = (BufferedReader) source; + // MASSEMBLY-637, MASSEMBLY-96 + // find characters at the end of the file + // needed to preserve the last line ending + // only check for LF (as CRLF also ends in LF) + String eofChars = ""; + if ( atEndOfFile == null) { + RandomAccessFile raf = null; + try { + if ( source.length() >= 1 ) { + raf = new RandomAccessFile( source, "r" ); + raf.seek( source.length() - 1 ); + byte last = raf.readByte(); + if ( last == '\n' ) { + eofChars = lineEndings; + } + } } - else + finally { - bufferedSource = new BufferedReader( source ); + if ( raf != null ) { + try { + raf.close(); + } + catch ( IOException ex ) + { + // ignore + } + } } + } else if ( atEndOfFile.booleanValue() == true ) { + eofChars = lineEndings; + } + BufferedReader in = null; + BufferedWriter out = null; + try + { if ( encoding == null ) { - out = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( dest ) ) ); // platform encoding + // platform encoding + in = new BufferedReader( new InputStreamReader( new FileInputStream( source ) ) ); + out = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( dest ) ) ); } else { + // MASSEMBLY-371 + in = new BufferedReader( new InputStreamReader( new FileInputStream( source ), encoding ) ); out = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( dest ), encoding ) ); } String line; - line = bufferedSource.readLine(); + line = in.readLine(); while ( line != null ) { out.write( line ); - line = bufferedSource.readLine(); + line = in.readLine(); if ( line != null ) { out.write( lineEndings ); } + else + { + out.write( eofChars ); + } } out.flush(); } finally { + IOUtil.close( in ); IOUtil.close( out ); } } Modified: maven/plugins/trunk/maven-assembly-plugin/src/test/java/org/apache/maven/plugin/assembly/utils/AssemblyFileUtilsTest.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-assembly-plugin/src/test/java/org/apache/maven/plugin/assembly/utils/AssemblyFileUtilsTest.java?rev=1506482&r1=1506481&r2=1506482&view=diff ============================================================================== --- maven/plugins/trunk/maven-assembly-plugin/src/test/java/org/apache/maven/plugin/assembly/utils/AssemblyFileUtilsTest.java (original) +++ maven/plugins/trunk/maven-assembly-plugin/src/test/java/org/apache/maven/plugin/assembly/utils/AssemblyFileUtilsTest.java Wed Jul 24 10:23:08 2013 @@ -21,6 +21,7 @@ package org.apache.maven.plugin.assembly import java.io.File; import java.io.FileReader; +import java.io.FileWriter; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; @@ -100,6 +101,7 @@ public class AssemblyFileUtilsTest public void testGetLineEndingChars_ShouldReturnDosLineEnding() throws AssemblyFormattingException { + assertEquals( "\r\n", AssemblyFileUtils.getLineEndingCharacters( "windows" ) ); assertEquals( "\r\n", AssemblyFileUtils.getLineEndingCharacters( "dos" ) ); assertEquals( "\r\n", AssemblyFileUtils.getLineEndingCharacters( "crlf" ) ); } @@ -136,7 +138,16 @@ public class AssemblyFileUtilsTest String test = "This is a \ntest."; String check = "This is a \r\ntest."; - testConversion( test, check, "\r\n" ); + testConversion( test, check, "\r\n", null ); + } + + public void testConvertLineEndings_ShouldReplaceLFWithCRLFAtEOF() + throws IOException + { + String test = "This is a \ntest.\n"; + String check = "This is a \r\ntest.\r\n"; + + testConversion( test, check, "\r\n", null ); } public void testConvertLineEndings_ShouldReplaceCRLFWithLF() @@ -145,7 +156,16 @@ public class AssemblyFileUtilsTest String test = "This is a \r\ntest."; String check = "This is a \ntest."; - testConversion( test, check, "\n" ); + testConversion( test, check, "\n", null ); + } + + public void testConvertLineEndings_ShouldReplaceCRLFWithLFAtEOF() + throws IOException + { + String test = "This is a \r\ntest.\r\n"; + String check = "This is a \ntest.\n"; + + testConversion( test, check, "\n", null ); } public void testConvertLineEndings_ShouldReplaceLFWithLF() @@ -154,7 +174,16 @@ public class AssemblyFileUtilsTest String test = "This is a \ntest."; String check = "This is a \ntest."; - testConversion( test, check, "\n" ); + testConversion( test, check, "\n", null ); + } + + public void testConvertLineEndings_ShouldReplaceLFWithLFAtEOF() + throws IOException + { + String test = "This is a \ntest.\n"; + String check = "This is a \ntest.\n"; + + testConversion( test, check, "\n", null ); } public void testConvertLineEndings_ShouldReplaceCRLFWithCRLF() @@ -163,33 +192,128 @@ public class AssemblyFileUtilsTest String test = "This is a \r\ntest."; String check = "This is a \r\ntest."; - testConversion( test, check, "\r\n" ); + testConversion( test, check, "\r\n", null ); + } + + public void testConvertLineEndings_ShouldReplaceCRLFWithCRLFAtEOF() + throws IOException + { + String test = "This is a \r\ntest.\r\n"; + String check = "This is a \r\ntest.\r\n"; + + testConversion( test, check, "\r\n", null ); + } + + public void testConvertLineEndings_LFToCRLFNoEOFForceEOF() + throws IOException + { + String test = "This is a \ntest."; + String check = "This is a \r\ntest.\r\n"; + + testConversion( test, check, "\r\n", true ); + } + + public void testConvertLineEndings_LFToCRLFWithEOFForceEOF() + throws IOException + { + String test = "This is a \ntest.\n"; + String check = "This is a \r\ntest.\r\n"; + + testConversion( test, check, "\r\n", true ); + } + + public void testConvertLineEndings_LFToCRLFNoEOFStripEOF() + throws IOException + { + String test = "This is a \ntest."; + String check = "This is a \r\ntest."; + + testConversion( test, check, "\r\n", false ); } - private void testConversion( String test, String check, String lineEndingChars ) + public void testConvertLineEndings_LFToCRLFWithEOFStripEOF() throws IOException { - File dest = File.createTempFile( "line-conversion-test.", "" ); + String test = "This is a \ntest.\n"; + String check = "This is a \r\ntest."; + + testConversion( test, check, "\r\n", false ); + } + + public void testConvertLineEndings_CRLFToLFNoEOFForceEOF() + throws IOException + { + String test = "This is a \r\ntest."; + String check = "This is a \ntest.\n"; + + testConversion( test, check, "\n", true ); + } + + public void testConvertLineEndings_CRLFToLFWithEOFForceEOF() + throws IOException + { + String test = "This is a \r\ntest.\r\n"; + String check = "This is a \ntest.\n"; + + testConversion( test, check, "\n", true ); + } + + public void testConvertLineEndings_CRLFToLFNoEOFStripEOF() + throws IOException + { + String test = "This is a \r\ntest."; + String check = "This is a \ntest."; + + testConversion( test, check, "\n", false ); + } + + public void testConvertLineEndings_CRLFToLFWithEOFStripEOF() + throws IOException + { + String test = "This is a \r\ntest.\r\n"; + String check = "This is a \ntest."; + + testConversion( test, check, "\n", false ); + } + + private void testConversion( String test, String check, String lineEndingChars, Boolean eof ) + throws IOException + { + File source = File.createTempFile( "line-conversion-test-in.", "" ); + source.deleteOnExit(); + File dest = File.createTempFile( "line-conversion-test-out.", "" ); dest.deleteOnExit(); + + FileWriter sourceWriter = null; + StringReader sourceReader = new StringReader( test ); + try + { + sourceWriter = new FileWriter( source ); - // Using platform encoding for the conversion tests in this class is OK - AssemblyFileUtils.convertLineEndings( new StringReader( test ), dest, lineEndingChars, null ); + IOUtil.copy( sourceReader, sourceWriter ); + } + finally + { + IOUtil.close( sourceWriter ); + } - FileReader reader = null; - StringWriter writer = new StringWriter(); + // Using platform encoding for the conversion tests in this class is OK + AssemblyFileUtils.convertLineEndings( source, dest, lineEndingChars, eof, null ); + FileReader destReader = null; + StringWriter destWriter = new StringWriter(); try { - reader = new FileReader( dest ); + destReader = new FileReader( dest ); - IOUtil.copy( reader, writer ); + IOUtil.copy( destReader, destWriter ); } finally { - IOUtil.close( reader ); + IOUtil.close( destReader ); } - assertEquals( check, writer.toString() ); + assertEquals( check, destWriter.toString() ); } }