دليلك الكامل إلى نظام البناء Gradle


أمل عبدالله محمد الجنايني

1. مقدمة عن نظام بناء Gradle

1.1. ما هو نظام بناء Gradle

Gradle هو نظام بناء إداري للأغراض العامة. يدعم Gradle التنزيل والضبط التلقائي للتبعيات Dependencies أو المكتبات الأخرى. ويدعم مستودعات Maven و Ivy لاستعادة هذه التبعيات.

يدعم Gradle المشروع المُتعدد والبناءات ذات النواتج المتعددة.

1.2. المشاريع والمهام في Gradle

يتم وصف بناءات جرادل (Gradle Builds) عبر ملف واحد أو عدة ملفات build.gradle متعددة. يوجد عادةً (ملف بناء Build File) واحد على الأقل في المجلد الأصلي للمشروع. يُعرِّف كل ملف بناء مشروعًا ومهامًا لهذا المشروع.

تنقسم المشروعات إلى نوعين:

  • شيء يجب بناؤه
  • شيء يجب القيام به

ويتكون المشروع من مهام Tasks. تمثل المهمة Task جزءًا من العمل الذي تؤديه أحد الأبنية Builds، على سبيل المثال، تجميع التعليمات البرمجية المصدر (Compile the source code) أو إنشاء Javadoc. تستند ملفات البناء هذه إلى لغة ذات مجال مخصص (Domain Specific Language - DSL).في هذا الملف، يمكنك استخدام مجموعة من التعليمات التصريحية والضرورية (declarative and imperative statements).

تستطيع كتابة كود Groovy أو Kotlin متى احتجت إلى ذلك. يمكنك أيضًا إنشاء المهام وتوسيعها ديناميكيًا في وقت التشغيل Runtime.

تمثل القائمة التالية ملف بناء بسيط للغاية.

task hello {
    doLast {
        println 'Hello Gradle'
    }
}

لتنفيذ المهمة hello في ملف البناء، اكتب gradle hello في سطر الأوامر في مجلد ملف البناء. إذا اختفى ناتج جرادل Gradle Output، يُمكنك استخدام q- كـ (quiet parameter).

gradle hello

# alternative add the -q flag
gradle -q hello

1.3 التعليقات في ملفات بناء Gradle

يُمكنك استخدام التعليقات الفردية والمتعددة الأسطر في ملفات بناء Gradle كما يلي:

// تعليق على سطر واحد

/*
 تعليق
على أسطر
متعددة
*/

1.4. إعدادات المشروع والوصف

بشكل افتراضي، يستخدم Gradle اسم ال (Directory Name) كاسم مشروع. يمكنك تغيير هذا عن طريق إنشاء ملف settings.gradle في الدليل الذي يُحدد اسم المشروع.

rootProject.name ='com.vogella.gradle.first'

يمكنك أيضًا إضافة وصف لمشروعك عبر ملف build.gradle:

description ="""
Example project for a Gradle build

Project name: ${project.name}

More detailed information here... """

task hello {
    doLast {
        println 'Hello Gradle'
    }
}

استخدم الأمر gradle project للحصول على معلومات حول مشروعك. تظهر القائمة التالية الناتج.

:projects

------------------------------------------------------------
Root project -
Example project for a Gradle build

Project name: com.vogella.gradle.first

More detailed information here...
------------------------------------------------------------

Root project 'com.vogella.gradle.first' -
Example project for a Gradle build

Project name: com.vogella.gradle.first

More detailed information here...
No sub-projects

To see a list of the tasks of a project, run gradle <project-path>:tasks
For example, try running gradle :tasks

BUILD SUCCESSFUL

Total time: 1.048 secs

2. مكونات Gradle الإضافية (Gradle Plug-ins)

يستخدم نظام بناء Gradle مكونات إضافية أو إضافات (Plug-ins) لزيادة وظائفه الأساسية. المكوّن الإضافي هو توسيع لعمل لـ Gradle يضيف عادة بعض المهام المُعدّة مسبقًا. يأتي Gradle مع عدد من المكونات الإضافية، ويمكنك تطوير مكونات إضافية مخصصة.

مثال على ذلك هو مُكوِّن جافا الإضافي (Java Plug-in). يُضيف هذا المكوّن الإضافي مهامًا إلى مشروعك والتي تسمح بترجمة شيفرة جافا المصدرية (Java Source Code)، وتشغيل اختبارات الوحدة وإنشاء ملف JAR. يتواجد المكون الإضافي في ملف build.gradle مع التعليمة البرمجية 'apply plugin:'pluginname .

على سبيل المثال، الأمر التالي يجعل المكون الإضافي لنظام Android متاحًا لإنشاء Gradle:

apply plugin: 'com.android.application'

يوفر Gradle أيضًا سجلًا للمكونات الإضافية عبر المكوِّن الإضافي الخاص بالبحث في Gradle والمُسمى بـ Gradle Plugin Search.

2.1. دعم بيئة تطوير متكاملة IDE لـ Gradle.

تقوم شركة Gradleware بتطوير برنامج Eclipse Gradle التعليمي عبر مشروع Eclipse Buildship. تتضمن البيئات التطويرية المتكاملة الأخرى IDEs مثل IntelliJ و Android Studio دعمًا جيدًا لـ Gradle.

تثبيت وتهيئة Gradle

2.2. المتطلبات

يتطلب استخدام Gradle تثبيت عدّة تطوير جافا (JDK (Java Development Kit.

2.3. تحميل واستخراج Gradle

يمكن العثور على أحدث إصدار من Gradle على صفحة تنزيل جرادل Gradle Download Page. قم بتنزيل أحدث توزيع متكامل.

إنها gradle-${version}-all.zip، حيث تعبّر {version}$ عن الإصدار الحالي.

استخرج محتويات الملف المضغوط الذي قمت بتنزيله في مجلد جديد.

2.4. تثبيت Gradle على الويندوز

أضف هذا المُجلد الجديد، الذي استخرجت فيه محتويات Gradle في الخطوة السابقة، إلى مُتغير البيئة PATH.

بالضغط على Win + Pause، يمكنك فتح إعدادات النظام.

2-SetupStep1.png

أولًا قم باختيار Advanced System Settings، ثم اضغط على زر Environment Variables كما هو موضّح.

3-SetupStep2.png

  1. في نافذة متغيرات البيئة، يجب تعيين متغيرات المستخدم JAVA_HOME و GRADLE_HOME.

  2. بعد ذلك، اختر المدخل PATH في (متغيرات النظام System Variables). ثم اضغط على زر التعديل Edit لإضافة ملف bin الخاص بتثبيت Gradle إلى المسار PATH.

4-SetupStep3.png

2.5. تثبيت Gradle على لينكس/ماك

2.5.1 التثبيت اليدوي

يجب أن يشير متغير JAVA_HOME إلى jdk مناسب ويجب أن يكون JAVA_HOME/bin$ جزءًا من متغير بيئة PATH.

أضف Gradle إلى المسار عن طريق تنفيذ السطر الآتي في Terminal:

export PATH=/usr/local/gradle/FOLDER_TO_WHICH_YOU_EXTRACTED_GRADLE/bin:$PATH

2.5.2 التثبيت مع SDKMAN!

SDKMAN! هي أداة سطر أوامر تتيح لك تثبيت إصدارات Gradle المتعددة والتبديل بينها. يتم تشغيله على أي نظام تشغيل يستند إلى UNIX.

تثبيت SDKMAN!

يمكنك تثبيته من سطر الأوامر. إذا كنت قد قمت بالفعل بتثبيت SDKMAN! يمكنك تخطي هذه الخطوة.

curl -s "https://get.sdkman.io" | bash

بعد تثبيت SDKMAN! يجب عليك إعادة تشغيل الجهاز قبل استخدامه.

تثبيت Gradle وإعداد الإصدار الافتراضي
sdk install gradle 6.2.1
sdk default gradle 6.2.1
gradle -v
تبديل إصدار Gradle
sdk install gradle 6.2.1
# use 6.2.1 for current terminal session
sdk use gradle 6.2.1
gradle -v

2.5.3. تحقق من نجاح تثبيت Gradle

افتح سطر أوامر واكتب gradle، وسيتم تشغيل المهمة المساعدة الخاصة بـ Gradle بشكل افتراضي.

تنبيه: قد يختلف الإصدار المتوافر حاليًا أثناء قراءتك للمقال عن الإصدار المستعمل أثناء ترجمة المقال، لذا نرجو التأكد من هذه النقطة من موقع Gradle الرسمي قبل الاستمرار، فقد يكون هنالك بعض الإختلافات والتحديثات التي أضيفت على أحدث إصدار Gradle عن الإصدارات السابقة.

2.6. استخدام البرنامج الخفي Gradle لتحسين وقت بدء التشغيل

يسمح Gradle لنفسه بالبدء كـبرنامج خفي لتجنب بدء تشغيل جهاز جافا الظاهري Java Virtual Machine لكل بنية. لتكوين ذلك:

  • أنشئ ملف يسمى gradle.properties في HOME}/.gradle}$ وإضافة السطر التالي إليه:
org.gradle.daemon=true

يمكنك أيضًا وضع ملف gradle.properties في المجلد الأصلي لمشروعك وإلزامه بنظام التحكم في الإصدار Control Version System.

إذا لم يتم استخدام Gradle لبضع ساعات ، فإن البرنامج الخفي يتوقف تلقائيًا.

بتنفيذ Gradle مع الوسيط daemon-- في سطر الأوامر يبدأ البرنامج الخفي gradle. لإيقاف البرنامج الخفي بشكل تفاعلي، استخدم الأمر gradle --stop.

2.7. حدد إعدادات JVM المخصصة لـ Gradle

يوفر متغير البيئة GRADLE_OPTS الفرصة لتعيين خيارات JVM محددة لـ Gradle. في استخدام البرنامج الخفي Gradle لتحسين وقت بدء التشغيل، تم تحسين أداء بدء التشغيل JVM، لكن (قاتل الأداء Performance Killer) الآخر للبنيات الكبيرة يمكن أن يكون الحد الأقصى لـ(مساحة كومة heap space) صغيرة جدا. لذلك من المنطقي زيادته في Gradle.

يُعرِّف export GRADLE_OPTS=-Xmx1024m أن Gradle يمكنه استخدام 1 غيغابايت كحد أقصى لحجم الكومة.

في نظام التشغيل Windows، عادةً ما يتم تعريف متغيرات البيئة عن طريق واجهة مستخدم خاصية النظام.

إذا كنت ترغب في ضبط إعدادات JVM على المستوى العالمي ولكن على أساس كل مشروع، أضف إلى الملف ‎/gradle.properties السطر التالي:

org.gradle.jvmargs=-Xms2g -Xmx4g -XX\:MaxHeapSize\=3g

2.8. ملف ‎.gitignore النموذجي لمشاريع Gradle

إذا كنت تستخدم Git كنظام للتحكم في الإصدار، فيمكنك استخدام ملف gitignore. التالي كقالب لمشروع Gradle.

# Android built artifacts
*.apk
*.ap_
*.dex

# Java build artifacts class files
*.class

# other generated files
bin/
gen/
build/

# local configuration file (for Android sdk path, etc)
local.properties

# OSX files
.DS_Store

# Eclipse project files
.classpath
.project

# Android Studio
*.iml
.idea
.gradle


#NDK
obj/

3. تمرين: إنشاء مشروع Java باستخدام سطر أوامر Gradle

يوفر Gradle دعمًا للسقالات Scaffolding Support لإنشاء مشاريع تستند إلى Gradle عبر سطر الأوامر.

قم بإنشاء مجلد جديد new directory على نظام الملفات الخاص بك، وانتقل إليه وقم بتشغيل الأمر التالي.

gradle init --type java-library --test-framework junit-jupiter

يؤدي هذا إلى إنشاء مشروع Java يستند إلى Gradle والذي يستخدم JUnit Jupiter لاختبار الوحدة Unit Testing.

يمكنك تشغيل البناء build عبر:

gradle build

والاختبار الناتج عن هذا البناء عبر:

gradle test

سيقوم Gradle بإنشاء تقرير اختبار في مجلد /build/reports/tests/test

4. تمرين: تكوين خصائص Gradle

عند استخدام أمر gradle للمرة الأولى، يتم إنشاء مجلد gradle. في الدليل {USER_HOME}$.

عادة ما يكون home/${yourUserName}/.gradle/ على نظام Linux.

بينما يكون C:\Users\${yourUserName}.gradle على نظام Windows. أما على نظام MAC فيكون /Users/${yourUserName}/.gradle.

داخل مجلد gradle. هذا، يجب إنشاء ملف gradle.properties مع المحتويات التالية:

org.gradle.warning.mode=all

الآن سيتم تجاوز الافتراض لخاصية org.gradle.warning.mode (الافتراض هو الملخص).

اقتباس

يمكن تعيين الخصائص الشائعة أو السرية أو استبدالها هنا، على سبيل المثال، افتراضيات Gradle أو رموز الوصول للنشر- access tokens for deployment.

5. إدارة التبعية لمشاريع جافا

5.1. إدارة التبعيات باستخدام Gradle

يسمح Gradle بإدارة classpath من المشاريع الخاصة بك. يمكنه إضافة ملفات JAR أو أدلة أو مشاريع أخرى إلى مسار إنشاء التطبيق الخاص بك. كما يدعم التنزيل التلقائي لتبعيات مكتبة Java. ما عليك سوى تحديد التبعية في ملف بناء Gradle الخاص بك. مما يجعل Gradle يقوم بتنزيل المكتبة بما في ذلك التبعيات العابرة لها أثناء الإنشاء.

يتم تحديد مكتبة Java بواسطة Gradle عبر groupId:artifactId:version الخاص بمشروعها (ويُعرف أيضًا باسم GAV في Maven).

تحدد هذه الـGAV مكتبة بشكل فريد في إصدار معين.

يمكنك استخدام موقع Maven للبحث عن GAV المكتبة في Maven Central.

لإضافة تبعية، قم بإضافة إدخال إلى قسم التبعية في ملف build.gradle الخاص بك كما هو موضح في القائمة التالية.

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.squareup.okhttp:okhttp:2.5.0'
    testCompile 'junit:junit:4.12'

}

5.2. تحديد المستودعات للبحث عن التبعيات

في ملف البناء الخاص بك، يمكنك تحديد المستودعات البعيدة للبحث عن التبعيات. يدعم Gradle مستودعات Maven و Ivy للبحث عن التبعيات. توضح القائمة التالية كيفية تكوين Maven central كمصدر تبعية.

repositories {
    mavenCentral()
}

من الممكن أيضًا تكوين الهدف كعنوان URL:

repositories {
    maven {
        url "http://repo.mycompany.com/maven2"
    }
}

توضح القائمة التالية كيفية تحديد تبعية Ivy:

repositories {
    ivy {
        url "http://repo.mycompany.com/repo"
    }
}

يمكنك أيضًا إضافة مستودعات مختلفة مرة واحدة.

repositories {
    maven ("https://repository-achartengine.forge.cloudbees.com/snapshot/")
    jcenter {
        url "http://jcenter.bintray.com/"
    }
}

يمكنك أيضًا الرجوع إلى الملفات التي ينتجها المشروع من نظام الملفات.

apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
    compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
    testCompile group: 'junit', name: 'junit', version: '4.+'
    runtime files('libs/library1.jar', 'libs/library2.jar')
    runtime fileTree(dir: 'libs', include: '*.jar')
    compile fileTree(dir: "${System.properties['user.home']}/libs/cargo", include: '*.jar')
}
}

5.3. إظهار تبعيات المشروع (التبعيات العابرة أيضًا)

يعرض الأمر التالي جميع التبعيات العابرة لمشروع Gradle:

gradle dependencies
اقتباس

يسمح mvnrepository.com أيضا بالبحث عن الناتج ويظهر التبعيات مباشرة.

5.4. ذاكرة التخزين المؤقت لـ Gradle وحذف ذاكرة التخزين المؤقت

يمكنك تحديث التبعيات في ذاكرة التخزين المؤقت مع خيار سطر الأوامر refresh-dependencies--.

يمكنك أيضًا حذف الملفات المخزنة مؤقتًا ضمن gradle/cache./~ مع البناء القادم (next build)، يحاول Gradle تنزيل التبعيات مرة أخرى.

5.5.استثناء التبعيات المتعدية

في بعض الأحيان يكون لديك تبعيات على الحزم Packages التي تحدد التبعيات العابرة المتعارضة. أحد الحلول هو استبعاد التبعية من وحدة نمطية محددة:

compile 'org.springframework:spring-web:4.3.10.RELEASE' {
    exclude group: 'com.google.code.gson', module: 'gson'
}

إذا كان لديك تبعية متعددة تحدد تبعية تريد استبعادها، فيمكنك القيام بذلك على مستوى المشروع:

configurations.all {
    exclude group: 'com.google.code.gson', module: 'gson'
}

باتباع نفس النهج، يمكننا استبعاد التبعية فقط أثناء وقت التشغيل runtim:

configurations.runtime {
    exclude group: 'com.google.code.gson', module: 'gson'
}

5.6. فرض إصدار محدد من تبعية متعدية

من الممكن إجبار gradle على اختيار إصدار معين عندما يواجه التبعيات العابرة المتعارضة. ضع في اعتبارك أنه قد تضطر إلى تحديث هذا الإصدار يدويًا عندما تقوم بتحديث الحزم التي تعتمد عليه.

configurations.all {
    resolutionStrategy.force 'com.google.code.gson:gson:2.8.1'
}

6. تشغيل بناء Running a build

عند بدء إنشاء Gradle عبر سطر الأوامر، تبحث أداة أمر gradle عن ملف يسمى build.gradle في الدليل الحالي.

يدعم Gradle أيضًا اختصار المهام، على سبيل المثال، لبدء تشغيل المهمة lars، فإنّ استخدام أمر gradle l يكفي. يجب على الاختصار أن يحدد المهمة بشكل فريد، وإلا سيُظهر Gradle رسالة خطأ، توضح أن الاختصار غامض. يمكن أيضًا استخدام CamelCase للاختصار، على سبيل المثال، يمكن استدعاء المهمة gradle vogellaCompany باستخدام الأمر gradle vC.

يمكن تشغيل بناء Gradle عبر الأمر gradle أو gradle -q. الوسائط q- أو quiet-- تجعل تنفيذ Gradle أقل طولًا. يمكن معالجة مهمة محددة كالتالي: gradle -q other، والتي تنفذ المهمة "الأخرى.

يمكنك بالطبع أيضًا استخدام السكربت المجمع the Gradle wrapper script، إذا كان ذلك متاحًا.

لتحديد ملف بناء مختلف، يمكن استخدام الخيار b buildFileName-.

في السيناريوهات التي لا يتوفر فيها اتصال بشبكة، يمكن استخدام المعاملoffline--. يعمل هذا على تشغيل Gradle build دون الاتصال بالإنترنت، مما يعني أن Gradle لا يحاول الوصول إلى الموارد من الشبكة أثناء الإنشاء. على سبيل المثال، للتبعيات من مستودع إنتاج مثل Maven Central أو Bintray.

للحصول على ناتج تفصيلي لما يقوم به Gradle، يمكنك تحديد المعامل info--.

7. مهام Gradle

7.1. مهام Gradle الافتراضية

يقدم Gradle أيضًا مهامًا لاستكشاف Gradle نفسه، حيث يمكنك تحليل مشروع Gradle باستخدام مهام Gradle الافتراضية.

مثال جيد هو مهمة المهام، والتي تعرض المهام المتاحة للمشروع. عند كتابة gradle -q tasks، يتم عرض قائمة بالمهام. يسرد هذا الأمر المهام الأساسية حتى بدون ملف build.gradle.

5-DefaultGradleTask.PNG

يحاول Gradle أيضًا إعطاء بعض الإرشادات لاستخدام المهام التي تم استدعاؤها، كما هو موضح في الجزء السفلي من إخراج وحدة التحكم. سيقوم الأمر gradle tasks --all أيضًا بسرد المهام التابعة، والتي يتم استدعاؤها قبل المهمة الفعلية.

عند تشغيل gradle tasks --all يبدو الناتج مشابهًا تمامًا للملف السابق، باستثناء مهمة init التي تعتمد على المهمة wrapper.

7.2. إنشاء مهام Gradle مخصصة

في جزء gradle_runbuild_buildfile، تم إنشاء أول مهمة بسيطة في ملف build.gradle

task hello {
    doLast {
        println 'Hello Gradle'
    }
}

عند تشغيل مهمة مهام gradle -q tasks مع ملف build.gradle هذا، سيتم سرد مهمة hello ضمن "مهام أخرى Other Tasks".

6-customeGradleTasks.PNG

تعتبر المهام بدون مجموعة مهام خاصة. على سبيل المثال، لا تُظهر طريقة العرض Gradle Task View الخاصة بـ Eclipse Gradle Plug-in مثل هذه المهام. ولكن يمكن إظهارها عن طريق تنشيط الإدخال الصحيح في قائمة العرض.

يمكن تطبيق المجموعات عن طريق خاصية المجموعة group ويمكن تطبيق وصف باستخدام خاصية الوصفdescription. في حالة وجود المجموعة بالفعل، تتم إضافة مهمة hello إليها. إذا كانت المجموعة غير موجودة، فهي موجودة مُسبقًا.

task hello {
     group 'vogella'
     description 'The hello task greets Gradle by saying "Hello Gradle"'

     doFirst {
        println 'Hello Gradle'
     }
     doLast {
        println 'Bye bye Gradle'
     }
}

7.3. هيكل المهمة Task Structure

Gradle له مراحل مختلفة، عند العمل مع المهام. بادئ ذي بدء، هناك مرحلة التكوين، حيث يتم تنفيذ الكود، المحدد مباشرة في إغلاق المهمة. يتم تنفيذ كتلة التكوين لكل مهمة متوفرة وليس فقط لتلك المهام، والتي يتم تنفيذها فعليًا فيما بعد.

بعد مرحلة التكوين، تقوم مرحلة التنفيذ بعد ذلك بتشغيل الكود داخل عمليات إغلاق doFirst أو doLast لتلك المهام، والتي تم تنفيذها بالفعل.

task onlySpecifiesCodeForConfigurationPhase {
    group 'vogella'
    description 'Configuration phase task example.'

    println 'I always get printed even though, I am not invoked'
}

task anotherUnrelatedTask {
    doLast {
        println 'I am in the doLast execution phase'
    }
}

عند تنفيذ gradle -q anotherUnrelatedTask، تتم طباعة ما يلي:

I always get printed even though, I am not invoked
I am in the doLast execution phase

تأتي العبارة الأولى من مرحلة التكوين التي يتم فيها تقييم تعريف المهمة onlySpecifiesCodeForConfigurationPhase.

7.4. تبعيات مهمة Task Dependencies

يسمح Gradle بتعريف المهام الافتراضية في ملف البناء. يتم تنفيذ هذه، إذا لم يتم تحديد مهام أخرى. يمكن للمهام أيضًا تحديد تبعياتها. كلا الإعدادات موضحة في ملف البناء التالي.

defaultTasks 'clean', 'compile'

task clean {
    doLast {
        println 'Executing the clean task'
    }
}

task compile {
    doLast {
        println 'Executing the compile task'
    }
}

task other(dependsOn: 'compile') {
    doLast {
        println "I'm not a default task!"
    }
}

task cleanOther {
    doLast {
        println "I want to clean up before running!"
    }
}

cleanOther.dependsOn clean, compile

يمكن أيضًا تنفيذ ارتباطات تنفيذ المهام المحددة مسبقًا للمهام الافتراضية أو المهام من المكونات الإضافية Plug-ins باستخدام طريقة dependOn.

على سبيل المثال، عندما يَتعيّن القيام ببعض الأشياء مباشرة بعد تجميع كود جافا:

apply plugin: 'java'

task invokedAfterCompileJava(dependsOn: 'compileJava')  {
    doLast {
        println 'This will be invoked right after the compileJava task is done'
    }
}

كبديل لإنشاء مهمة جديدة، والتي تعتمد على مهمة 'compileJava'، يمكن أيضًا تطبيق كتلة تنفيذ جديدة مباشرة على مهمة موجودة، على سبيل المثال، المهمة 'compileJava':

apply plugin: 'java'

compileJava.doFirst { println 'Another action applied to the "compileJava" task' }
compileJava.doLast { println 'Another doLast action is also applied' }

عند تشغيل المهمة 'javaCompile'، يتم تنفيذ جميع الإجراءات، التي تم تطبيقها على المهمة javaCompile، واحدة تلو الأخرى وفقًا للترتيب الذي تم تطبيقه على المهمة.

7.5. تخطي مهام Skipping Tasks

يمكن تخطي المهام عن طريق تمرير إغلاق مُسند predicate closure إلى طريقة onlyIf الخاصة بالمهمة أو عن طريق طرح StopExecutionException:

task eclipse {
    doLast {
        println 'Hello Eclipse'
    }
}

// #1st approach - closure returning true, if the task should be executed, false if not.
eclipse.onlyIf {
    project.hasProperty('usingEclipse')
}

// #2nd approach - alternatively throw an StopExecutionException() like this
eclipse.doFirst {
    if(!usingEclipse) {
        throw new StopExecutionException()
    }
}
اقتباس

سيتم تشغيل المهام التي تعتمد على مهمة Eclipse حتى إذا تم طرح StopExecutionException.

7.5.1. الوصول إلى متغيرات النظام مثل دليل المستخدم الرئيسي

يمكنك الوصول إلى متغيرات النظام. على سبيل المثال، للحصول على دليل المستخدم الرئيسي، استخدم ما يلي:

def homePath = System.properties['user.home']

8. تمرين: مهام Gradle

8.1. استخدام مهمة المهام في Gradle

الهدف من هذا التمرين هو الحصول على نظرة عامة حول المهام الافتراضية، والتي يتم تسليمها افتراضيًا.

افتح سطر الأوامر وقم بتنفيذ الأمر التالي:

gradle -q tasks

8.2. استخدام المهمة help

الهدف من هذا التمرين هو الاستفادة من المهمة help المساعدة للحصول على مزيد من المعلومات حول المهام الأخرى، مثل مهمة init.

gradle -q help --task init

8.3. إنشاء مشروع Groovy

التمرين السابق على علم باستخدام المهمة init:

gradle -q init --type groovy-library

8.4. اختياري - إدخال مشروع Groovy جديد

يمكن استخدام Eclipse Buildship لإدخال المشروع إلى Eclipse IDE.

8.5 . استخدام مهمة التبعيات

من أجل رؤية تبعيات المشروع (بما في ذلك التبعيات)، يجب التذرع بمهمة التبعيات.

./gradlew dependencies

إذا تم تنفيذ تمرين الإدخال Buildship الاختياري، فيمكن أيضًا استدعاء مهمة التبعيات باستخدام طريقة العرض Gradle Tasks.

9. استخدام Gradle Wrapper

يتيح Gradle Wrapper إمكانية قيام المستخدم بتشغيل البناء باستخدام إصدار مُحدَّد مُسبقًا واستخدام إعدادات Gradle دون تثبيت Gradle محليًا. هذا المُغلِّفWrapper هو برنامج يتكون من سكربتات مرقِّعة-Patch Script على ويندوز، وسكربت للصدفة-Shell Script لأنظمة التشغيل الأخرى مثل لينكس. عند بدء تشغيل Gradle build عبر المجمع، يتم تنزيل الإصدار المحدد من Gradle تلقائيًا ويستخدم لتشغيل البناء.

يعد الـWrapper الطريقة المفضلة لبدء إنشاء Gradle، حيث يجعل تنفيذ البناء مستقلًا عن إصدار Gradle المثبت. يمكن إنشاء البرنامج النصي المجمع عن طريق gradle wrapper.

نتيجًة لذلك، يمكنك العثور على gradlew للأنظمة المستندة إلى يونكس (أنظمة التشغيل مفتوحة المصدر) و gradlew.bat لأنظمة الويندوز. يمكن استخدام هذه الملفات بدلاً من ذلك لأمر gradle، وإذا لم يتم تثبيت Gradle على الجهاز، فسيتم تنزيل Gradle وتثبيته تلقائيًا.

من الممكن أيضًا تحديد مهمة تُحدِّد إصدار البرنامج. إذا تم تنفيذ هذه المهمة، فإنها تنشئ الـWrapper وتُحمِّل الإصدار الصحيح من Gradle.

wrapper {
    gradleVersion = '4.9'
}

يمكن أيضًا تعريف إصدار Gradle Wrapper، عند إنشائه عبر سطر الأوامر الآتي:

gradle wrapper --gradle-version 4.9

بدون هذا الإصدار الصريح، ستقوم Gradle تلقائيًا باختيار أحدث إصدار.

9.1. تكوين GRADLE_OPTS لبرنامج Gradle Wrapper

يمكن أيضًا تحديد GRADLE_OPTS داخل ملف gradlew أو gradlew.bat.

#!/usr/bin/env bash

##############################################################################
##
##  Gradle start up script for UN*X
##
##############################################################################

# Add default JVM options here.
# You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS="-Xmx1024m"

#... {more lines}
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

@rem Add default JVM options here. You can also use JAVA_OPTS
# and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=-Xmx1024m

@rem ... {more lines}

10. تمرين: تكوين مهمة الـ Wrapper

تتوفر مهام مثل مهام Gradle Wrapper افتراضيًا ويمكن تعيين خصائص معينة منها، على سبيل المثال، gradleVersion مثل هذا:

wrapper {
    gradleVersion = '4.9'
}

11. تمرين - إنشاء مهام Gradle مخصصة

11.1. تمرين: مهمة Hello Gradle

قم بإنشاء مهمة helloGradle، والتي تطبع Hello Gradle مع ورشة عمل المجموعة والوصف المناسب.

ثم استخدم أمر gradlew tasks/. لرؤية مهمة helloGradle الجديدة في وحدة التحكم أو استخدام Buildship في Eclipse IDE. ثم استدعِ مهمة helloGradle عن طريق استدعاء gradlew hG/. أو مرة أخرى استخدم Buildship في Eclipse IDE.

11.2. تمرين: التبعيات بين المهام

قم بإنشاء مهمتين جديدتين الأولى تدعى LearnGroovy، تطبع Learn Groovy، والثانية learnGradle، تطبع 'Learn Gradle'. يجب أن يكون لهذه المهام تبعيات معقولة.

11.3. تمرين: عمل doFirst للمهام

قم بتعديل مهمة learnGroovy بحيث تقوم بطباعة *Install Eclipse IDE with Buildship * قبل أن تقوم بطباعة Learn Groovy.

12. تمرين: إنشاء مهمة نسخ

يمكن أيضًا إنشاء مهام جديدة واستخلاصها من مهمة أخرى وتحديد خصائص معينة لها. يمكن استخدام نوع المهمة Copy لتحديد هذه المهمة، والتي تكون قادرة على نسخ الملفات.

إنشاء مشروع جديد باستخدام ملف build.gradle التالي:

task copyFile(type: Copy) {
    from 'source'
    into 'destination'
}

قم بإنشاء مجلد مصدر داخل هذا المشروع وأضف ملف نصي إلى هذا المجلد. عند تشغيل مهمة copyFile، تقوم بنسخ الملف النصي إلى مجلد وجهة جديد.

13. تمرين: تحديد مهمة مخصصة في ملف gradle آخر

إنشاء مشروع Gradle جديد، والذي يحتوي على الهيكل التالي.

7-CustomeGradle.PNG

تبدو الفئة CheckWebsite.groovy كما يلي:

package com.example

import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

import java.io.IOException;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

class CheckWebsite extends DefaultTask {

    String url = 'http://www.vogella.com'

    @TaskAction
    void checkWebsite() {
        // check the given website by using the url
    try {
        Document doc = Jsoup.connect(url).get();
        String title = doc.title();
        println title
        println url
    } catch (IOException e) {
        e.printStackTrace();
    }
    }
}

نظرًا لأن هذا الصنف-Class بها تبعيات خارجية لـ jsoup، يجب إنشاء ملف build.gradle لها. لذلك فإن build.gradle داخل مجلد buildSrc، المسؤول عن بناء فئة CheckWebsite، يبدو كما يلي:

plugins {
    id 'groovy'
}

repositories {
   jcenter()
}

dependencies {
    compile 'org.jsoup:jsoup:1.8.3'
}

أخيرًا، يستخدم ملف build.gradle الرئيسي في المجلد الرئيسي نوع مهام جديدة مثل com.example.CheckWebsite.

task defaultWebsiteCheck(type: com.example.CheckWebsite)

task checkGradleWebsite(type: com.example.CheckWebsite) {
    url = 'https://docs.gradle.org/'
}

wrapper {
    gradleVersion = '4.9'
}

14. تمرين: بناء Gradle Trigger من كود جافا

يصف هذا التمرين كيفية تشغيل إنشاء gradle من تعليمات كود جافا.

14.1. إنشاء مشاريع جديدة لـGradle

قم بإنشاء مشروعين gradle جديدين بأسماء BaseProject (يبدأ هذا المشروع إنشاء gradle) و TargetProject (تم بناء هذا المشروع بواسطة BaseProject). تأكد من أن BaseProject يطبق البرنامج المساعد جافا Java blugin.

14.2. إضافة التبعيات

أضِف التبعية التالية إلى BaseProject.

compile 'org.gradle:gradle-tooling-api:4.0-rc-2'

14.3. إنشاء TargetProject

أُنشئ Class تحت إسم Application بطريقة static main كما يلي:

import java.io.File;

import org.gradle.tooling.BuildLauncher;
import org.gradle.tooling.GradleConnector;
import org.gradle.tooling.ProjectConnection;

public class Application {

    public static void main(String[] args) {
        ProjectConnection connection = GradleConnector.newConnector().forProjectDirectory(new File("path/to/targetproject")).connect();
        try {
            BuildLauncher build = connection.newBuild();
            build.forTasks("build");
            build.run();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            connection.close();
        }
    }
}

تقوم هذه الطريقة أولاً بإنشاء ProjectConnection للمشروع الذي يجب إنشاؤه ويتصل به. تأكد من استبدال path/to/targetproject بمسار TargetProject. من project connection، يمكن الحصول على BuildLauncher جديد. بمساعدة الدالة ()forTasks يمكنك تحديد مهام gradle التي يجب تنفيذها. يوفر BuildLauncher أيضًا بعض الطرق الأخرى لتكوين البناء. يمكنك، على سبيل المثال، تعيين عوامل بناء gradle أو تغيير إصدار Java لإنشاء المشروع بها. وعن طريق استدعاء الدالة ()run يتم تنفيذ البناء أخيرًا. تأكد من إغلاق الاتصال في البلوك الأخير.

15.بناء مشاريع جافا

15.1. البريمج التكميلي جافا Java plug-in

يوفر البريمج التكميلي Java مهامًا لتجميع كود Java وتشغيل اختبارات الوحدة وإنشاء Javadoc وإنشاء ملف JAR.

15.2. تخطيط المشروع الافتراضي لمشاريع Java

تفترض هذه المكونات الإضافية إعدادًا معينًا لمشروع Java الخاص بك (على غرار Maven).

  • src/main/java يحتوي على كود جافا الأساسي.
  • src/test/java يحتوي على اختبارات جافا.

إذا اتبعت هذا الإعداد، فسيكون ملف البناء التالي كافياً لتجميع مشروع Java واختباره وحزمه.

apply plugin: 'java'

لبدء التنفيذ، اكتب gradle build في سطر الأوامر.

يمكن استخدام SourceSets لتحديد بنية مشروع مختلفة، على سبيل المثال، يتم تخزين المصادر في مجلد src بدلاً من src/main/java.

apply plugin: 'java'

sourceSets {
    main {
         java {
              srcDir 'src'
              }
         }
    test {
         java {
              srcDir 'test'
              }
         }
}

15.3. إنشاء مشروع Java باستخدام مهمة init

لا يدعم Gradle بعد قوالب مشاريع متعددة (تسمى النماذج الأولية archetypes) مثل Maven. لكنه يوفر مهمة init لإنشاء هيكل مشروع Gradle جديد. بدون عوامل إضافية، تنشئ هذه المهمة مشروع Gradle، والذي يحتوي على ملفات gradle wrapper وملف build.gradle و settings.gradle.

عند إضافة المعامل type-- مع 'java-library' كقيمة، يتم تنفيذ بناء مشروع java ويحتوي ملف build.gradle على قالب Java معين مع JUnit.

8-JavaProjectUsingInitFunction.PNG

سيبدو ملف build.gradle مشابهًا لهذا:

/*
 * ... deleted the generated text for brevity
 */

// Apply the java plugin to add support for Java
apply plugin: 'java'

// In this section you declare where to find the dependencies of your project
repositories {
    // Use 'jcenter' for resolving your dependencies.
    // You can declare any Maven/Ivy/file repository here.
    jcenter()
}

// In this section you declare the dependencies for your production and test code
dependencies {
    // The production code uses the SLF4J logging API at compile time
    compile 'org.slf4j:slf4j-api:1.7.12'

    // Declare the dependency for your favourite test framework you want to use
    // TestNG is also supported by the Gradle Test task. Just change the
    // testCompile dependency to testCompile 'org.testng:testng:6.8.1' and add
    // 'test.useTestNG()' to your build script.
    testCompile 'junit:junit:4.12'
}

يوفر المشروع المستضاف على Github والذي يُدعى Gradle-Templates Project مزيدًا من القوالب تتجاوز مهمة init. يعمل فريق Gradle أيضًا على موضوع النموذج/القالب هذا.

عادةً ما يحتوي مشروع Java على إصدار و JRE مُستهدف يتم تجميعه عليه. يمكن تعيين خاصية version و sourceCompatibility في ملف build.gradle.

version = 0.1.0
sourceCompatibility = 1.8

عند تعيين خاصية الإصدار، سيتم تغيير اسم الناتج وفقًا لذلك، على سبيل المثال، my-lib-name} -0.1.0.jar}

إذا كان الناتج عبارة عن تطبيق جافا قابل للتنفيذ، فيجب أن يكون ملف MANIFEST.MF على دراية بالصنف Class باستخدام الدالة main.

apply plugin: 'java'

jar {
    manifest {
        attributes 'Main-Class': 'com.example.main.Application'
    }
}

16. بناء مشاريع Groovy

16.1. البريمج التكميلي جروفي Groovy Plugin

يعمل البريمج التكميلي Groovy في Gradle على تمديد البريمج التكميلي Java ويوفر مهامًا لبرامج Groovy.

apply plugin: 'groovy'

repositories {
  mavenCentral()
}
dependencies {
    implementation 'org.codehaus.groovy:groovy-all:2.4.5'
    testImplementation 'junit:junit:4.12'
}

لكي تبدأ البناء، اكتب gradle build في سطر الأوامر.

16.2. الشكل الافتراضي لمشاريع Groovy

تفترض هذه البريمجات التكميلية

  • src/main/groovy يحتوي على الكود الأصلي لـ Groovy.
  • src/test/groovy يحتوي على اختبارات Groovy.
  • src/main/java يحتوي على الكود الأصلي لـ Java.
  • src/test/java يحتوي على اختبارات Java.

إذا تتبّعت هذا الإعداد، يكون ملف البناء التالي كافياً لتجميع مشروع Groovy واختباره وتعبئته.

17. اختبارات مع Gradle

17.1. تنفيذ 5 اختبارات JUnit مع Gradle

لاستخدام 5 اختبارات جافا، أضف ما يلي إلى نهاية الـ dependencies في ملف 'build.gradle` الخاص بك. استخدم Gradle 6.0 على الأقل لهذا لتجنب المشكلات التي تم إصلاحها بالفعل.

dependencies {

    // more stuff
    testImplementation(enforcedPlatform("org.junit:junit-bom:5.4.0")) // JUnit 5 BOM
    testImplementation("org.junit.jupiter:junit-jupiter")
}

17.2. اختبار اصطلاحات التسمية لـ Gradle

تفحص مهمة "test" في Gradle جميع الفئات المترجمة في المجلد المصدر للمشروع، على سبيل المثال،

src/test/java أو /src/test/groovy/. يتم تحديد أصناف JUnit بواسطة:

  • Class أو Super Class يوسِّع TestCase أو GroovyTestCase.

  • الـ Class أو Super Class يُرمز أليهم بـ RunWith@.

  • يحتوي الـ Class أو Super Class على دالة يُرمز إليها بـ Test@.

يمكنك تعيين خاصية scanForTestClasses إلى false، إذا كنت لا تريد الكشف التلقائي عن فئة الاختبار. في هذه الحالة، إذا لم يتم تحديد أنماط تضمين/استبعاد إضافية، فإن الإعدادات الافتراضية للفئات المضمنة هي "Tests.class”, “/*Test.class/” والفئات المُستثناة الافتراضية هي"Abstract * .class /*".

17.3. تضمين واستبعاد اختبارات معينة

يتم وصف تكوين الاختبار بشكل عام في وصف مهام اختبار جرادل Gradle Test Tasks Description.

فئة الاختبار teast Class لديها دوال include وexclude. يمكن استخدام هذه الدوال لتحديد الاختبارات التي يجب تشغيلها بالفعل.

تشغيل الاختبارات المضمنة included tests فقط:

test {
    include '**my.package.name/*'
}

تخطي الاختبارات المستبعدة excluded tests:

test {
    exclude '**my.package.name/*'
}

17.4. إظهار كل نواتج الاختبار في الطرفية Terminal

بشكل افتراضي، لا يقوم Gradle بطباعة الناتج القياسي لاختباراتك على الطرفية Terminal. لمشاهدة جميع مخرجات اختباراتك، أضف هذا إلى ملف البناء الخاص بك:

test {
    testLogging.showStandardStreams = true
}

18. بناء مشاريع متعددة مع Gradle

18.1. إنشاء هيكل بناء مشروع متعدد

عادةً لا يتألف تطبيق الأعمال من مشروع / وحدة واحدة فقط ، ولكن يحتوي على العديد من المشاريع، والتي يجب أن يتم بناؤها.

لدى Gradle مفهوم المشروع الأساسي The root project، والذي يمكن أن يحتوي على العديد من المشاريع الفرعية. يتم تحديد المشروع الأساسي بواسطة ملف build.gradle، مثل المشاريع الفردية من قبل. لتحديد، ما هي المشاريع التي تنتمي إلى البناء يتم استخدام ملف settings.gradle.

على سبيل المثال، قد يكون هناك هيكل المشروع هذا:

  • root_project

  • core

  • ui

  • util

  • settings.gradle

وجود بنية المشروع هذا، سيبدو ملف الإعدادات settings.gradle هكذا:

include 'core', 'ui', 'util'

# altenative way would be
#include 'core'
#include 'ui'
#include 'util'

إلى جانب المهمة tasks، يوفر Gradle أيضًا المهمة المساعدة projects، والتي يمكن تنفيذها في المجلد root_project.

> gradle projects

9-RootProject.PNG

18.2. تحديد تكوين بناء عام

في ملف build.gradle في التكوينات العامة root_project يمكن تطبيقها على جميع المشاريع أو على المشروعات الفرعية فقط.

allprojects {
    group = 'com.example.gradle'
    version = '0.1.0'
}

subprojects {
    apply plugin: 'java'
    apply plugin: 'eclipse'
}

يحدد هذا مجموعة com.example.gradle مشتركة وإصدار 0.1.0 لجميع المشاريع.

تُطبِّق نهاية المشروعات الفرعية تكوينات شائعة على جميع المشروعات الفرعية، ولكن ليس على المشروع الأصلي، كما هو الحال في نهاية all projects.

18.3. تكوينات محددة المشروع والتبعيات

يمكن أن يكون للـ core و ui و util (هيكل الـ root project في المشروع كما وضحنا ذلك في الجزء 19.1) الخاصين بالمشروعات الفرعية ملف build.gradle خاص بها أيضًا. إذا كانت لديهم احتياجات محددة، والتي لم يتم تطبيقها بالفعل عن طريق التكوين العام للمشروع الأصلي.

على سبيل المثال، عادةً ما يكون لمشروع واجهة المستخدم ui تبعية للمشروع الأساسي. لذا يحتاج مشروع واجهة المستخدم إلى ملف build.gradle الخاص به لتحديد هذه التبعية.

dependencies {
    compile project(':core')
    compile 'log4j:log4j:1.2.17'
}

يتم تحديد تبعيات المشروع مع دالة المشروع project method.

اقتباس

الـ : قبل أن يكون مرجع المشروع الأساسي فهو خاص بـ Gradle ويعمل إلى حد كبير مثل شرطة مائلة (/) ، عند الرجوع إلى هيكل المجلد.

بدلاً من ذلك، يمكنك أيضًا تحديد تبعيات مشروع في ملف build.gradle الأصلي. ولكن يعتبر ممارسة جيدة لتحديد التبعيات في ملفات build.gradle المحدّدة الخاصة بالمشروع، وبالتالي يتم تضمين النهج التالي فقط لغرض العرض التوضيحي.

allprojects {
 apply plugin: 'java'

 repositories {
  mavenCentral()
 }

}

project(':com.example.core').dependencies {
    compile project(':com.example.model')
    compile 'log4j:log4j:1.2.17'
}

19. النشر مع Gradle

19.1. كيفية النشر باستخدام Gradle

يوفر Gradle عدة طرق لنشر عناصر البناء في مستودعات الإنتاج، مثل Artifactory أو Sonatyp Nexus.

19.2. باستخدام المافن نشر البريمج التكميلي Using the maven-publish plugin

الطريقة الأكثر شيوعًا هي استخدام المكون الإضافي maven-publish، والذي يوفره Gradle افتراضيًا.

// other plug-ins
apply plugin: 'maven-publish'

publishing {
    publications {
        mavenJava(MavenPublication) {
            from components.java
        }
    }

    repositories {
        maven {
            url "$buildDir/repo"
        }
    }
}

هناك العديد من خيارات النشر ، عندما يتم تطبيق java والمكون الإضافي maven-publish.

10-GradleDeployment.PNG

يمكن إجراء النشر إلى مستودع منفصل مثل هذا:

apply plugin: 'groovy'
apply plugin: 'maven-publish'

group 'workshop'
version = '1.0.0'

publishing {
    publications {
        mavenJava(MavenPublication) { from components.java }
    }

    repositories {
        maven {
            // default credentials for a nexus repository manager
            credentials {
                username 'admin'
                password 'admin123'
            }
            // url to the releases maven repository
            url "http://localhost:8081/nexus/content/repositories/releases/"
        }
    }
}

يمكن العثور على مزيد من المعلومات حول النشر إلى مستودع Maven للإنتاج هنا: Publish to Maven repository with Gradle.

20. التكامل مع Ant

يدعم Gradle تشغيل مهام Ant عبر برنامج Groovy AntBuilder.

21. تحويل مشاريع Groovy إلى Gradle

يوفر Gradle مهمة init المحتضنة، والتي تساعد في إنشاء مشاريع Gradle جديدة. يمكن لهذه المهمة أيضًا تحويل ملفات Apache Maven pom.xml إلى ملفات بناء Gradle، إذا كانت جميع المكونات الإضافية المستخدمة في Maven معروفة لهذه المهمة.

في هذا الجزء، سيتم تحويل Groovy pom.xml التالي إلى مشروع Gradle.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example.app</groupId>
    <artifactId>example-app</artifactId>
    <packaging>jar</packaging>
    <version>1.0.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

يؤدي تشغيل gradle init --type pom في سطر الأوامر إلى تكوين Gradle الآتي.

11-ConvertMavenToGradle.PNG

تعتمد مهمة init على مهمة Wrapper بحيث يتم أيضًا إنشاء Gradle Wrapper.

يشبه ناتج ملف build.gradle الآتي:

apply plugin: 'java'
apply plugin: 'maven'

group = 'com.example.app'
version = '1.0.0-SNAPSHOT'

description = """"""

sourceCompatibility = 1.5
targetCompatibility = 1.5

repositories {
     maven { url "http://repo.maven.apache.org/maven2" }
}

dependencies {
    testImplementation group: 'junit', name: 'junit', version:'4.11'
}

22. تطوير مكونات Gradle الإضافية Gradle Plug-ins

22.1. لماذا نُنشيء مكونات Gradle الإضافية؟

كقاعدة عامة، من المفيد أن يكون هناك بناءً تصريحيًا declarative build بأكبر قدر ممكن لأن هذا يُبسِّط التعديلات المستقبلية. لذلك يُنصح بتجنب التعليمات البرمجية المعقدة في ملف بناء Gradle الخاص بك. إذا كنت بحاجة إلى منطق مخصص، فيجب وضعه في مكون إضافي مخصص لـ Gradle.

22.2. Gradle DSL

يأتي كل مكون إضافي من Gradle مزودًا بخدمة DSL. لمشاهدة جميع خصائص كائن Gradle، يمكنك استخدام مقتطف التالي من الكود:

println variants.properties
            .sort{it.key}
            .collect{it}
            .findAll{!filtered.contains(it.key)}
            .join('\n')

على سبيل المثال، لتحديد المهام التي تعرض جميع خصائص android.applicationVariants (في مشروع أندرويد)، استخدم:

task showAndoidVariantsInformation {
    doLast {
        android.applicationVariants.all { variants ->
            println variants.properties
            .sort{it.key}
            .collect{it}
            .findAll{!filtered.contains(it.key)}
            .join('\n')
        }
    }
}

23. تمرين: إنشاء برنامجًا مساعدًا بسيطًا Simple Gradle Plugin

تعمل الأداة الإضافية java-gradle-plugin على تبسيط إنشاء مكونات إضافية مخصصة لـ Gradle. هذا البرنامج المساعد في طور الإعداد حاليًا. يفعل ما يأتي:

  • تتم إضافة التابع ()gradleApi تلقائيًا.
  • تتم إضافة التابع ()gradleTestKit تلقائيًا.
  • تتم إضافة ملفات واصف المكونات الإضافية الضرورية تلقائيًا.

23.1. إنشاء مشروع Gradle

حدِّد Gradle Project < Gradle < Other < new < File في Eclipse لإنشاء مشروع Gradle جديد. ضع com.vogella.gradleplugin ليكون اسم المشروع كما هو موضّح.

12-NewGradleProject.PNG

التزم بالإعدادات الافتراضية للمعالج وقم بإنشاء المشروع.

23.2. قم بتطبيق المكون الإضافي "java-gradle-plugin"

غيِّر ملف build.gradle إلى ما يلي:

plugins {
    id 'java-gradle-plugin'
}

gradlePlugin {
    plugins {
        vogellaPlugin {
            id = 'com.vogella.gradleplugin'
            implementationClass = 'com.vogella.gradleplugin.MyPlugin'
        }
    }
}

repositories {
    jcenter()
}

dependencies {
    // No need to add gradleApi() here, because it is applied by the 'java-gradle-plugin' plug-in

    // We want to merge and parse SpotBugs xml files with XSLT
    compile('net.sf.saxon:Saxon-HE:9.8.0-12')
    // Use JUnit test framework
    testImplementation 'junit:junit:4.12'
}

wrapper {
    gradleVersion = '4.9'
}

في مجلد src/main/java/، قم بإنشاء الصنفين Classes التاليتين.

package com.vogella.gradleplugin;

import org.gradle.api.DefaultTask;
import org.gradle.api.tasks.TaskAction;

public class MyTask extends DefaultTask {

    @TaskAction
    public void myTask() {
        System.out.println("Hello from vogella task");
    }
}
package com.vogella.gradleplugin;

import org.gradle.api.Plugin;
import org.gradle.api.Project;

public class MyPlugin implements Plugin<Project> {

    @Override
    public void apply(Project project) {
        project.getTasks().create("myTask", MyTask.class);
    }

}

قم بتنفيذ المهمة build لإنشاء مكون إضافي وانظر التدريبات التالية حول كيفية نشر المكون الإضافي واستخدامه.

24. تمرين: قم بنشر المكونات الإضافية المخصصة لـ Gradle في مستودع Maven المحلي

أضف المكوّن الإضافي Gradle-plugin ومغلِّف النشر publishing closur إلى ملف build.gradle.

plugins {
    id 'java-gradle-plugin'
    id 'maven-publish'
}

group = 'com.vogella'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

// ... more code

publishing {
    publications {
        mavenJava(MavenPublication) {
            from components.java
        }
    }
}

تتوفر الآن مهام نشر إضافية ويمكن استخدام مهمة publishToMavenLocal لإضافة مكون Gradle الإضافي إلى مستودع Maven المحلي.

./gradlew pTML

25. تمرين: استخدام المكون الإضافي الجديد

لاستخدام مكون Gradle الجديد، يجب تحديد تبعية له. إذا دفعت مكونك الإضافي إلى مستودع Maven المحلي، فيجب على Gradle العثور عليه وإتاحته.

buildscript {
    repositories {
        mavenLocal()
    }
    dependencies {
        classpath 'com.vogella:com.vogella.gradleplugin:0.0.1-SNAPSHOT'
    }
 }

apply plugin: 'com.vogella.gradleplugin'

الآن المهمة الجديدة من com.vogella.gradleplugin يجب أن تكون متاحة:

./gradlew tasks

./gradlew myTask

26. تمرين: -اختياري- نشر المكوّن الإضافي في مدخل المكوّن الإضافي جرادل Gradle Plug-in Portal

لنشر مكون إضافي من نوع Gradle في مدخل Gradle Plug-in، يمكن استخدام com.gradle.plugin-publish.

قبل تحميل مكونات Gradle الإضافية إلى البوابة ، يجب عليك التسجيل على https://plugins.gradle.org/user/register والحصول على مفاتيح api من ملفك الشخصي.

13-PublishingGradlePluginToGradlePluginPortal.PNG

يجب إضافة خصائص gradle.publish.key و gradle.publish.secret إلى gradle.properties.

اقتباس

عادةً ما يكون ملف gradle.properties موجودًا في (usually /${user.home}/.gradle)

بعد ذلك ، يجب تعديل ملف build.gradle ليتمكن من تحميل مكونات Gradle الإضافية.

plugins {
    id 'java-gradle-plugin'
    id 'maven-publish'
    id 'com.gradle.plugin-publish' version '0.9.10'
}

// more code ...

pluginBundle {
    website = '${Web site for your plugin}'
    vcsUrl = 'https://github.com/${your-repo}'

    plugins {
        vogellaPlugin {
            id = 'com.vogella.gradleplugin'
            displayName = 'Vogella Sample Plug-in'
            description = 'Vogella Sample Plug-in for trying the '
            tags = ['Vogella','Training','Gradle','Sample']
            // Gradle's plug-in portal does not support SNAPSHOTs
            version = '0.0.1'
        }
    }
}

يمكن بعد ذلك استخدام المهمة التالية لتحميل المكوّن الإضافي Gradle.

./gradlew publishPlugins

عند نشر المكون الإضافي، يمكن استخدام نهايات المكونات الإضافية للاستفادة من مكون Gradle الإضافي.

plugins {
  id "com.vogella.gradleplugin" version "0.0.1"
}

لذلك يمكن حذف النهايات المطوّلة بشكل أكبر وأيضًا دالة المكوِّن الإضافي apply من الفصول السابقة.

المزيد من التفاصيل تجدها هنا.

27. تصحيح إضافات غرادل Gradle Plug-ins

27.1. تنشيط تصحيح الأخطاء عن بُعد

يجب تحديد الخصائص التالية في ملف gradle.properties لتمكين تصحيح الأخطاء عن بُعد:

org.gradle.daemon=true
org.gradle.jvmargs=-XX:+HeapDumpOnOutOfMemoryError -Xmx4g -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5006

عند تشغيل بناء Gradle محليًا باستخدام هذه الإعدادات، يمكن الوصول إلى تصحيح الأخطاء عن بُعد عبر مضيف محلي localhost على المنفذ 5006.

اقتباس

عادةً ما يكون ملف gradle.properties موجودًا في gradleHomeDir (عادةً user.home}/.gradle}$/)

27.2. تصحيح الأخطاء عن بُعد في Eclipse IDE

يجب عليك إدخال مكون إضافي معين إلى Eclipse IDE باستخدام أدوات Buildship. بعد ذلك، يمكنك إضافة نقاط التوقف break points إلى الملفات الأساسية للمكون الإضافي.

بعد ذلك، افتح تكوين تصحيح الأخطاء Debug Configuration وانقر بزر الفأرة الأيمن فوق Remote Java Application لإنشاء Debug Configuration جديد باستخدام الإعدادات التالية:

14-RemoteDebuggingInEclipse.PNG

اضغط على الزر Debug لتشغيل مصحح الأخطاء عن بُعد remote debugger.

15-Debug.PNG

بعد ذلك، يمكن تشغيل بناء Gradle، الذي يستخدم مكون Gradle الإضافي المطلوب، إما باستخدام طريقة عرض مهام Gradle لأداة Buildship داخل Eclipse IDE أو استدعاء بناء Gradle من سطر الأوامر.

عند الوصول إلى نقطة توقف أثناء مهمة Gradle، فإن Eclipse IDE سوف يتوقف عند هذه النقطة.

16-BreakPoint.PNG

28. استخدام أدوات تحليل الكود

يوفر Gradle عدة مكونات إضافية لتحليل قاعدة الكود لمشروع Gradle.

الجدول 1. أدوات تحليل كود Gradle

الأداة Plug-in الوصف
Checkstyle checkstyle التحقق من صحة قواعد checkstyle، والتي يتم تطبيقها على المشروع.
Jacoco jacoco يتحقق من تغطية الاختبار للكود الذي يجري بناؤه.
FindBugs findbugs تحليل الكود الثابت للجافا.
CodeNarc codenarc تحليل الكود الثابت لـGroovy.
PMD pmd يضيف اختبارات جودة الكود لعدة لغات برمجة.
JDepend jdepend أداة تحليل التعليمات البرمجية الأخرى لتحليل التبعيات في كود الجافا.

28.1. Jcoco لمشاريع Gradle

لاستخدام Jacoco لتحليل مدى تغطية الاختبار-Code Coverage، يجب إضافة الكود التالي إلى ملف build.gradle ذي المستوى الأعلى.

plugins {
    id 'jacoco'
}

jacocoTestReport {
    reports {
        xml.enabled true
        html.enabled true
    }
}

إذا كان لديك مشروع Gradle متعدد المشروعات، فأنت بحاجة إلى إضافة jacocoTestReport والمكون الإضافي jacoco إلى قسم المشاريع الفرعية في ملف build.gradle ذي المستوى الأعلى.

plugins {
    id 'jacoco'
}

subprojects {

    apply plugin: 'jacoco'

    jacocoTestReport {
        reports {
            xml.enabled true
            html.enabled true
        }
    }
}

إذا كنت ترغب في الحصول على ملف xml مدمج لجميع المشروعات الفرعية، على سبيل المثال لاستخدام SonarQube، يمكنك إنشائه بالمهمة التالية في build.gradle ذي المستوى الأعلى.

task generateMergedReport(type: JacocoReport) {
    dependsOn = subprojects.test

    additionalSourceDirs.setFrom files(subprojects.sourceSets.main.allSource.srcDirs)
    sourceDirectories.setFrom files(subprojects.sourceSets.main.allSource.srcDirs)
    classDirectories.setFrom files(subprojects.sourceSets.main.output)

    executionData.setFrom project.fileTree(dir: '.', include: '**/build/jacoco/test.exec')

    reports {
        xml.enabled true
        xml.destination file("../coverage-reports/coverage.xml")
    }
}

ستقوم هذه المهمة بحفظ ملف XML الموحد في المستوى العلوي من المشروع ضمن تقارير التغطية.

أخيرًا لإنشاء ملف xml مدمج، قم بتشغيل Gradle باستخدام المهمة التي تم إنشاؤها generMergedReport.

./gradle clean build generateMergedReport

29. Gradle

حقوق النشر والترخيص والكود

يتم منح الاستخدام المجاني لأمثلة البرامج بموجب شروط Eclipse Public License 2.0. المقال مترجم وبتصرف للمقال The Gradle build system- Tutorial





تفاعل الأعضاء


لا توجد أيّة تعليقات بعد



يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن