ग्रैड बिल्ड स्क्रिप्ट से सामान्य तरीके निकालें


85

मेरे पास ग्रैड बिल्ड स्क्रिप्ट ( build.gradle) है, जिसमें मैंने कुछ कार्य बनाए हैं। इन कार्यों में अधिकतर विधि कॉल शामिल हैं। निर्मित विधियाँ निर्माण लिपि में भी हैं।

अब, यहाँ की स्थिति है:

मैं उचित स्क्रिप्ट का निर्माण कर रहा हूं, जिसमें विभिन्न कार्य हैं, लेकिन मूल स्क्रिप्ट से समान विधियों का उपयोग करें। इस प्रकार, मैं इन "सामान्य तरीकों" को किसी तरह से निकालना चाहूंगा, इसलिए मैं आसानी से उनके द्वारा बनाई गई प्रत्येक नई स्क्रिप्ट की प्रतिलिपि बनाने के बजाय उन्हें फिर से उपयोग कर सकता हूं।

यदि ग्रेडल PHP थे, तो निम्नलिखित जैसा कुछ आदर्श होगा:

//script content
...
require("common-methods.gradle");
...
//more script content

लेकिन निश्चित रूप से, यह संभव नहीं है। या यह है?

वैसे भी, मैं इस परिणाम को कैसे प्राप्त कर सकता हूं? ऐसा करने के लिए सबसे अच्छा संभव तरीका क्या है? मैंने ग्रैडल प्रलेखन के माध्यम से पहले से ही पढ़ा है, लेकिन मैं यह निर्धारित नहीं कर सकता कि कौन सी विधि इसके लिए सबसे आसान और सबसे उपयुक्त होगी।

अग्रिम में धन्यवाद!


अपडेट करें:

मैंने दूसरी फाइल में तरीके निकालने में कामयाबी हासिल की है

(का उपयोग करते हुए apply from: 'common-methods.gradle' ),

तो संरचना इस प्रकार है:

parent/
      /build.gradle              // The original build script
      /common-methods.gradle     // The extracted methods
      /gradle.properties         // Properties used by the build script

किसी कार्य को निष्पादित करने के बाद build.gradle, मैं एक नई समस्या से टकरा गया हूं: जाहिरा तौर पर, तरीकों को मान्यता नहीं मिलती है जब वे अंदर होते हैंcommon-methods.gradle

कैसे तय करने के बारे में कोई विचार?


क्या आप सुनिश्चित हैं कि आपको विधियों को लिखने की आवश्यकता है? यदि आप तरीकों के संदर्भ में अपनी बिल्ड स्क्रिप्ट लिखते हैं, तो आप कुछ ग्रेड गुडियों को याद करेंगे, सबसे महत्वपूर्ण बात यह है कि वृद्धिशील निर्माण को सही ढंग से काम करने के लिए अतिरिक्त काम करना होगा। टास्क का उपयोग और पुन: उपयोग करने के लिए अभिप्रेत अमूर्त है s । आप कस्टम कार्य भी बना सकते हैं । शायद आपको उन कार्यविधियों को लागू करने पर विचार करना चाहिए जो अब आपके पास हैं।
अल्पार

@ आलपर और अन्य ; क्या उद्देश्य के रूप में ( timestamp()या उदाहरण के लिए) के currentWorkingDirectory()रूप में एक या तरीकों की तरह कुछ बना दिया है task। उपयोगिता फ़ंक्शंस और इसी तरह की चीजें नाममात्र स्केलर हैं - वे कार्य नहीं होंगे सिवाय इसके कि कोड-पुन: उपयोग पर सीमाएं हैं जो ग्रैड और अधिकांश बिल्ड सिस्टम के साथ निर्मित हैं। मुझे DRY दुनिया पसंद है जहां मैं एक बार एक चीज बना सकता हूं और उसका पुन: उपयोग कर सकता हूं। वास्तव में, @Pieter VDE के उदाहरण का विस्तार मैं भी एक "का उपयोग root.gradle" पैटर्न मेरी माता पिता परियोजना के लिए - build.gradle फ़ाइल आम तौर पर कुछ परियोजना बारीकियों को परिभाषित करता है और फिर बस apply ${ROOT}...
होगा

यदि आपको संपत्तियों के साथ काम करने के लिए एक केंद्रीकृत तरीके की आवश्यकता है, तो शायद यह सवाल आपकी मदद कर सकता है: stackoverflow.com/questions/60251228/…
GarouDan

जवाबों:


76

विधियों को साझा करना संभव नहीं है, लेकिन आप अतिरिक्त गुणों को साझा कर सकते हैं जिसमें एक क्लोजर होता है, जो एक ही चीज़ को उबालता है। उदाहरण के लिए, की घोषणा ext.foo = { ... }में common-methods.gradle, उपयोग apply from:स्क्रिप्ट लागू करने के लिए, और फिर साथ बंद फोन foo()


1
यह वास्तव में चाल है! लेकिन मुझे इस बारे में एक सवाल है: कुछ वापस करने के तरीकों के बारे में कैसे? Fe File foo(String f)बन जाएगा ext.foo = { f -> ... }, क्या मैं तब कुछ कर सकता हूं File f = foo(...):?
पीटर वीडीई

2
जाहिर है, मेरी पिछली टिप्पणी में सवाल संभव है। तो इस प्रश्न का उत्तर देने के लिए, पीटर को धन्यवाद!
पीटर वीडीई

1
@PeterNiederwieser यह क्यों संभव नहीं है? Gradle.org अन्यथा सोचता है: docs.gradle.org/current/userguide/…
इगोरगानपोलस्की

1
@IgorGanapolsky लिंक के लिए धन्यवाद। मुझे आश्चर्य है कि मैं gradle.build में अलग बिल्ड फ़ाइल में उत्पन्न मान का उपयोग कैसे कर सकता हूं - इस तरह यह बहुत उपयोगी होगा :)
kiedysktos

@IgorGanapolsky आपको पीटर VDEs प्रश्न के संदर्भ में मदद को किस प्रकार साझा करना चाहिए?
t0r0X

157

पीटर के जवाब पर बिल्डिंग , यह है कि मैं अपने तरीके कैसे निर्यात करता हूं:

की सामग्री helpers/common-methods.gradle:

// Define methods as usual
def commonMethod1(param) {
    return true
}
def commonMethod2(param) {
    return true
}

// Export methods by turning them into closures
ext {
    commonMethod1 = this.&commonMethod1
    otherNameForMethod2 = this.&commonMethod2
}

और यह है कि मैं एक अन्य स्क्रिप्ट में उन तरीकों का उपयोग कैसे करूं:

// Use double-quotes, otherwise $ won't work
apply from: "$rootDir/helpers/common-methods.gradle"

// You can also use URLs
//apply from: "https://bitbucket.org/mb/build_scripts/raw/master/common-methods.gradle"

task myBuildTask {
    def myVar = commonMethod1("parameter1")
    otherNameForMethod2(myVar)
}

यहाँ ग्रोवी में बंद करने के तरीकों को बदलने पर अधिक है


वहाँ कोई विशेष कारण के रूप में बंद नाम का उपयोग करने के लिए है?
अनूप

1
@AnoopSS हम ग्रेड के अतिरिक्त गुणों के लिए दो क्लोजर जोड़ते हैं । इन अतिरिक्त गुणों को नामक ऑब्जेक्ट में बंडल किया जाता है ext
मथायस ब्रौन

क्या हम किसी तरह, मान को हमारे वर्ग के रूप में डाल सकते हैं, जिसे सम्मिलित फ़ाइल में परिभाषित किया गया है?
गरौदान

इस बारे में उदाहरण कोड @GarouDan के साथ एक अलग प्रश्न पोस्ट करना शायद एक अच्छा विचार है।
मथायस ब्रौन

7

कोटलिन डीएसएल का उपयोग करना इस तरह काम करता है:

build.gradle.kts :

apply {
  from("external.gradle.kts")
}

val foo = extra["foo"] as () -> Unit
foo()

बाहरी

extra["foo"] = fun() {
  println("Hello world!")
}

महान वहाँ actuall प्रकार साझा करने के लिए एक रास्ता है? आप मूल रूप से प्रकार सुरक्षा खो रहे हैं और संकलक मदद करते हैं ... यदि आप उस वर्ग को साझा कर सकते हैं जिसमें आपके तरीके शामिल हैं तो आप संकलक का उपयोग कर सकते हैं।
vach

0

Kotlin DSL के लिए एक और दृष्टिकोण हो सकता है:

मेरी-plugin.gradle.kts

extra["sum"] = { x: Int, y: Int -> x + y }

settings.gradle.kts

@Suppress("unchecked_cast", "nothing_to_inline")
inline fun <T> uncheckedCast(target: Any?): T = target as T

apply("my-plugin.gradle.kts")

val sum = uncheckedCast<(Int, Int) -> Int>(extra["sum"])

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