Как написать метод расширения для блока Gradle зависимости {} - PullRequest
0 голосов
/ 11 сентября 2018

Я пытаюсь написать методы расширения для DependencyHandler.Одна из основных целей - автозаполнение этих методов.

Итак, я написал функцию расширения в проекте buildSrc следующим образом (Shortcuts.kt):

fun DependencyHandler.autoValue() {
    add("compileOnly", Libs.Auto.autoValueAnnotations)
    add("annotationProcessor", Libs.Auto.autoValueCompiler)
}

И зарегистрировал ее как модуль расширения, как описано здесь :

# File: src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule
moduleName = buildSrc
moduleVersion = 1.0
extensionClasses = com.example.test.ShortcutsKt

Я хочу использовать эти методы в build.gradle файлах, таких как:

dependencies {
    ...
    autoValue()
}

Появляется в списке автозаполнения внутри блока dependencies{},но во время настройки я получил ошибку:

org.gradle.internal.metaobject.AbstractDynamicObject$CustomMessageMissingMethodException: Could not find method autoValue() for arguments [] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
    at org.gradle.internal.metaobject.AbstractDynamicObject.methodMissingException(AbstractDynamicObject.java:179)
    at org.gradle.internal.metaobject.ConfigureDelegate.invokeMethod(ConfigureDelegate.java:87)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeOnDelegationObjects(ClosureMetaClass.java:430)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:369)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:69)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:158)
    at build_dh4v5lw1dkt4b2nii5ope5rmy$_run_closure1.doCall(/.../app/build.gradle:29)

1 Ответ

0 голосов
/ 11 сентября 2018

Gradle DefaultDependencyHandler реализует стратегию разрешения пользовательских методов (для обработки обозначений областей, таких как testCompile(smth)), поэтому дополнительные методы могут быть добавлены через свойство dependencies.ext:

dependencies.ext.autoValue = {
    dependencies.add("compileOnly", Libs.Auto.autoValueAnnotations)
    dependencies.add("annotationProcessor", Libs.Auto.autoValueCompiler)
}

Но в этом случае вы этого не сделаетеполучить автозаполнение.

Чтобы включить автозаполнение, вы можете смешать эти два подхода и методы расширения прокси из buildSrc через dependencies.ext:

import com.example.test.ShortcutsKt

import java.lang.reflect.Method
import java.lang.reflect.Modifier

// DependencyHandler implementation resolves all undeclared methods by self,
// so we need to add these extension methods to dependencies.ext
def methodNames = ShortcutsKt.declaredMethods
        .findAll { isDependencyHandlerExtension(it) }
        .collect { it.name }
        .unique()

methodNames.each { String methodName ->
    dependencies.ext[methodName] = { Object... args ->
        ShortcutsKt."$methodName"(dependencies, *args)
    }
}

private static boolean isDependencyHandlerExtension(Method method) {
    return Modifier.isPublic(method.getModifiers()) &&
            Modifier.isStatic(method.getModifiers()) &&
            method.parameterCount > 0 &&
            method.parameterTypes[0] == DependencyHandler.class
}
...