diff --git a/let-plugin/src/main/groovy/com/canelmas/let/LetPlugin.groovy b/let-plugin/src/main/groovy/com/canelmas/let/LetPlugin.groovy index ca4e0ca..c8a8ad2 100644 --- a/let-plugin/src/main/groovy/com/canelmas/let/LetPlugin.groovy +++ b/let-plugin/src/main/groovy/com/canelmas/let/LetPlugin.groovy @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 Can Elmas + * Copyright (C) 2017 Can Elmas * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,71 +18,32 @@ package com.canelmas.let import com.android.build.gradle.AppPlugin import com.android.build.gradle.LibraryPlugin -import org.aspectj.bridge.IMessage -import org.aspectj.bridge.MessageHandler -import org.aspectj.tools.ajc.Main import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.api.tasks.compile.JavaCompile class LetPlugin implements Plugin { - @Override void apply(Project project) { - def hasApp = project.plugins.withType(AppPlugin) - def hasLib = project.plugins.withType(LibraryPlugin) - if (!hasApp && !hasLib) { - throw new IllegalStateException("'android' or 'android-library' plugin required.") - } + @Override + void apply(Project project) { - final def log = project.logger - final def variants - if (hasApp) { - variants = project.android.applicationVariants - } else { - variants = project.android.libraryVariants - } + makeSureProjectIsAndroidAppOrLib(project) + + project.android.registerTransform(new LetTransform(project)) project.dependencies { - implementation 'org.aspectj:aspectjrt:1.8.10' + implementation 'org.aspectj:aspectjrt:1.8.9' implementation 'com.canelmas.let:let-runtime:1.0.0-beta1' implementation 'com.canelmas.let:let-annotations:1.0.0-beta1' } + } - variants.all { variant -> - JavaCompile javaCompile = variant.javaCompile - javaCompile.doLast { - String[] args = [ - "-showWeaveInfo", - "-1.5", - "-inpath", javaCompile.destinationDir.toString(), - "-aspectpath", javaCompile.classpath.asPath, - "-d", javaCompile.destinationDir.toString(), - "-classpath", javaCompile.classpath.asPath, - "-bootclasspath", project.android.bootClasspath.join(File.pathSeparator) - ] - log.debug "ajc args: " + Arrays.toString(args) + private void makeSureProjectIsAndroidAppOrLib(Project project) { + def hasApp = project.plugins.withType(AppPlugin) + def hasLib = project.plugins.withType(LibraryPlugin) - MessageHandler handler = new MessageHandler(true); - new Main().run(args, handler); - for (IMessage message : handler.getMessages(null, true)) { - switch (message.getKind()) { - case IMessage.ABORT: - case IMessage.ERROR: - case IMessage.FAIL: - log.error message.message, message.thrown - break; - case IMessage.WARNING: - log.warn message.message, message.thrown - break; - case IMessage.INFO: - log.info message.message, message.thrown - break; - case IMessage.DEBUG: - log.debug message.message, message.thrown - break; - } - } - } + if (!hasApp && !hasLib) { + throw new IllegalStateException("'android' or 'android-library' plugin required.") } } + } \ No newline at end of file diff --git a/let-plugin/src/main/groovy/com/canelmas/let/LetTransform.groovy b/let-plugin/src/main/groovy/com/canelmas/let/LetTransform.groovy new file mode 100644 index 0000000..d664380 --- /dev/null +++ b/let-plugin/src/main/groovy/com/canelmas/let/LetTransform.groovy @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2017 Can Elmas + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.canelmas.let + +import com.android.annotations.NonNull +import com.android.build.api.transform.* +import com.google.common.base.Joiner +import com.google.common.base.Strings +import com.google.common.collect.Lists +import com.google.common.collect.Sets +import org.aspectj.bridge.IMessage +import org.aspectj.bridge.MessageHandler +import org.aspectj.tools.ajc.Main +import org.gradle.api.GradleException +import org.gradle.api.Project +import org.gradle.api.logging.Logger + +class LetTransform extends Transform { + + private Project project + + LetTransform(Project project) { + this.project = project + } + + @Override + void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException { + + List files = Lists.newArrayList() + List classpathFiles = Lists.newArrayList() + Logger logger = project.logger + + TransformOutputProvider outputProvider = transformInvocation.getOutputProvider() + + // clean + outputProvider.deleteAll() + + // Referenced Inputs to classpath + for (TransformInput input : transformInvocation.getReferencedInputs()) { + input.directoryInputs.each { + classpathFiles.add(it.file) + } + + input.jarInputs.each { + classpathFiles.add(it.file) + } + } + + // Scope inputs + for (TransformInput input : transformInvocation.getInputs()) { + + for (DirectoryInput folder : input.directoryInputs) { + files.add(folder.file) + } + + for (JarInput jar : input.jarInputs) { + files.add(jar.file) + } + } + + // Evaluate class paths + final String inpath = Joiner.on(File.pathSeparator).join(files) + final String classpath = Joiner.on(File.pathSeparator).join( + classpathFiles.collect { it.absolutePath }) + final String bootpath = Joiner.on(File.pathSeparator).join(project.android.bootClasspath) + final File output = outputProvider.getContentLocation("main", outputTypes, Sets.immutableEnumSet(QualifiedContent.Scope.PROJECT), Format.DIRECTORY) + + // Weaving args + def args = [ + "-source", "1.6", + "-target", "1.6", + "-showWeaveInfo", + "-inpath", inpath, + "-d", output.absolutePath, + "-bootclasspath", bootpath] + + // Append classpath argument if any + if (!Strings.isNullOrEmpty(classpath)) { + args << '-classpath' + args << classpath + } + + // run aspectj + MessageHandler handler = new MessageHandler(true) + new Main().run(args as String[], handler) + + for (IMessage message : handler.getMessages(null, true)) { + + if (IMessage.ERROR.isSameOrLessThan(message.kind)) { + logger.error(message.message, message.thrown) + throw new GradleException(message.message, message.thrown) + } else if (IMessage.WARNING.isSameOrLessThan(message.kind)) { + logger.warn message.message + } else if (IMessage.DEBUG.isSameOrLessThan(message.kind)) { + logger.info message.message + } else { + logger.debug message.message + } + } + + } + + @NonNull + @Override + String getName() { + "let" + } + + @NonNull + @Override + Set getInputTypes() { + return Sets.immutableEnumSet(QualifiedContent.DefaultContentType.CLASSES) + } + + @NonNull + @Override + Set getScopes() { + return Sets.immutableEnumSet(QualifiedContent.Scope.PROJECT, + QualifiedContent.Scope.EXTERNAL_LIBRARIES) + } + + @Override + Set getReferencedScopes() { + return Sets.immutableEnumSet( + QualifiedContent.Scope.SUB_PROJECTS, + QualifiedContent.Scope.EXTERNAL_LIBRARIES, + QualifiedContent.Scope.PROVIDED_ONLY + ) + } + + @Override + boolean isIncremental() { + false + } + +} \ No newline at end of file