@@ -7,6 +7,13 @@ import org.gradle.api.file.DirectoryProperty
77import org.gradle.api.invocation.BuildInvocationDetails
88import org.gradle.api.provider.ListProperty
99import org.gradle.api.provider.Property
10+ import org.gradle.api.tasks.Classpath
11+ import org.gradle.api.tasks.Input
12+ import org.gradle.api.tasks.InputDirectory
13+ import org.gradle.api.tasks.InputFiles
14+ import org.gradle.api.tasks.Optional
15+ import org.gradle.api.tasks.OutputDirectory
16+ import org.gradle.api.tasks.TaskAction
1017import org.gradle.api.tasks.compile.AbstractCompile
1118import org.gradle.jvm.toolchain.JavaLanguageVersion
1219import org.gradle.jvm.toolchain.JavaToolchainService
@@ -20,8 +27,8 @@ import java.util.regex.Matcher
2027/**
2128 * instrument<Language> task plugin which performs build-time instrumentation of classes.
2229 */
30+ @SuppressWarnings (' unused' )
2331class InstrumentPlugin implements Plugin<Project > {
24-
2532 @Override
2633 void apply (Project project ) {
2734 InstrumentExtension extension = project. extensions. create(' instrument' , InstrumentExtension )
@@ -34,8 +41,8 @@ class InstrumentPlugin implements Plugin<Project> {
3441 Matcher versionMatcher = it. name =~ / compileMain_(.+)Java/
3542 project. afterEvaluate {
3643 if (! compileTask. source. empty) {
37- String sourceSetSuffix
38- String javaVersion
44+ String sourceSetSuffix = null
45+ String javaVersion = null
3946 if (versionMatcher. matches()) {
4047 sourceSetSuffix = versionMatcher. group(1 )
4148 if (sourceSetSuffix ==~ / java\d +/ ) {
@@ -51,14 +58,28 @@ class InstrumentPlugin implements Plugin<Project> {
5158
5259 // insert task between compile and jar, and before test*
5360 String instrumentTaskName = compileTask. name. replace(' compile' , ' instrument' )
54- def instrumentTask = project. task([' type' : InstrumentTask ], instrumentTaskName) {
55- description = " Instruments the classes compiled by ${ compileTask.name} "
56- doLast {
57- instrument(javaVersion, project, extension, rawClassesDir, classesDir, it)
61+ def instrumentTask = project. tasks. register(instrumentTaskName, InstrumentTask ) {
62+ // Task configuration
63+ it. group = ' Byte Buddy'
64+ it. description = " Instruments the classes compiled by ${ compileTask.name} "
65+ it. inputs. dir(compileTask. destinationDirectory)
66+ it. outputs. dir(classesDir)
67+ // Task inputs
68+ it. javaVersion = javaVersion
69+ def instrumenterConfiguration = project. configurations. named(' instrumentPluginClasspath' )
70+ if (instrumenterConfiguration. present) {
71+ it. pluginClassPath. from(instrumenterConfiguration. get())
5872 }
73+ it. plugins = extension. plugins
74+ it. instrumentingClassPath. from(
75+ findCompileClassPath(project, it. name) +
76+ rawClassesDir +
77+ findAdditionalClassPath(extension, it. name)
78+ )
79+ it. sourceDirectory = rawClassesDir
80+ // Task output
81+ it. targetDirectory = classesDir
5982 }
60- instrumentTask. inputs. dir(compileTask. destinationDirectory)
61- instrumentTask. outputs. dir(classesDir)
6283 if (javaVersion) {
6384 project. tasks. named(project. sourceSets. " main_java${ javaVersion} " . classesTaskName) {
6485 it. dependsOn(instrumentTask)
@@ -72,6 +93,22 @@ class InstrumentPlugin implements Plugin<Project> {
7293 }
7394 }
7495 }
96+
97+ static findCompileClassPath (Project project , String taskName ) {
98+ def matcher = taskName =~ / instrument([A-Z].+)Java/
99+ def cfgName = matcher. matches() ? " ${ matcher.group(1).uncapitalize()} CompileClasspath" : ' compileClasspath'
100+ project. configurations. named(cfgName). findAll {
101+ it. name != ' previous-compilation-data.bin' && ! it. name. endsWith(' .gz' )
102+ }
103+ }
104+
105+ static findAdditionalClassPath (InstrumentExtension extension , String taskName ) {
106+ extension. additionalClasspath. getOrDefault(taskName, []). collect {
107+ // insert intermediate 'raw' directory for unprocessed classes
108+ def fileName = it. get(). asFile. name
109+ it. get(). dir(" ../${ fileName.replaceFirst('^main', 'raw')} " )
110+ }
111+ }
75112}
76113
77114abstract class InstrumentExtension {
@@ -80,53 +117,51 @@ abstract class InstrumentExtension {
80117}
81118
82119abstract class InstrumentTask extends DefaultTask {
83- {
84- group = ' Byte Buddy'
85- }
120+ @Input @Optional
121+ String javaVersion
122+ @InputFiles @Classpath
123+ abstract ConfigurableFileCollection getPluginClassPath ()
124+ @Input
125+ ListProperty<String > plugins
126+ @InputFiles @Classpath
127+ abstract ConfigurableFileCollection getInstrumentingClassPath ()
128+ @InputDirectory
129+ Directory sourceDirectory
130+
131+ @OutputDirectory
132+ Directory targetDirectory
86133
87134 @Inject
88135 abstract JavaToolchainService getJavaToolchainService ()
89-
90136 @Inject
91137 abstract BuildInvocationDetails getInvocationDetails ()
92-
93138 @Inject
94139 abstract WorkerExecutor getWorkerExecutor ()
95140
96- void instrument (String javaVersion ,
97- Project project ,
98- InstrumentExtension extension ,
99- Directory sourceDirectory ,
100- Directory targetDirectory ,
101- InstrumentTask instrumentTask )
102- {
103- def workQueue = getWorkQueueFor(javaVersion)
104- workQueue. submit(InstrumentAction . class, parameters -> {
105- parameters. buildStartedTime. set(invocationDetails. buildStartedTime)
106- parameters. pluginClassPath. setFrom(project. configurations. findByName(' instrumentPluginClasspath' ) ?: [])
107- parameters. plugins. set(extension. plugins)
108- def matcher = instrumentTask. name =~ / instrument([A-Z].+)Java/
109- def cfgName = matcher. matches() ? " ${ matcher.group(1).uncapitalize()} CompileClasspath" : ' compileClasspath'
110- parameters. instrumentingClassPath. setFrom(project. configurations[cfgName]. findAll {
111- it. name != ' previous-compilation-data.bin' && ! it. name. endsWith(" .gz" )
112- } + sourceDirectory + (extension. additionalClasspath[instrumentTask. name] ?: [])* . get())
113- parameters. sourceDirectory. set(sourceDirectory. asFile)
114- parameters. targetDirectory. set(targetDirectory. asFile)
141+ @TaskAction
142+ instrument () {
143+ workQueue(). submit(InstrumentAction . class, parameters -> {
144+ parameters. buildStartedTime. set(this . invocationDetails. buildStartedTime)
145+ parameters. pluginClassPath. from(this . pluginClassPath)
146+ parameters. plugins. set(this . plugins)
147+ parameters. instrumentingClassPath. setFrom(this . instrumentingClassPath)
148+ parameters. sourceDirectory. set(this . sourceDirectory. asFile)
149+ parameters. targetDirectory. set(this . targetDirectory. asFile)
115150 })
116151 }
117152
118- private getWorkQueueFor ( String javaVersion ) {
119- if (javaVersion) {
120- def javaLauncher = javaToolchainService. launcherFor { spec ->
121- spec. languageVersion. set(JavaLanguageVersion . of(javaVersion))
153+ private workQueue ( ) {
154+ if (this . javaVersion) {
155+ def javaLauncher = this . javaToolchainService. launcherFor { spec ->
156+ spec. languageVersion. set(JavaLanguageVersion . of(this . javaVersion))
122157 }. get()
123- return workerExecutor. processIsolation { spec ->
158+ return this . workerExecutor. processIsolation { spec ->
124159 spec. forkOptions { fork ->
125160 fork. executable = javaLauncher. executablePath
126161 }
127162 }
128163 } else {
129- return workerExecutor. noIsolation()
164+ return this . workerExecutor. noIsolation()
130165 }
131166 }
132167}
0 commit comments