2013-09-03 7 views
16

मैं प्लगइन लिखने की कोशिश कर रहा हूं जो प्लगइन एक्सटेंशन ऑब्जेक्ट में एकत्रित सूचनाओं के अनुसार project.dependencies पर निर्भरता जोड़ता है। लेकिन ऐसा असंभव प्रतीत होता है।ग्रैडल कस्टम प्लगइन: एक्सटेंशन ऑब्जेक्ट से निर्भरता जोड़ें

वास्तव में, एक्सटेंशन ऑब्जेक्ट का डेटा केवल एक नए कार्य में उपलब्ध है या project.afterEvaluate बंद में है, लेकिन उन स्थानों में जोड़े गए निर्भरताओं को अनदेखा कर दिया जाता है।


निम्नलिखित कोड afterEvaluate में निर्भरता को जोड़ने के लिए कोशिश करता है लेकिन निर्भरता को नजरअंदाज कर दिया जाता है:

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 
} 

निम्न कोड में निर्भरता इंजेक्शन काम करता है, लेकिन मैं करने के लिए पहुँच नहीं है एक्सटेंशन ऑब्जेक्ट:

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 
} 

क्या कोई समाधान है? अगर है कि अभी भी प्रासंगिक है

+1

आप विस्तार तक पहुँचने, एक ही रास्ता या किसी अन्य रूप में स्थगित करना होगा। यह मुझे स्पष्ट नहीं है कि 'project.afterEvalalu' में निर्भरता जोड़ने क्यों काम नहीं करेगा। प्लगइन का उपयोग करने वाले कोड के साथ समस्या हो सकती है। –

+0

धन्यवाद, मैंने स्पष्ट रहने के लिए कोड को सरल बना दिया है, आप संपूर्ण कोड [यहां] (https://github.com/tbruyelle/ResetUnreadSms/blob/aa-plugin/build.gradle) पा सकते हैं। यह पुस्तकालय के लिए एक एंड्रॉइड प्लगइन है जो एनोटेशन से जावा कक्षाएं उत्पन्न करता है। प्लगइन एक्सटेंशन ऑब्जेक्ट्स के बिना अच्छी तरह से काम करता है, लेकिन अगर मैं विस्तार वस्तुओं से डेटा के साथ निर्भरता इंजेक्ट करना चाहता हूं तो विफल रहता है, जैसा कि प्रश्न में बताया गया है। – tbruyelle

+0

सीसी @ पीटर Niederwieser अगर आपको मेरे उत्तर से अधिसूचित नहीं किया गया है ... – tbruyelle

उत्तर

1

पता नहीं है, लेकिन आप स्पष्ट रूप से doFirst में जावा classpath के लिए अपने संकलन कॉन्फ़िगरेशन जोड़कर इस समाधान कर सकते हैं:

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

अद्यतन: मैं अपने मूल के बाद से यह पता लगा करने में कामयाब जवाब। ऐसा तरीका है DependencyResolutionListener जिसमें आप निर्भरता जोड़ते हैं और फिर श्रोता को हटाते हैं, इसलिए यह उन्हें बाद के संकल्प चरणों में जोड़ने का प्रयास नहीं करता है। ।

यह भी देर लेकिन में छोड़ने नवीनतम Gradle के साथ किसी को भी (2.6 के लिए है:

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) {} 
}) 

मैं इस here

मूल उत्तर का उपयोग करता है एक प्लगइन की एक काम उदाहरण है लेखन का समय), आप DependencyResolutionListener जोड़ सकते हैं और निर्भरताओं को हल करने से पहले कोई निर्भरता जोड़ सकते हैं।

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) { 

    } 
}) 

हालांकि, इस लेखन के रूप में मुझे एंड्रॉइड स्टूडियो आईडीई के साथ काम करने में कुछ समस्याएं आईं। समस्या मेरे प्रश्न here

3

में ट्रैक की गई है, मैंने मूल रूप से साद द्वारा DependencyResolutionListener दृष्टिकोण का उपयोग करके इस समाधान को लागू किया था। हालांकि, श्रोता को खुद को only when something iterates over the configuration associated with the dependency कहा जाता है। उदाहरण के लिए, आप गतिशील compile करने के लिए एक निर्भरता जोड़ना चाहते हैं, तो आप यह सुनिश्चित करें कि कुछ बाद में की तरह कुछ करता है बनाने के लिए है:

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

लेकिन चूंकि compile एक है यह कुछ ऐसा है पाठ्यक्रम के एक मामले के रूप में होता है, जावा प्लगइन का उपयोग करने वाली किसी भी परियोजना के लिए ज्ञात कॉन्फ़िगरेशन। हालांकि, यदि आप एक कस्टम कॉन्फ़िगरेशन (जैसा कि मैं था) का उपयोग कर रहा हूं, तो श्रोता दृष्टिकोण तब तक काम नहीं करेगा जब तक आप स्पष्ट रूप से अपनी कस्टम कॉन्फ़िगरेशन पर पुन: प्रयास नहीं करते।

मैं इसे करने के लिए एक बेहतर तरीका खोजने में सक्षम था, और afterEvaluate के भीतर ओपी मूल रूप से चाहता था।मैं एक कस्टम विन्यास यहाँ उपयोग कर रहा हूँ, लेकिन मैं एक कारण नहीं दिख रहा है यही कारण है कि इसके लिए compile या तो काम नहीं होगा:

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

बेशक, कुछ बिंदु कुछ पर अभी भी उनके लिए निर्भरता से अधिक पुनरावृति करना पड़ता है वास्तव में हल करने के लिए।

0

सबसे आसान तरीका है यह करने के लिए:

project.dependencies { 
    delegate.compile("com.android.support:appcompat-v7:25.0.1") 
} 
संबंधित मुद्दे