बिल्ड.ग्रेडल में कस्टम तरीकों को कैसे परिभाषित करें और कॉल करें


79

मेरी परियोजना के हिस्से के रूप में, मुझे एक निर्देशिका से फाइल पढ़ने और इन स्क्रिप्ट के निर्माण में कुछ ऑपरेशन करने की आवश्यकता है। प्रत्येक फ़ाइल के लिए, ऑपरेशन समान है (कुछ एसक्यूएल प्रश्नों को पढ़ने और इसे निष्पादित करें)। मुझे लगता है कि इसका दोहराव कार्य और एक विधि के अंदर लिखना बेहतर है। चूंकि मैं पदच्युत करने के लिए नया हूं, मुझे नहीं पता कि यह कैसा होना चाहिए। कृपया मदद करे।


जवाबों:


109

नीचे दिया गया एक तरीका:

ext.myMethod = { param1, param2 ->
    // Method body here
}

ध्यान दें कि यह प्रोजेक्ट स्कोप के लिए बनाया गया है, अर्थात। परियोजना के लिए वैश्विक रूप से उपलब्ध है, जिसे बिल्ड स्क्रिप्ट में कहीं भी निम्नानुसार लागू किया जा सकता है, जिसके myMethod(p1, p2)समान हैproject.myMethod(p1, p2)

विधि को अलग-अलग स्कोप के तहत परिभाषित किया जा सकता है, जैसे कि कार्यों के भीतर:

task myTask {
    ext.myMethod = { param1, param2 ->
        // Method body here
    }

    doLast {
        myMethod(p1, p2) // This will resolve 'myMethod' defined in task
    }
}

एक और संदेह। क्या मैं कार्य करने के लिए एक विधि को चिह्नित कर सकता हूँ? ext.myMethod इसे वैश्विक रूप में चिह्नित करेगा।
टॉमिन

3
जब हम उपयोग करते हैं ext, तो गुंजाइश सीमित है जहां इसे परिभाषित किया गया है, अर्थात। यदि इसे किसी कार्य के तहत परिभाषित किया गया है, तो यह कार्य के लिए स्थानीय है। जिस तरह से यह काम करता है वह संस्थाओं (जैसे परियोजना, कार्य आदि) के माध्यम से होता है जो ExtensionAware को लागू करता है । यह एक एक्स्ट्राप्रोटेक्ट्स एक्स्टेंशन जोड़ता है जिसे extनिर्देश के माध्यम से कॉन्फ़िगर किया गया है ।
अदृश्य तीर

तो इसका मतलब है कि मैं बिना किसी संघर्ष के एक ही विधि का नाम अलग-अलग कार्यों में उपयोग कर सकता हूं। अर्थात; ext.myMethod दो या अधिक कार्यों में काम करना चाहिए।
टॉमिन

1
जब एक उप-परियोजना से पहुंच हो, तो rootProject.ext.myMethod (p1, P2) के रूप में एक्सेस किया जा सकता है
फिलिप

30

यदि आपने किसी अन्य फ़ाइल में किसी भी तरीके को परिभाषित किया है * .ग्रेडल - ext.method () यह सुलभ प्रोजेक्ट को व्यापक बनाता है। उदाहरण के लिए यहाँ एक है

versioning.gradle

// ext makes method callable project wide
ext.getVersionName = { ->
    try {
        def branchout = new ByteArrayOutputStream()
        exec {
            commandLine 'git', 'rev-parse', '--abbrev-ref', 'HEAD'
            standardOutput = branchout
        }
        def branch = branchout.toString().trim()

        if (branch.equals("master")) {
            def stdout = new ByteArrayOutputStream()
            exec {
                commandLine 'git', 'describe', '--tags'
                standardOutput = stdout
            }
            return stdout.toString().trim()
        } else {
            return branch;
        }
    }
    catch (ignored) {
        return null;
    }
}

build.gradle

task showVersion << {
    // Use inherited method
    println 'VersionName: ' + getVersionName()
}

Ext.method () प्रारूप के बिना, विधि केवल * .gradle फ़ाइल के भीतर ही उपलब्ध होगी। गुणों के साथ भी ऐसा ही है।


27

आप निम्न तरीके से तरीकों को परिभाषित कर सकते हैं:

// Define an extra property
ext.srcDirName = 'src/java'

// Define a method
def getSrcDir(project) {
    return project.file(srcDirName)
}

आप ढाल प्रलेखन अध्याय 62 में अधिक विवरण पा सकते हैं । बिल्ड लॉजिक का आयोजन


1
मैंने यह कोशिश की, हालाँकि मैं जो विधि बना रहा हूं, वह मेरे द्वारा चलाए जा रहे प्रत्येक कार्य पर निष्पादित की जाती है, उदाहरण के लिए जब चलाने की कोशिश की जा रही हो ।/gradlew क्लीन - मुझे लगता है कि विधि निष्पादित हो रही है और यह वह नहीं है जो मैं चाहता हूं - क्या आप जानते हैं कि क्या हो सकता है समस्या हो?
user1002065

@ user1002065 अपने सेटअप को देखे बिना बताना मुश्किल है, अगर आप कृपया साझा कर सकते हैं (यानी एक जिस्ट के रूप में), तो मैं मदद करने की कोशिश कर सकता हूं
इवान मारिनोव

11

एक रूट ऑब्जेक्ट वाली विधि के साथ एक उदाहरण।

hg.gradle फ़ाइल:

ext.hg = [

    cloneOrPull: { source, dest, branch ->
        if (!dest.isDirectory())
            hg.clone(source, dest, branch)
        else
            hg.pull(dest)
        hg.update(dest, branch)
    },

    clone: { source, dest, branch ->
        dest.mkdirs()
        exec {
            commandLine 'hg', 'clone', '--noupdate', source, dest.absolutePath
        }
    },

    pull: { dest ->
        exec {
            workingDir dest.absolutePath
            commandLine 'hg', 'pull'
        }
    },

]

build.gradle फ़ाइल

apply from: 'hg.gradle'

hg.clone('path/to/repo')

3

किसी तरह, शायद क्योंकि यह ओपी से पांच साल है, लेकिन कोई भी नहीं

ext.someMethod = { foo ->
   methodBody
}

मेरे लिए काम कर रहे हैं। इसके बजाय, एक साधारण फ़ंक्शन की परिभाषा को मेरी ग्रेडल फ़ाइल में काम मिल रहा है:

def retrieveEnvvar(String envvar_name) {
    if ( System.getenv(envvar_name) == "" ) {
        throw new InvalidUserDataException("\n\n\nPlease specify environment variable ${envvar_name}\n")
    } else {
        return System.getenv(envvar_name)
    }       
}

और मैं इसे अपनी स्क्रिप्ट में कहीं और नहीं उपसर्ग के साथ कहता हूं, अर्थात retrieveEnvvar("APP_PASSWORD")

यह 2020 है इसलिए मैं ग्रैडल 6.1.1 का उपयोग कर रहा हूं।


मैं भी ६.१.१ पर हूँ, ex.someMethod = {} ठीक काम करता है। बस यह कि मैं लंबोदर को बुलाते समय परम नामों का उपयोग नहीं कर सकता था।
rpattabi

0

@ether_joe @InvisibleArrow द्वारा जवाब शीर्ष मतदान ऊपर करता है काम हालांकि आप विधि आप कॉल को परिभाषित करना होगा इससे पहले कि आप इसे कहते हैं - यानी में पहले build.gradleफ़ाइल।

आप यहां एक उदाहरण देख सकते हैं । मैंने ग्रेडल 6.5 के साथ इस दृष्टिकोण का उपयोग किया है और यह काम करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.