Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ability to include/exclude paths via real regex #536

Merged
merged 7 commits into from
Mar 7, 2020
16 changes: 15 additions & 1 deletion src/docs/configuration/relocation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ Be specific as possible when configuring relocation as to avoid unintended reloc

## Filtering Relocation

Specific classes or files can be `included`/`excluded` from the relocation operation if necessary.
Specific classes or files can be `included`/`excluded` from the relocation operation if necessary. Use
[Ant Path Matcher](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/util/AntPathMatcher.html)
syntax to specify matching path for your files and directories.

```groovy
// Configuring Filtering for Relocation
Expand All @@ -46,6 +48,18 @@ shadowJar {
}
```

For a more advanced path matching you might want to use [Regular Expressions](https://regexr.com/) instead. Wrap the expresion in `%regex[]` before
passing it to `include`/`exclude`.

```groovy
// Configuring Filtering for Relocation with Regex
shadowJar {
relocate('org.foo', 'a') {
include '%regex[org/foo/.*Factory[0-9].*]'
}
}
```

## Automatically Relocating Dependencies

Shadow is shipped with a task that can be used to automatically configure all packages from all dependencies to be relocated.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ class SimpleRelocator implements Relocator {
normalized = new LinkedHashSet<String>()

for (String pattern : patterns) {
// Regex patterns don't need to be normalized and stay as is
if (pattern.startsWith(SelectorUtils.REGEX_HANDLER_PREFIX)) {
normalized.add(pattern)
continue
}

String classPattern = pattern.replace('.', '/')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,39 @@ class SimpleRelocatorTest extends TestCase {
assertEquals(true, relocator.canRelocatePath("org/f")) // equal to path pattern
assertEquals(true, relocator.canRelocatePath("/org/f")) // equal to path pattern with /
}

void testCanRelocatePathWithRegex() {
SimpleRelocator relocator

// Include with Regex
relocator = new SimpleRelocator("org.foo", null, Collections.singletonList("%regex[org/foo/R(\\\$.*)?\$]"), null)
assertEquals(true, relocator.canRelocatePath("org/foo/R.class"))
assertEquals(true, relocator.canRelocatePath("org/foo/R\$string.class"))
assertEquals(true, relocator.canRelocatePath("org/foo/R\$layout.class"))
assertEquals(false, relocator.canRelocatePath("org/foo/Recording/R.class"))
assertEquals(false, relocator.canRelocatePath("org/foo/Recording.class"))
assertEquals(false, relocator.canRelocatePath("org/foo/bar/R\$string.class"))
assertEquals(false, relocator.canRelocatePath("org/R.class"))
assertEquals(false, relocator.canRelocatePath("org/R\$string.class"))

// Exclude with Regex
relocator = new SimpleRelocator("org.foo", null, null, null)
relocator.exclude("%regex[org/foo/.*Factory[0-9].*]")
assertEquals(true, relocator.canRelocatePath("org/foo/Factory.class"))
assertEquals(true, relocator.canRelocatePath("org/foo/FooFactoryMain.class"))
assertEquals(true, relocator.canRelocatePath("org/foo/BarFactory.class"))
assertEquals(false, relocator.canRelocatePath("org/foo/Factory0.class"))
assertEquals(false, relocator.canRelocatePath("org/foo/FooFactory1Main.class"))
assertEquals(false, relocator.canRelocatePath("org/foo/BarFactory2.class"))

// Include with Regex and normal pattern
relocator = new SimpleRelocator("org.foo", null,
Arrays.asList("%regex[org/foo/.*Factory[0-9].*]", "org.foo.public.*"), null)
assertEquals(true, relocator.canRelocatePath("org/foo/Factory1.class"))
assertEquals(true, relocator.canRelocatePath("org/foo/public/Bar.class"))
assertEquals(false, relocator.canRelocatePath("org/foo/Factory.class"))
assertEquals(false, relocator.canRelocatePath("org/foo/R.class"))
}

void testCanRelocateClass() {
SimpleRelocator relocator
Expand Down