Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ on:
branches:
- 8.x
pull_request:
branches:
- 8.x
workflow_dispatch:

jobs:
Expand Down
4 changes: 4 additions & 0 deletions src/docs/changes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

## [Unreleased]

**Fixed**

- Fix the regression of `PropertiesFileTransformer` in `8.3.7`. ([#1493](https://github.com/GradleUp/shadow/pull/1493))

**Changed**

- Expose Ant as `compile` scope. ([#1488](https://github.com/GradleUp/shadow/pull/1488))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.github.jengelman.gradle.plugins.shadow.internal

import groovy.transform.CompileStatic

@CompileStatic
class CleanProperties extends Properties {

private static class StripCommentsWithTimestampBufferedWriter extends BufferedWriter {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,9 @@ class PropertiesFileTransformer implements Transformer {
String charset = 'ISO_8859_1'

@Internal
Closure<String> keyTransformer = IDENTITY
Closure<String> keyTransformer = new Closure<String>("") {
String doCall(Object arguments) { arguments } // We can't use Closure#IDENTITY instead, as it is not compatible with Groovy 3 and 4.
}

@Override
boolean canTransformResource(FileTreeElement element) {
Expand Down Expand Up @@ -192,6 +194,9 @@ class PropertiesFileTransformer implements Transformer {
}

private Properties transformKeys(Properties properties) {
if (keyTransformer == null) {
throw new IllegalStateException("keyTransformer must not be null.")
}
if (keyTransformer == IDENTITY) {
return properties
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
package com.github.jengelman.gradle.plugins.shadow

import com.github.jengelman.gradle.plugins.shadow.transformers.PropertiesFileTransformer
import com.github.jengelman.gradle.plugins.shadow.util.PluginSpecification
import spock.lang.Issue
import spock.lang.Unroll

class PropertiesFileTransformerSpec extends PluginSpecification {

@Unroll
def 'merge properties with different strategies: #mergeStrategy'() {
given:
File one = buildJar('one.jar')
.insertFile('test.properties',
'key1=one\nkey2=one').write()

File two = buildJar('two.jar')
.insertFile('test.properties',
'key2=two\nkey3=two').write()

buildFile << """
import ${PropertiesFileTransformer.name}
tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
from('${escapedPath(one)}')
from('${escapedPath(two)}')
}
tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
transform(PropertiesFileTransformer) {
paths = ['test.properties']
mergeSeparator = ";"
mergeStrategy = '${mergeStrategy}'
}
}
""".stripIndent()

when:
run('shadowJar')

then:
assert output.exists()

and:
String text = getJarFileContents(output, 'test.properties')
def lines = text.replace('#', '').trim().split("\\r?\\n").toList()
assert lines.size() == 3
switch (mergeStrategy) {
case 'first':
assert lines.containsAll(['key1=one', 'key2=one', 'key3=two'])
break
case 'latest':
assert lines.containsAll(['key1=one', 'key2=two', 'key3=two'])
break
case 'append':
assert lines.containsAll(['key1=one', 'key2=one;two', 'key3=two'])
break
default:
assert false: "Unknown mergeStrategy: $mergeStrategy"
}

where:
mergeStrategy << ['first', 'latest', 'append']
}

def 'merge properties with key transformer'() {
given:
File one = buildJar('one.jar')
.insertFile('META-INF/test.properties', 'foo=bar')
.write()

File two = buildJar('two.jar')
.insertFile('META-INF/test.properties', 'FOO=baz')
.write()

buildFile << """
import ${PropertiesFileTransformer.name}
tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
from('${escapedPath(one)}')
from('${escapedPath(two)}')
}
tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
transform(PropertiesFileTransformer) {
paths = ['META-INF/test.properties']
mergeStrategy = 'append'
keyTransformer = { key -> key.toUpperCase() }
}
}
""".stripIndent()

when:
run('shadowJar')

then:
output.exists()
String text = getJarFileContents(output, 'META-INF/test.properties')
text.contains('FOO=bar,baz')
}

def 'merge properties with specified charset'() {
given:
File one = buildJar('one.jar')
.insertFile('META-INF/utf8.properties', 'foo=第一')
.write()

File two = buildJar('two.jar')
.insertFile('META-INF/utf8.properties', 'foo=第二')
.write()

buildFile << """
import ${PropertiesFileTransformer.name}
tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
from('${escapedPath(one)}')
from('${escapedPath(two)}')
}
tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
transform(PropertiesFileTransformer) {
paths = ['META-INF/utf8.properties']
mergeStrategy = 'append'
charset = 'UTF-8'
}
}
""".stripIndent()

when:
run('shadowJar')

then:
output.exists()
String text = getJarFileContents(output, 'META-INF/utf8.properties')
text.contains('foo=第一,第二')
}

def 'merge properties with mappings'() {
given:
File one = buildJar('one.jar')
.insertFile('META-INF/foo.properties', 'foo=1')
.insertFile('META-INF/bar.properties', 'bar=2')
.write()

File two = buildJar('two.jar')
.insertFile('META-INF/foo.properties', 'foo=3')
.insertFile('META-INF/bar.properties', 'bar=4')
.write()

buildFile << """
import ${PropertiesFileTransformer.name}
tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
from('${escapedPath(one)}')
from('${escapedPath(two)}')
}
tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
transform(PropertiesFileTransformer) {
mappings = [
'META-INF/foo.properties': [mergeStrategy: 'append', mergeSeparator: ';'],
'META-INF/bar.properties': [mergeStrategy: 'latest']
]
}
}
""".stripIndent()

when:
run('shadowJar')

then:
output.exists()

and:
String fooText = getJarFileContents(output, 'META-INF/foo.properties')
fooText.contains('foo=1;3')

and:
String barText = getJarFileContents(output, 'META-INF/bar.properties')
barText.contains('bar=4')
}

@Issue(
['https://github.com/GradleUp/shadow/issues/622',
'https://github.com/GradleUp/shadow/issues/856'
]
)
def 'merged properties dont contain date comment'() {
given:
File one = buildJar('one.jar')
.insertFile('META-INF/test.properties', 'foo=one')
.write()

File two = buildJar('two.jar')
.insertFile('META-INF/test.properties', 'foo=two')
.write()

buildFile << """
import ${PropertiesFileTransformer.name}
tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
from('${escapedPath(one)}')
from('${escapedPath(two)}')
}
tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
transform(PropertiesFileTransformer) {
paths = ['META-INF/test.properties']
mergeStrategy = 'append'
}
}
""".stripIndent()

when:
run('shadowJar')

then:
output.exists()
String text = getJarFileContents(output, 'META-INF/test.properties')
text.replace('#', '').trim() == 'foo=one,two'
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ class ShadowPluginSpec extends PluginSpecification {
package client;
import junit.framework.TestCase;
public class Client extends TestCase {
public static void main(String[] args) {}
public static void main(String[] args) {}
}
""".stripIndent()

Expand Down Expand Up @@ -1029,7 +1029,7 @@ class ShadowPluginSpec extends PluginSpecification {
version = '1.0'
repositories { maven { url = "${repo.uri}" } }
dependencies { api project(':api') }

shadowJar.minimize()
""".stripIndent()

Expand Down Expand Up @@ -1247,8 +1247,4 @@ class ShadowPluginSpec extends PluginSpecification {
JarFile jar = new JarFile(output)
assert jar.entries().collect().findAll { it.name.endsWith('.class') }.size() == 1
}

private String escapedPath(File file) {
file.path.replaceAll('\\\\', '\\\\\\\\')
}
}
Loading