When I use the copy task on a file that contains Windows linendings (CRLF) then the target file has Windows lineendings as expected.
If I use “expand” in the copy task then if a file that contains Windows lineendings (CRLF) is copied the target file has UNIX lineendings CR instead of keeping CRLF.
Here is a gradle.build to demonstrate (unfortunatly I am not allowed to upload the files.
import groovy.io.FileType
def src = file('TEMPLATE')
def tgt_with_substitution = file('RESULT/with_substitution')
def tgt_without_substitution = file('RESULT/without_substitution')
task copy_without_substitution (type: Copy) {
from src
into tgt_without_substitution
rename { fileName ->
"without_substitution_${(fileName - 'template_')}"
}
}
task copy_with_substitution (type: Copy) {
from src
into tgt_with_substitution
expand(gradle_fan: 'Kai')
rename { fileName ->
"with_substitution_${(fileName - 'template_')}"
}
}
boolean has_windows_lineendings(File file) {
String fileContents = file.text
return ( fileContents =~ /\r\n/ )
}
task examine_results {
dependsOn copy_with_substitution
dependsOn copy_without_substitution
}
examine_results.doLast( {
tgt_without_substitution.eachFile(FileType.FILES){ f ->
printf "%44s %s\n", f.name, ( has_windows_lineendings(f) ? "CRLF (Windows)" : "CR (Unix)" )
}
tgt_with_substitution.eachFile(FileType.FILES){ f ->
printf "%44s %s\n", f.name, ( has_windows_lineendings(f) ? "CRLF (Windows)" : "CR (Unix)" )
}
println '''
The difference occurs when this script is executed in Windows.
This is a bit of surprise, the behavior I would expect is that,
line endings of the template are not changed when substituting
i.e.
with_substitution_windows_lineendings.txt CR (Windows)
instead of
with_substitution_windows_lineendings.txt CR (Unix)
'''
})
I ran this on Windows and reproduced the issue with Gradle 2.4, 2.5 and 2.6
The Directory TEMPLATE contains two files:
template_unix_lineendings.txt
template_windows_lineendings.txt
Content of template_unix_lineendings.txt. As you might think the file has LF (Unix) lineendings.
This text is UTF-8 without BOM with UNIX lineendings (LF)
Hello ${gradle_fan},
Gradle unfortunately does not preserve line endings on substitution.
Best regards
Kai
Content of template_unix_lineendings.txt is similar but as you might think the file has CR+LF (Windows) lineendings.
This text is UTF-8 without BOM with WINDOWS lineendings (CR+LF)
Hello ${gradle_fan},
Gradle unfortunately does not preserve line endings on substitution.
Best regards
Kai
And sorry for causing additional confusion. I didn’t note that I wrote CR for Unix lineending instead of LF.
thank you for pointing to GROOVY-3487. This makes pretty clear why this happens.
The Ant filter will help me to implement a well working workaround in my build.gradle file.
I will add a dependent task for all files with destination platform Windows.
As the target of the real build process are some ZIP files for Windows and some ZIP files for UNIX,
the task chain will unfortunately get longer, as I now need to stage in a temporary directory.
Would be nice if this implicit Groovy optimization could be controlled in a declarative manner in the Copy task
specification at some point.