2013-09-03 20 views
16

Próbuję napisać wtyczkę, która dodaje zależności do project.dependencies zgodnie z informacjami zebranymi w obiekcie rozszerzenia wtyczki. Ale wydaje się to niemożliwe.Wtyczka niestandardowa Gradle: dodaj zależność od obiektu rozszerzenia

Rzeczywiście dane z obiektu rozszerzenia są dostępne tylko w nowym zadaniu lub w zamknięciu project.afterEvaluate, ale zależności dodane w tych miejscach są ignorowane.


Poniższy kod próbuje dodać zależność w afterEvaluate ale zależność jest ignorowane:

apply plugin: MyPlugin 

myplugin { 
    version '1.0' 
} 

class MyPlugin implements Plugin<Project> { 
    void apply(Project project) { 
    project.extensions.create('myplugin', MyPluginExtension) 

    project.afterEvaluate { 
     def version = project.myplugin.version 
     project.dependencies.add("compile", "org.foo:bar:$version") // --> ignored 
    } 
    } 
} 

class MyPluginExtension { 
    def version 
} 

W poniższym kodzie prace wstrzykiwania zależności, ale nie mam dostępu do obiekt rozszerzenia:

apply plugin: MyPlugin 

myplugin { 
    version '1.0' 
} 

class MyPlugin implements Plugin<Project> { 
    void apply(Project project) { 
    project.extensions.create('myplugin', MyPluginExtension)  

    def version = project.myplugin.version // == null 
    project.dependencies.add("compile", "org.foo:bar:$version") // --> fail because $version is null 

    } 
} 

class MyPluginExtension { 
    def version 
} 

Czy istnieje rozwiązanie?

+1

Będziesz musiał odroczyć dostęp do rozszerzenia, w taki czy inny sposób. Nie jest dla mnie jasne, dlaczego dodanie zależności w 'project.afterEvaluate' nie zadziałałoby. Może to być problem z kodem korzystającym z wtyczki. –

+0

Dzięki, uprościłem kod, aby zachować jasność, możesz znaleźć cały kod [tutaj] (https://github.com/tbruyelle/ResetUnreadSms/blob/aa-plugin/build.gradle). Jest to wtyczka do Androida dla biblioteki, która generuje klasy java z adnotacji. Wtyczka działa dobrze bez obiektów rozszerzeń, ale kończy się niepowodzeniem, jeśli chcę wstrzyknąć zależności z danymi z obiektów rozszerzeń, jak wyjaśniono w pytaniu. – tbruyelle

+0

cc @PeterNiederwieser w przypadku, gdy moja odpowiedź nie została powiadomiona ... – tbruyelle

Odpowiedz

1

Nie wiem, czy to nadal aktualne, ale można obejść ten jawnie dodając konfigurację kompilacji do ścieżki klasy Java w doFirst:

variant.javaCompile.doFirst { 
    variant.javaCompile.classpath += project.configurations.myconfiguration 
} 
13

Aktualizacja: udało mi się dowiedzieć się tego od mojego oryginału odpowiedź. W tym celu należy dodać DependencyResolutionListener, w którym dodaje się zależności, a następnie usunąć obiekt nasłuchujący, aby nie był on dodawany w późniejszych etapach rozwiązywania problemów.

compileDeps = project.getConfigurations().getByName("compile").getDependencies() 
project.getGradle().addListener(new DependencyResolutionListener() { 
    @Override 
    void beforeResolve(ResolvableDependencies resolvableDependencies) { 
     compileDeps.add(project.getDependencies().create("org.foo:bar:$version")) 
     project.getGradle().removeListener(this) 
    } 

    @Override 
    void afterResolve(ResolvableDependencies resolvableDependencies) {} 
}) 

Mam przykład roboczy plugin, który wykorzystuje tę here

oryginalny odpowiedź:

to też późno, ale dla każdego, kto spada w Z najnowszych Gradle (2.6 u. czas pisania), można dodać DependencyResolutionListener i dodać wszelkie zależności przed rozwiązaniem zależności.

project.getGradle().addListener(new DependencyResolutionListener() { 
    @Override 
    void beforeResolve(ResolvableDependencies resolvableDependencies) { 
     depsToAdd.each { dep -> 
      compileConfig.getDependencies() 
       .add(project.getDependencies().create(dep)) 
     } 
    } 

    @Override 
    void afterResolve(ResolvableDependencies resolvableDependencies) { 

    } 
}) 

Jednakże, jak to pisze miałem pewne problemy z dostaniem tego, aby współpracować z systemem Android Studio IDE. Problem jest śledzony w moim pytaniu: here

3

Pierwotnie zaimplementowałem to rozwiązanie, korzystając z metody Saad w ramach metody DependencyResolutionListener. Jednak sam słuchacz nazywa się only when something iterates over the configuration associated with the dependency. Na przykład, jeśli chcesz, aby dynamicznie dodać zależność do compile, trzeba upewnić się, że coś później robi coś takiego:

project.configurations.compile.each { 
    ... 
} 

Ale to jest coś, co się dzieje, jak oczywistością, ponieważ compile jest znana konfiguracja dla dowolnego projektu korzystającego z wtyczki java. Jeśli jednak używasz niestandardowej konfiguracji (tak jak ja), to podejście detektora nie zadziała, dopóki nie zostanie jawnie powtórzona konfiguracja niestandardowa.

Udało mi się znaleźć lepszy sposób na zrobienie tego, a także w ramach afterEvaluate, jak pierwotnie chciał OP.Używam niestandardową konfigurację tutaj, ale nie widzę powodu, dlaczego nie będzie działać dla compile albo:

project.afterEvaluate { 
    def version = project.myPlugin.version 
    project.configurations.myConfig.dependencies.add(
     project.dependencies.add("myConfig", "org.foo:bar:$version") 
    ) 
} 

Oczywiście, w pewnym momencie coś jeszcze do iteracyjne nad zależnościami dla nich faktycznie zostać rozwiązanym.

0

Najprostszym sposobem, aby to zrobić:

project.dependencies { 
    delegate.compile("com.android.support:appcompat-v7:25.0.1") 
} 
Powiązane problemy