You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
399 lines
13 KiB
Groovy
399 lines
13 KiB
Groovy
package org.xbib.gradle.plugin.shadow.tasks
|
|
|
|
import org.gradle.api.file.DuplicatesStrategy
|
|
import org.gradle.api.internal.file.copy.CopySpecResolver
|
|
import org.gradle.api.logging.LogLevel
|
|
import org.gradle.api.tasks.bundling.ZipEntryCompression
|
|
import org.gradle.api.Action
|
|
import org.gradle.api.artifacts.Configuration
|
|
import org.gradle.api.file.FileCollection
|
|
import org.gradle.api.internal.DocumentationRegistry
|
|
import org.gradle.api.internal.file.FileResolver
|
|
import org.gradle.api.internal.file.copy.CopyAction
|
|
import org.gradle.api.tasks.InputFiles
|
|
import org.gradle.api.tasks.Internal
|
|
import org.gradle.api.tasks.Optional
|
|
import org.gradle.api.tasks.TaskAction
|
|
import org.gradle.api.tasks.bundling.Jar
|
|
import org.gradle.api.tasks.util.PatternSet
|
|
import org.gradle.internal.Factory
|
|
import org.gradle.api.tasks.util.internal.PatternSets
|
|
import org.xbib.gradle.plugin.shadow.ShadowStats
|
|
import org.xbib.gradle.plugin.shadow.internal.DefaultDependencyFilter
|
|
import org.xbib.gradle.plugin.shadow.internal.DefaultZipCompressor
|
|
import org.xbib.gradle.plugin.shadow.internal.DependencyFilter
|
|
import org.xbib.gradle.plugin.shadow.internal.UnusedTracker
|
|
import org.xbib.gradle.plugin.shadow.internal.ZipCompressor
|
|
import org.xbib.gradle.plugin.shadow.relocation.Relocator
|
|
import org.xbib.gradle.plugin.shadow.relocation.SimpleRelocator
|
|
import org.xbib.gradle.plugin.shadow.transformers.AppendingTransformer
|
|
import org.xbib.gradle.plugin.shadow.transformers.GroovyExtensionModuleTransformer
|
|
import org.xbib.gradle.plugin.shadow.transformers.ServiceFileTransformer
|
|
import org.xbib.gradle.plugin.shadow.transformers.Transformer
|
|
import org.xbib.gradle.plugin.shadow.zip.ZipOutputStream
|
|
|
|
import java.util.concurrent.Callable
|
|
|
|
class ShadowJar extends Jar implements ShadowSpec {
|
|
|
|
private List<Transformer> transformers
|
|
|
|
private List<Relocator> relocators
|
|
|
|
private List<Configuration> configurations
|
|
|
|
private DependencyFilter dependencyFilter
|
|
|
|
private boolean minimizeJar
|
|
|
|
private DependencyFilter dependencyFilterForMinimize
|
|
|
|
private ShadowStats shadowStats
|
|
|
|
ShadowJar() {
|
|
super()
|
|
dependencyFilter = new DefaultDependencyFilter(getProject())
|
|
dependencyFilterForMinimize = new DefaultDependencyFilter(getProject())
|
|
setManifest(new DefaultInheritManifest(getServices().get(FileResolver)))
|
|
transformers = []
|
|
relocators = []
|
|
configurations = []
|
|
shadowStats = new ShadowStats()
|
|
setDuplicatesStrategy(DuplicatesStrategy.INCLUDE)
|
|
}
|
|
|
|
@Override
|
|
ShadowJar minimize() {
|
|
minimizeJar = true
|
|
this
|
|
}
|
|
|
|
@Override
|
|
ShadowJar minimize(Action<DependencyFilter> c) {
|
|
minimize()
|
|
if (c != null) {
|
|
c.execute(dependencyFilterForMinimize)
|
|
}
|
|
return this
|
|
}
|
|
|
|
@Override
|
|
@Internal
|
|
ShadowStats getStats() {
|
|
shadowStats
|
|
}
|
|
|
|
@Override
|
|
InheritManifest getManifest() {
|
|
(InheritManifest) super.getManifest()
|
|
}
|
|
|
|
@Override
|
|
protected CopyAction createCopyAction() {
|
|
DocumentationRegistry documentationRegistry = getServices().get(DocumentationRegistry)
|
|
FileCollection toMinimize = dependencyFilterForMinimize.resolve(configurations)
|
|
UnusedTracker unusedTracker = UnusedTracker.forProject(getProject(), toMinimize)
|
|
CopySpecResolver copySpecResolver = mainSpec.buildRootResolver()
|
|
Factory<PatternSet> patternSetFactory = PatternSets.getNonCachingPatternSetFactory()
|
|
PatternSet patternSet = patternSetFactory.create()
|
|
patternSet.setCaseSensitive(copySpecResolver.caseSensitive)
|
|
patternSet.include(copySpecResolver.allIncludes)
|
|
patternSet.includeSpecs(copySpecResolver.allIncludeSpecs)
|
|
patternSet.exclude(copySpecResolver.allExcludes)
|
|
patternSet.excludeSpecs(copySpecResolver.allExcludeSpecs)
|
|
new ShadowCopyAction(getLogger(), getArchiveFile().get().getAsFile(), getInternalCompressor(), documentationRegistry,
|
|
this.getMetadataCharset(), transformers, relocators, patternSet, shadowStats,
|
|
isPreserveFileTimestamps(), minimizeJar, unusedTracker)
|
|
}
|
|
|
|
@Internal
|
|
protected ZipCompressor getInternalCompressor() {
|
|
switch (getEntryCompression()) {
|
|
case ZipEntryCompression.DEFLATED:
|
|
return new DefaultZipCompressor(isZip64(), ZipOutputStream.DEFLATED)
|
|
case ZipEntryCompression.STORED:
|
|
return new DefaultZipCompressor(isZip64(), ZipOutputStream.STORED)
|
|
default:
|
|
throw new IllegalArgumentException(String.format("unknown compression type %s", entryCompression))
|
|
}
|
|
}
|
|
|
|
@TaskAction
|
|
protected void copy() {
|
|
from(getIncludedDependencies())
|
|
super.copy()
|
|
getLogger().info(shadowStats.toString())
|
|
}
|
|
|
|
@InputFiles
|
|
FileCollection getIncludedDependencies() {
|
|
getProject().files(new Callable<FileCollection>() {
|
|
|
|
@Override
|
|
FileCollection call() throws Exception {
|
|
return dependencyFilter.resolve(configurations)
|
|
}
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Configure inclusion/exclusion of module & project dependencies into uber jar.
|
|
*
|
|
* @param c the configuration of the filter
|
|
* @return this
|
|
*/
|
|
@Override
|
|
ShadowJar dependencies(Action<DependencyFilter> c) {
|
|
if (c != null) {
|
|
c.execute(dependencyFilter)
|
|
}
|
|
this
|
|
}
|
|
|
|
/**
|
|
* Add a Transformer instance for modifying JAR resources and configure.
|
|
*
|
|
* @param clazz the transformer to add. Must have a no-arg constructor
|
|
* @return this
|
|
*/
|
|
@Override
|
|
ShadowJar transform(Class<? extends Transformer> clazz)
|
|
throws InstantiationException, IllegalAccessException {
|
|
transform(clazz, null)
|
|
}
|
|
|
|
/**
|
|
* Add a Transformer instance for modifying JAR resources and configure.
|
|
*
|
|
* @param clazz the transformer class to add. Must have no-arg constructor
|
|
* @param c the configuration for the transformer
|
|
* @return this
|
|
*/
|
|
@Override
|
|
ShadowJar transform(Class<? extends Transformer> clazz, Action<? extends Transformer> c)
|
|
throws InstantiationException, IllegalAccessException {
|
|
Transformer transformer = clazz.getDeclaredConstructor().newInstance()
|
|
if (c != null) {
|
|
c.execute(transformer)
|
|
}
|
|
transformers.add(transformer)
|
|
this
|
|
}
|
|
|
|
/**
|
|
* Add a preconfigured transformer instance.
|
|
*
|
|
* @param transformer the transformer instance to add
|
|
* @return this
|
|
*/
|
|
@Override
|
|
ShadowJar transform(Transformer transformer) {
|
|
transformers.add(transformer)
|
|
this
|
|
}
|
|
|
|
/**
|
|
* Syntactic sugar for merging service files in JARs.
|
|
*
|
|
* @return this
|
|
*/
|
|
@Override
|
|
ShadowJar mergeServiceFiles() {
|
|
try {
|
|
transform(ServiceFileTransformer.class)
|
|
} catch (IllegalAccessException e) {
|
|
getLogger().log(LogLevel.ERROR, e.getMessage() as String, e)
|
|
} catch (InstantiationException e) {
|
|
getLogger().log(LogLevel.ERROR, e.getMessage() as String, e)
|
|
}
|
|
this
|
|
}
|
|
|
|
/**
|
|
* Syntactic sugar for merging service files in JARs.
|
|
*
|
|
* @return this
|
|
*/
|
|
@Override
|
|
ShadowJar mergeServiceFiles(String rootPath) {
|
|
try {
|
|
transform(ServiceFileTransformer.class, new Action<ServiceFileTransformer>() {
|
|
|
|
@Override
|
|
void execute(ServiceFileTransformer serviceFileTransformer) {
|
|
serviceFileTransformer.setPath(rootPath)
|
|
}
|
|
})
|
|
} catch (IllegalAccessException e) {
|
|
getLogger().log(LogLevel.ERROR, e.getMessage() as String, e)
|
|
} catch (InstantiationException e) {
|
|
getLogger().log(LogLevel.ERROR, e.getMessage() as String, e)
|
|
}
|
|
this
|
|
}
|
|
|
|
/**
|
|
* Syntactic sugar for merging service files in JARs.
|
|
*
|
|
* @return this
|
|
*/
|
|
@Override
|
|
ShadowJar mergeServiceFiles(Action<ServiceFileTransformer> configureClosure) {
|
|
try {
|
|
transform(ServiceFileTransformer.class, configureClosure)
|
|
} catch (IllegalAccessException e) {
|
|
getLogger().log(LogLevel.ERROR, e.getMessage() as String, e)
|
|
} catch (InstantiationException e) {
|
|
getLogger().log(LogLevel.ERROR, e.getMessage() as String, e)
|
|
}
|
|
this
|
|
}
|
|
|
|
/**
|
|
* Syntactic sugar for merging Groovy extension module descriptor files in JARs
|
|
*
|
|
* @return this
|
|
*/
|
|
@Override
|
|
ShadowJar mergeGroovyExtensionModules() {
|
|
try {
|
|
transform(GroovyExtensionModuleTransformer.class)
|
|
} catch (IllegalAccessException e) {
|
|
getLogger().log(LogLevel.ERROR, e.getMessage() as String, e)
|
|
} catch (InstantiationException e) {
|
|
getLogger().log(LogLevel.ERROR, e.getMessage() as String, e)
|
|
}
|
|
this
|
|
}
|
|
|
|
/**
|
|
* Syntactic sugar for merging service files in JARs
|
|
*
|
|
* @return this
|
|
*/
|
|
@Override
|
|
ShadowJar append(String resourcePath) {
|
|
try {
|
|
transform(AppendingTransformer.class, new Action<AppendingTransformer>() {
|
|
@Override
|
|
void execute(AppendingTransformer transformer) {
|
|
transformer.setResource(resourcePath)
|
|
}
|
|
})
|
|
} catch (IllegalAccessException e) {
|
|
getLogger().log(LogLevel.ERROR, e.getMessage() as String, e)
|
|
} catch (InstantiationException e) {
|
|
getLogger().log(LogLevel.ERROR, e.getMessage() as String, e)
|
|
}
|
|
return this
|
|
}
|
|
|
|
/**
|
|
* Add a class relocator that maps each class in the pattern to the provided destination.
|
|
*
|
|
* @param pattern the source pattern to relocate
|
|
* @param destination the destination package
|
|
* @return this
|
|
*/
|
|
@Override
|
|
ShadowJar relocate(String pattern, String destination) {
|
|
relocate(pattern, destination, null)
|
|
}
|
|
|
|
/**
|
|
* Add a class relocator that maps each class in the pattern to the provided destination.
|
|
*
|
|
* @param pattern the source pattern to relocate
|
|
* @param destination the destination package
|
|
* @param configure the configuration of the relocator
|
|
* @return this
|
|
*/
|
|
@Override
|
|
ShadowJar relocate(String pattern, String destination, Action<SimpleRelocator> configure) {
|
|
SimpleRelocator relocator = new SimpleRelocator(pattern, destination, new ArrayList<String>(), new ArrayList<String>());
|
|
if (configure != null) {
|
|
configure.execute(relocator)
|
|
}
|
|
relocators.add(relocator)
|
|
this
|
|
}
|
|
|
|
/**
|
|
* Add a relocator instance.
|
|
*
|
|
* @param relocator the relocator instance to add
|
|
* @return this
|
|
*/
|
|
@Override
|
|
ShadowJar relocate(Relocator relocator) {
|
|
relocators.add(relocator)
|
|
this
|
|
}
|
|
|
|
/**
|
|
* Add a relocator of the provided class.
|
|
*
|
|
* @param relocatorClass the relocator class to add. Must have a no-arg constructor.
|
|
* @return this
|
|
*/
|
|
@Override
|
|
ShadowJar relocate(Class<? extends Relocator> relocatorClass)
|
|
throws InstantiationException, IllegalAccessException {
|
|
relocate(relocatorClass, null)
|
|
}
|
|
|
|
/**
|
|
* Add a relocator of the provided class and configure.
|
|
*
|
|
* @param relocatorClass the relocator class to add. Must have a no-arg constructor
|
|
* @param configure the configuration for the relocator
|
|
* @return this
|
|
*/
|
|
@Override
|
|
ShadowJar relocate(Class<? extends Relocator> relocatorClass, Action<? extends Relocator> configure)
|
|
throws InstantiationException, IllegalAccessException {
|
|
Relocator relocator = relocatorClass.getDeclaredConstructor().newInstance()
|
|
if (configure != null) {
|
|
configure.execute(relocator)
|
|
}
|
|
relocators.add(relocator)
|
|
this
|
|
}
|
|
|
|
@Internal
|
|
List<Transformer> getTransformers() {
|
|
return this.transformers
|
|
}
|
|
|
|
void setTransformers(List<Transformer> transformers) {
|
|
this.transformers = transformers
|
|
}
|
|
|
|
@Internal
|
|
List<Relocator> getRelocators() {
|
|
return this.relocators
|
|
}
|
|
|
|
void setRelocators(List<Relocator> relocators) {
|
|
this.relocators = relocators
|
|
}
|
|
|
|
@InputFiles @Optional
|
|
List<Configuration> getConfigurations() {
|
|
this.configurations
|
|
}
|
|
|
|
void setConfigurations(List<Configuration> configurations) {
|
|
this.configurations = configurations
|
|
}
|
|
|
|
@Internal
|
|
DependencyFilter getDependencyFilter() {
|
|
return this.dependencyFilter
|
|
}
|
|
|
|
void setDependencyFilter(DependencyFilter filter) {
|
|
this.dependencyFilter = filter
|
|
}
|
|
}
|