آشنایی با گردل
فهرست مطالب
آخرین به روزرسانی در 16/03/2022
در این مقاله قصد آشنایی با گردل و کاربرد آن در طراحی اپلیکیشن و عملیات بیلد کردن را داریم.
لازم به ذکر است در این مقاله تنها ما به معرفی و ارائه ی کاربرد گردل خواهیم پرداخت و آموزش کاملی
را نخواهیم داشت زیراکه گردل بسیار بزرگ و گسترده است.
برای درک بهتر این مقاله پیشنهاد می شود در ابتدا با زبان برنامه نویسی جاوا آشنایی نسبی داشته باشید.
آشنایی اولیه
Gradle یک سیستم مدیریت بیلد کردن پروژه ها می باشد که مبتنی بر Groovy است.
و به طور خاص برای ساخت پروژه های مبتنی بر جاوا طراحی شده است.
گردل یک ابزار ساخت اعلانی و همه منظوره است. که می توان گفت ترکیبی از دو ابزار Ant و Maven اعلامی می باشد به همراه ویژگی های بیشتر.
میتوانیم از Groovy یا Kotlin برای نوشتن یک اسکریپت بیلد برای ارائه دستورالعملها به Gradle استفاده کنیم.
در این مجموعه قرار است از زبان کاتلین برای نوشتن اسکریپت های ساختمان استفاده کنیم.
لازم به ذکر است که بگوییم، Gradle یک ابزار بیلد زبان JVM است، اما از ابزار بیلد ، نوشته شده با C++ ، C و … نیز پشتیبانی می کند.
چرا ما به ابزار Build Automation نیاز داریم ؟
متداول ترین فرآیندها در ساخت هر اپلیکیشن شامل : کامپایل کردن سورس کد ، بسته بندی خروجی کامپایل شده به فرمت فشرده شده مانند apk (اندروید)، JAR، TAR، ZIP و … است.
در کنار این، ممکن است کارهای دیگری مانند اجرای برنامه را نیز انجام دهیم.
تجزیه و تحلیل کد ایستا یا اجرای آزمایشات روی سورس کد و..
حال تصور کنید که هیچ ابزاری برای خودکارسازی این فرآیند وجود نداشته باشد.
و ما باید تمام این اقدامات را به صورت دستی انجام دهیم ، که مشکلات سیستم دستی به شرح زیر می باشد :
- خسته کننده بودن و طولانی بودن پروسه ی انجام این فرایندها.
- امکان بروز خطا
بیلد اتوماتیک به ما اجازه می دهد تا مراحل دستی مربوط به فرآیند ساخت را خودکار کنیم.
این باعث صرفه جویی در هزینه و زمان صرف شده در فرآیند دستی می شود.
هدف اصلی ابزار بیلد اتوماتیک این است که هر بار که اسکریپت بلید را اجرا می کنیم asset های قابل تکرار ایجاد کنیم.
همانطور که اکنون اهمیت ابزارهای بلید را می دانیم، بیایید اطلاعات بیشتری را در مورد آنها شرح دهیم.
انواع ابزارهای بیلد
دو نوع ابزار بیلد وجود دارد، ابزارهای بلید دستوری و ابزارهای اعلامی.
یک ابزار بیلد ضروری به سیستم می گوید که چه کاری را چگونه انجام دهد.
این بدان معناست که برای سیستم بیلد ضروری (دستوری)، ما باید تمام مراحل مربوط به فرآیند بیلد را مشخص کنیم.
همراه با مشخص کردن هر مرحله، باید اطلاعاتی در مورد نحوه اجرای آن مراحل نیز ارائه کنیم.( Ant نمونه ای از ابزار ساخت ضروری است.)
اما برای ابزارهای اعلامی، فقط باید مشخص کنیم که می خواهیم به چه چیزی برسیم و سیستم نحوه انجام آن را مشخص خواهد کرد.
( Maven نمونه ای از ابزار ساخت اعلانی است.) اکنون، ممکن است از خود بپرسید که Gradle جز کدام دسته از این ابزارها قرار دارد.
ویژگی های گردل
Incremental Build :
Gradle Build از چندین تسک تشکیل شده است، و task ممکن است برخی از ورودی ها را بگیرد و برخی از خروجی ها را تولید کند.
Gradle بررسی می کند که آیا ورودی، خروجی یا اجرای یک تسک از آخرین فراخوانی عملیات بیلد تغییر کرده است یا خیر.
در غیر این صورت، تسک به روز در نظر گرفته می شود و اجرا نمی شود که این موضوع منجر به تکمیل سریعتر بیلد می شود.
Parallel Execution :
Gradle امکان اجرای موازی تسک ها را فراهم می کند که این فرایند به کاهش زمان بیلد بسیار کمک می کند.
Build Output Caching :
Gradle می تواند خروجی های بیلد را کش کند.
یکی از مزیت های این ذخیره سازی این است که ما می توانیم از خروجی ذخیره شده برای ساخت کار دیگری که وابسته به آن است، دوباره استفاده کنیم.
این فرایند از کار پرهزینه بازسازی آنها جلوگیری می کند.
Task Exclusion :
ما اغلب نیاز به اجرای برخی تسک ها بسته به برخی شرایط داریم.
و وقتی تسکی را حذف می کنیم، تمام تسک هایی که این تسک به آنها وابسته است نیز به طور خودکار حذف می شوند.
همچنین میتوانیم نام تسکی را که میخواهیم با استفاده از گزینه -x یا -exclude-task از خط فرمان حذف کنیم، ذکر کنیم.
Version Conflict Resolution :
گاهی در یک بیلد همزمان چند پروژه، ممکن است موقعیتی پیش بیاید که بیش از یک پروژه وابستگی مشترک داشته باشد.
در این حالت، Gradle با استفاده از جدیدترین نسخه درخواستی، dependency conflicts را حل می کند.
ما همچنین می توانیم این فرایند را سفارشی کنیم.
Transitive Dependencies :
یکی از مزایای اصلی استفاده از سیستم مدیریت dependency ، مدیریت transitive dependencies است.
Gradle از بارگیری و transitive dependencies حفاظت می کند.
Publishing Multiple Artifacts :
ما اغلب نیاز داریم که پس از اتمام پروسه ی بیلد، گزارش های بیلد را در برخی از منابع منتشر کنیم.
Gradle می تواند چندین artifacts مانند apk (اندروید)، JAR، TAR، ZIP و … ایجاد و منتشر کند.
Customisable Logging :
نمایش لاگ ها برای درک آنچه در حین اجرای بیلد اتفاق می افتد بسیار مهم است و همچنین به اشکال زدایی و یافتن مشکلات کمک می کند.
Gradle از سطوح مختلف گزارش مانند debug(-d) و .. پشتیبانی می کند.
Extensibility :
توسعه پذیری یکی از ویژگی های فوق العاده ی Gradle است.
ما به راحتی می توانیم Gradle را برای ارائه انواع تسک ها یا مدل های بیلد خود گسترش دهیم.
Incremental Builds :
Gradle کار ما را با بیلد افزایشی سریع تر می کند، به این معنی که فقط تسک های ضروری را اجرا می کند.
اگر سورس کد را کامپایل کنیم، بررسی می کند که آیا منابع نسبت به اجرای قبلی تغییر کرده اند یا خیر.
اگر کد تغییر کند، آنگاه اجرا خواهد شد.
اما، اگر کد تغییر نکرده باشد، اجرا را رد می کند و تسک به عنوان به روز شده علامت گذاری می شود.
الگوریتم های زیادی در Gradle برای انجام این کار وجود دارد.
Familiar with the Java :
ما برای اجرای Gradle به JVM نیاز داریم، بنابراین دستگاه ما باید یک کیت توسعه جاوا (JDK) داشته باشد.
Gradle با اکثر ویژگی های جاوا آشنا است.
این یک امتیاز برای کاربران جاوا است زیرا میتوانیم از APIهای استاندارد جاوا استفاده کنیم، مانند پلاگینها و تسک های سفارشی.
بنابراین اجرای Gradle بر روی پلتفرم های مختلف را آسان می کند.
Gradle فقط به ساخت پروژه های JVM محدود نمی شود. همچنین از ساخت پروژه های بومی پشتیبانی می کند.
Performance :
Gradle در عملکرد بسیار سریع است. در تمام بخش ها حدود دو برابر سریعتر از Maven و در بیلدهای بزرگ با استفاده از build-cache صد برابر سریعتر است.
فایل های گردل
Gradle از انواع فایل های زیر پشتیبانی می کند:
- تنظیمات
- بلید اسکریپت ها
- اسکریپت های Init
- فایل های Property
در ادامه به صورت مجزا هر یک از این فایل ها را بررسی کرده و مفهوم آنهارا شرح خواهیم داد.
Settings
نام پیش فرض این فایل settings.gradle (برای Groovy) یاsettings.gradle.kts (برای Kotlin) است.
هدف اصلی فایل تنظیمات ثبت پروژه های فرعی است که بخشی از فرآیند بیلد خواهد بود.
با استفاده از روش include می توانیم پروژه های فرعی را در فایل تنظیمات ثبت کنیم.
Gradle چگونه می داند که فرآیند بیلد فعلی بخشی از بیلد تک یا چند پروژه ای است؟
همانطور که می دانیم Gradle از بیلد تک پروژه ای و چند پروژه ای پشتیبانی می کند.
برای تعیین نوع فرآیند بیلد فعلی، ابتدا فایل تنظیمات را در دایرکتوری فعلی و سپس در سلسله مراتب والد آن جستجو می کند
و مراحل زیر را برای تعیین نوع دنبال می کند.
اگر دایرکتوری والد و فعلی حاوی فایل تنظیمات نباشند، Gradle بیلد را به عنوان یک پروژه واحد در نظر می گیرد.
اگر دایرکتوری فعلی دارای فایل تنظیمات باشد، Gradle آن را به عنوان بیلد چند پروژه ای در نظر می گیرد و دایرکتوری فعلی را به عنوان یک پروژه والد (root) در نظر می گیرد.
سپس فایل تنظیمات را می خواند تا پروژه های فرعی را که باید در فرآیند بیلد گنجانده شوند، مشخص کند.
اگر دایرکتوری فعلی حاوی فایل تنظیمات نباشد، اما اگر فایل تنظیمات در دایرکتوری والد باشد، Gradle آن را به عنوان بیلد چند پروژه ای در نظر می گیرد.
سپس بررسی می کند که آیا زیرشاخه فعلی به عنوان یک پروژه فرعی در فایل تنظیمات پروژه root ثبت شده است یا خیر.
اگر پروژه فعلی بخشی از پروژه root باشد، به عنوان بخشی از ساخت چند پروژه ای اجرا می شود، در غیر این صورت، به عنوان یک پروژه واحد اجرا می شود.
// can create variables
private val TAG = "Settings File: "
//can access rootProject object
rootProject.name = "GradleLearning"
//can access gradle object
val gradleVersion = gradle.gradleVersion
println("$TAG gradle version is $gradleVersion")
println("$TAG project name is ${rootProject.name}")
// can add projects which are part of build process.
include(":app")
// Access user defined properties using extra
val greetMessage = extra.properties.get("greetMessage")
if(greetMessage != null) {
println("$TAG value of user defined property greetMessage is $greetMessage")
}else{
println("$TAG user defined property greetMessage is not available.")
}
// Access System properties using System.getProperty()
val javaVersion = System.getProperty("java_version")
if(javaVersion != null) {
println("$TAG value of system property java_version is available $javaVersion")
}else{
println("$TAG value of system property java_version is not available")
}
مواردی که در مورد فایل تنظیمات باید در نظر داشته باشید عبارتند از:
ما در این فایل به نمونه های gradle و rootProject دسترسی داریم.
ما به ویژگیهایی دسترسی داریم که هم در gradle.properties اعلام شدهاند و هم از خط فرمان ارائه شدهاند.
Build Scripts
یک رابطه تنگاتنگی بین یک نمونه پروژه و یک فایل بیلد وجود دارد.
بیلدهای پروژه واحد ، فایل بیلد شامل dependencies ها برای هر دو اسکریپت بیلد و پروژه است.
بیلد چند پروژه ، هر پروژه فرعی ممکن است فایل بیلد خود را داشته باشد و هر پروژه فرعی در صورت وجود، با اجرای فایل بیلد آن ارزیابی خواهد شد.
فایل بیلد یک پروژه root معمولاً برای به اشتراک گذاری چیزهای مشترکی که در همه پروژه های فرعی مورد نیاز است استفاده می شود.
به عنوان مثال، dependency های اسکریپت، و repository links را برای مکان یابی آن dependency ها بسازید.
و تسک های معمولی مانند پاک کردن، که منابع ایجاد شده قبلی را توسط پروژه root و هر پروژه فرعی حذف می کند.
بیلد dependency اسکریپت در مقابل dependency پروژه
dependency اسکریپت بیلد به معنی کتابخانه ها یا افزونه هایی است که بیلد Gradle ما به آنها وابسته است.
به عنوان مثال، ما می خواهیم با استفاده از Gradle یک پروژه اندروید بسازیم، سپس باید وابستگی build script را به com.android.tools.build:gradle اضافه کنیم، پس از آن دیگر تمامی کارها با گردل می باشد.
project.buildscript {
// repository links to locate build script dependencies.
repositories {
google()
jcenter()
}
// build script dependencies
dependencies {
val kotlin_version = "1.3.61"
classpath("com.android.tools.build:gradle:4.0.0-alpha09")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlin_version}")
}
}
از طرف دیگر، وابستگی پروژه به کدی که قرار است بیلد شود، مربوط می شود.
به عنوان مثال، فرض کنید پروژه ما برای اجرای آزمایشات به کتابخانه JUnit نیاز دارد.
بنابراین ما باید وابستگی JUnit را در محدوده پروژه و نه در محدوده اسکریپت بیلد فراخوانی کنیم.
project.repositories {
// repository links to locate project dependencies.
google()
jcenter()
}
project.dependencies {
// project dependencies
implementation("org.jetbrains.kotlin:kotlin-stdlib:${kotlin_version}")
testImplementation("junit:junit:4.12")
}
BuildSrc
در یک پروژه بیلد پیچیده، ما اغلب نیاز به نوشتن تسک های سفارشی یا پلاگین یا برخی از منطق های بیلد را داریم.
این تسک های سفارشی و پیادهسازی پلاگین نباید در فایل اسکریپت بیلد وجود داشته باشد زیرا پیچیدگی فایل اسکریپت بیلد را افزایش میدهد.
ما می توانیم این منطق را در دایرکتوری buildSrc نگه داریم.
هنگامی که Gradle دایرکتوری buildSrc را یافت، Gradle به طور خودکار این کد را کامپایل و آزمایش می کند و آن را در مسیر کلاس اسکریپت ساخت قرار می دهد.
لازم به ذکر است فقط یک دایرکتوری buildSrc می تواند وجود داشته باشد (حتی برای بیلد چند پروژه)، و باید در دایرکتوری اصلی پروژه باشد.
مزایای جداسازی کدهای مربوط به اسکریپت بیلد در دایرکتوری buildSrc عبارتند از:
نگهداری آسان تر، اصلاح و تست کدها و …
Init Scripts
اسکریپت های Init که به اسکریپت های Initialisation نیز معروف هستند، شبیه اسکریپت های بیلد در Gradle هستند.
اسکریپت های Init قبل از شروع عملیات بیلد اجرا می شوند.
این اسکریپتها بهعنوان اسکریپتهای سراسری عمل میکنند که برای همه پروژههای موجود در دستگاه فعلی به اشتراک گذاشته میشوند.
از این اسکریپت ها می توان برای موارد زیر استفاده کرد:
تعریف جزئیات خاص ماشین، مانند محل نصب JDKها.
راهاندازی ویژگیها بر اساس محیط فعلی، مانند ماشین دولوپر در مقابل سرور continuous integration.
برای ارائه اطلاعات شخصی در مورد کاربر که توسط بیلد مورد نیاز است، مانند اعتبارنامه احراز هویت پایگاه داده.
کجا اسکریپت های init را اعلام کنیم؟
همانطور که می دانیم، اسکریپت های init برای همه پروژه ها در ماشین فعلی در دسترس هستند،
بنابراین باید در منطقه مشترک سراسری بین همه پروژه ها در دسترس باشد.
ما می توانیم مسیر فایل اسکریپت init را از خط فرمان با استفاده از گزینه -I یا –init-script ارائه کنیم.
اگر فقط یک اسکریپت init داشته باشیم، میتوانیم آن را init.gradle یا init.gradle.kts نامگذاری کنیم و آن را در فهرست USER_HOME/.gradle/ قرار دهیم.
اگر بیش از یک فایل اسکریپت init داریم، دایرکتوری با نام init.d ایجاد کرده و در پوشه USER_HOME/.gradle/ قرار دهید.
مزیت داشتن دایرکتوری init.d این است که میتوانیم همه فایلهای اسکریپت init را در یک مکان معمولی داشته باشیم، و میتوانیم نام فایل را متفاوت از init.gradle کنیم.
لازم به ذکر است اسکریپت های init در فهرست init.d به ترتیب حروف الفبا اجرا می شوند.
Init Scripts در مقابل بیلد اسکریپت ها
اسکریپت های بیلد مختص یک پروژه هستند. Gradle برای هر فایل اسکریپت بیلد نمونه ای از پروژه ایجاد می کند و به طور ضمنی در آن فایل اسکریپت موجود است. بین فایل بیلد و نمونه پروژه ارتباط یک به یک وجود دارد.
از سوی دیگر، اسکریپتهای Init مانند اسکریپتهای سراسری هستند که بین تمام پروژههای موجود در ماشین فعلی به اشتراک گذاشته میشوند.
Gradle برای هر اسکریپت init نمونه ای از gradle ایجاد می کند و به طور ضمنی در آن فایل اسکریپت موجود است.
Gradle properties
Gradle اجازه می دهد تا با استفاده از ویژگی های سفارشی، بیلد را پیکربندی کنید.
ویژگی های سیستم به JVM منتقل می شود که Gradle را اجرا می کند.
ما میتوانیم از ویژگیهای سیستم استفاده کنیم تا مطمئن شویم که کل تیم روی یک محیط کار میکند، به عنوان مثال، نسخه خاصی از جاوا.
ویژگی های پروژه برای سفارشی سازی بیلد پروژه با استفاده از ویژگی های تعریف شده توسط کاربر استفاده می شود.
یک تفاوت دیگر بین نحوه مدیریت سیستم و خصوصیات پروژه وجود دارد.
اگر به خاصیت سیستمی دسترسی پیدا کنیم که وجود ندارد، مقدار null برای آن دریافت میکنیم و اجرای Gradle به این دلیل متوقف نمیشود.
از طرف دیگر، اگر سعی کنیم به برخی از ویژگی های کاربر دسترسی پیدا کنیم که در دسترس نیست، MissingPropertyException را دریافت می کنیم و Gradle اجرا را متوقف می کند، به این معنی که بیلد با شکست مواجه می شود.
با استفاده از روش های زیر می توانیم ویژگی ها را اعلام کنیم :
- فایل gradle.properties
- Extra Properties
- گزینه Command line
فایل gradle.properties
ما می توانیم هر دو ویژگی سیستم و پروژه را در فایل gradle.properties اعلام کنیم.
و همچنین میتوانیم فایل خصوصیات مختص یک پروژه و همچنین فایل مشترک برای همه پروژهها داشته باشیم.
فایل ویژگی خاص پروژه در همان دایرکتوری پروژه root قرار دارد.
فایل مشترک و جهانی خصوصیات فایل در فهرست USER_HOME/.gradle/ قرار دارد.
# gradle(JVM) arguments
org.gradle.daemon=true
org.gradle.jvmargs=-Xmx2048m
# system properties
systemProp.gradle.wrapperUser=myuser
systemProp.gradle.wrapperPassword=mypassword
systemProp.greetMessageSystem="hello : System property"
# project properties
greetMessageProject="Hello, Good Morning."
// Project properties can be accessed via delegation.
val greetMessageProject: String by project
val greetMessageSystem: String by System.getProperties()
// We can also access properties using property object.
val greet = project.property("greetMessage")
val message = System.getProperty("greetMessage")
Extra Properties
تمام اشیاء پیشرفته در مدل دامنه Gradle میتوانند ویژگیهای اضافی تعریفشده توسط کاربر را داشته باشند.
این شامل پروژه ها، تسک ها و منابع می شود.
ویژگی های اضافی را می توان از طریق ویژگی ext شیء مالک اضافه، خواند و تنظیم کرد.
از طرف دیگر، یک بلوک ext می تواند برای افزودن چندین ویژگی به طور همزمان استفاده شود.
// declare properties using set(key,value) of ext.
project.ext.set("greetMessage", " Good Morning")
// declare properties inside ext closure
project.ext {
set("greetMessage", "Good Morning")
set("greetMessage2", "Good Afternoon")
}
// access a property using its key
println("${project.property("greetMessage")}")
// Project properties can be accessed via delegation
val greetMessage: String by project
// Print all project properties
println("gradle: In Root Project Printing all properties -------")
project.properties.forEach{
println("Property key name: ${it.key} and value is : ${it.value}")
}
گزینه Command line
ما می توانیم هر دو ویژگی پروژه و سیستم را از خط فرمان در زمان اجرای بیلد تنظیم کنیم.
برای تنظیم ویژگی سیستم از خط فرمان از گزینه -D استفاده کنید، مثلاً فرض کنید ویژگی سیستمی به نام javaVersion وجود دارد و اگر بخواهیم آن را از خط فرمان تنظیم کنیم، میتوانیم از DjavaVersion=1.8 با دستور gradle استفاده کنیم.
برای تنظیم ویژگی پروژه از خط فرمان از گزینه -P استفاده کنید، به عنوان مثال، فرض کنید ویژگی پروژه وجود دارد به نام testable و اگر بخواهیم آن را از خط فرمان تنظیم کنیم، می توانیم از -Ptestable=true با دستور gradle استفاده کنیم.
( از این قسمت به بعد می خواهیم کمی وارد مباحث تخصصی تر در رابطه با گردل بشویم و ممکن است درک برخی این موارد برای شما سخت تر بوده و نیاز به مقدمات و مطالعات بیشتری در رابطه با گردل داشته باشد.
پس اگر قصد شما تنها آشنایی با این ابزار بوده است تا همینجای مقاله کفایت می کند اما اگر قصد درگیر شدن با مباحث تخصصی تری را دارید پس با ما در ادامه همراه باشید.)
تسک ها
Gradle همه چیز را بر اساس پروژه ها و تسک ها توصیف می کند.
هر بیلد Gradle شامل یک یا چند پروژه است و این پروژه ها شامل برخی تسک ها هستند.
اسکریپت های ساخت Gradle چیزی جز Groovy نیستند :
task toLower {
doLast {
String someString = 'HELLO FROM BAELDUNG'
println "Original: "+ someString
println "Lower case: " + someString.toLowerCase()
}
}
ما می توانیم تسک هایی را تعریف کنیم که به تسک های دیگر وابسته هستند.
وابستگی تسک ها را می توان با ارسال آرگومان dependentOn: taskName در تسک تعریف کرد :
task helloGradle {
doLast {
println 'Hello Gradle!'
}
}
task fromBaeldung(dependsOn: helloGradle) {
doLast {
println "I'm from Baeldung"
}
}
پلاگین ها در گردل
دو نوع پلاگین در Gradle وجود دارد ؛ اسکریپت و باینری.
برای بهره مندی از یک عملکرد اضافی، هر افزونه باید دو مرحله را طی کند: resolving و applying.
Resolving به معنای یافتن نسخه صحیح افزونه jar و افزودن آن به classpath پروژه است.
Applying هم به معنای اجرای Plugin.apply(T) در پروژه است.
Applying Script Plugins
در aplugin.gradle میتوانیم یک تسک به شرح زیر تعریف کنیم :
task fromPlugin {
doLast {
println "I'm from plugin"
}
}
اگر بخواهیم این افزونه را در فایل build.gradle پروژه خود اعمال کنیم، تنها کاری که باید انجام دهیم این است که این خط را به build.gradle خود اضافه کنیم:
apply from: 'aplugin.gradle'
اکنون، اجرای دستور gradle tasks باید تسک fromPlugin را در لیست تسک ها نمایش دهد.
استفاده از پلاگین های باینری با استفاده از پلاگین های DSL
در مورد اضافه کردن یک پلاگین core binary ، میتوانیم نامهای کوتاه یا شناسه پلاگین را اضافه کنیم:
plugins {
id 'application'
}
اکنون تسک اجرا از افزونه برنامه باید در یک پروژه برای اجرای هر jar قابل اجرا ، در دسترس باشد.
برای اعمال یک افزونه انجمن، باید یک شناسه افزونه کاملاً واجد شرایط را ذکر کنیم:
plugins {
id "org.shipkit.bintray" version "0.9.116"
}
محدودیت های افزونه های DSL عبارتند از:
- از کد Groovy در داخل بلوک افزونه ها پشتیبانی نمی کند.
- پلاگین ها DSL را نمی توان در پلاگین اسکریپت، فایل settings.gradle یا در اسکریپت های init نوشت.
- Plugins DSL هنوز در حال توسعه است پس DSL و سایر تنظیمات ممکن است در نسخه های بعدی Gradle تغییر کنند.
مدیریت Dependency
Gradle از سیستم مدیریت Dependency بسیار انعطاف پذیر پشتیبانی می کند، این سیستم با طیف گسترده ای از رویکردهای موجود سازگار است.
بهترین روشها برای مدیریت Dependency در Gradle عبارتند از versioning ، versioning پویا، resolving version conflicts و managing transitive dependencies.
Declaring Dependencies
بیایید به مثالی از افزودن برخی Dependencies ها (Spring و Hibernate) با استفاده از چندین روش مختلف نگاه کنیم:
dependencies {
compile group:
'org.springframework', name: 'spring-core', version: '4.3.5.RELEASE'
compile 'org.springframework:spring-core:4.3.5.RELEASE',
'org.springframework:spring-aop:4.3.5.RELEASE'
compile(
[group: 'org.springframework', name: 'spring-core', version: '4.3.5.RELEASE'],
[group: 'org.springframework', name: 'spring-aop', version: '4.3.5.RELEASE']
)
testCompile('org.hibernate:hibernate-core:5.2.12.Final') {
transitive = true
}
runtime(group: 'org.hibernate', name: 'hibernate-core', version: '5.2.12.Final') {
transitive = false
}
}
ما Dependencies ها را در پیکربندیهای مختلف اعلام میکنیم : کامپایل، testCompile و زمان اجرا در قالبهای مختلف.
گاهی اوقات ما به Dependencies هایی نیاز داریم که مصنوعات متعددی دارند.
در چنین مواردی، میتوانیم یک نماد فقط آرتیفکت @extensionName (یا ext به شکل توسعهیافته) برای دانلود آرتیفکت مورد نظر اضافه کنیم:
runtime "org.codehaus.groovy:groovy-all:2.4.11@jar"
runtime group: 'org.codehaus.groovy', name: 'groovy-all', version: '2.4.11', ext: 'jar'
در اینجا، نماد jar@ را اضافه کردیم تا فقط artifact jar را بدون Dependencies دانلود کنیم.
برای افزودن Dependencies به هر فایل محلی، می توانیم از چیزی شبیه به این استفاده کنیم:
compile files('libs/joda-time-2.2.jar', 'libs/junit-4.12.jar')
compile fileTree(dir: 'libs', include: '*.jar')
Multi-Project Builds
در مرحله initialization ، Gradle تعیین می کند که کدام پروژه ها قرار است در Multi-Project Builds شرکت کنند.
این موضوع معمولاً در فایل settings.gradle که در ریشه پروژه قرار دارد ذکر می شود.
Gradle همچنین نمونه هایی از پروژه های شرکت کننده را ایجاد می کند.
در مرحله پیکربندی، تمام نمونههای پروژه ایجاد شده بر اساس پیکربندی ویژگی Gradle در صورت تقاضا پیکربندی میشوند.
در این ویژگی، تنها پروژه های مورد نیاز برای اجرای یک کار خاص پیکربندی می شوند.
به این ترتیب، زمان پیکربندی برای ساخت چند پروژه بزرگ بسیار کاهش می یابد. این ویژگی هنوز در حال توسعه است.
در نهایت، در مرحله اجرا، زیر مجموعه ای از تسک های، ایجاد و پیکربندی شده اجرا می شود.
برای درک این سه فاز می توانیم کد را در فایل های settings.gradle و build.gradle قرار دهیم.
در settings.gradle :
println 'At initialization phase.'
در build.gradle :
println 'At configuration phase.'
task configured { println 'Also at the configuration phase.' }
task execFirstTest { doLast { println 'During the execution phase.' } }
task execSecondTest {
doFirst { println 'At first during the execution phase.' }
doLast { println 'At last during the execution phase.' }
println 'At configuration phase.'
}
ایجاد Multi-Project Build
میتوانیم دستور gradle init را در root folder اجرا کنیم تا یک اسکلت برای فایل settings.gradle و build.gradle ایجاد کنیم.
تمام پیکربندی های رایج در اسکریپت ساخت root حفظ می شود:
allprojects {
repositories {
mavenCentral()
}
}
subprojects {
version = '1.0'
}
فایل تنظیمات باید شامل نام پروژه root و نام پروژه فرعی باشد:
rootProject.name = 'multi-project-builds'
include 'greeting-library','greeter'
اکنون باید چند پوشه فرعی به نامهای greeting-library و greeter داشته باشیم تا یک نسخه نمایشی از یک Multi-Project Build داشته باشیم.
هر پروژه فرعی نیاز به یک individual build script برای پیکربندی Dependencies individual و سایر تنظیمات لازم دارد.
اگر میخواهیم پروژه greeter ما به greeting-library وابسته باشد، باید Dependencies را در اسکریپت ساخت greeter قرار دهیم:
dependencies {
compile project(':greeting-library')
}
مهرسا امینی
برنامه نویس ، انیماتور ، سئوکار
در زندگی رویاهات را دنبال کن