سیاق و مقصد

شروع کرنے کا נקutta

پروجیکٹ`slider-gradle`Gradle پلاگین کے ذریعے AsciiDoc فائلوں سے Reveal.js پیشنِیشنز بناتا ہے`org.asciidoctor.jvm.revealjs`. مرکزی کام کی تنظیم`asciidoctorRevealJs`جڑ buildscript میں بی واسطہ رہتا تھا`build.gradle.kts`(No output - empty string)

plugins { id("org.asciidoctor.jvm.revealjs") }

apply<slides.SlidesPlugin>()

project.tasks.getByName<AsciidoctorJRevealJSTask>(TASK_ASCIIDOCTOR_REVEALJS) {
    repositories { ruby { gems() } }
    revealjs {
        version = "3.1.0"
        templateGitHub {
            setOrganisation("hakimel")
            setRepository("reveal.js")
            setTag("3.9.1")
        }
    }
    revealjsOptions {
        // ... configuration complète
    }
}

الهدف

اس تمام کنفیگریشن میں منتقل کریں`buildSrc/src/main/kotlin/slides/SlidesPlugin.kt`اس طوریے سے کہ consumerscript buildscript کم ہو جائے:

apply<slides.SlidesPlugin>()

پلاگین کو مکمل طور پر خودمختار ہونا چاہیے: وہ خود اپنی پلاگین کی انحصارات لاگو کرتا ہے، اپنے ریپوزٹریز کنفیجر کرتا ہے، اور اپنی روبی gems کو منجاتا ہے۔

پہلا رکاوٹ : `ruby { gems() }

گراوی کے سینٹیکس شُگر جو چھپاتا ہے

خط`repositories { ruby { gems() } }`یہ Groovy DSL ایک extension ہے جو صرف buildscript کے execution context میں دستیاب ہے۔ یہ buildSrc سے قابل رسائی ہونے والی/static Kotlin API نہیں ہے۔

اس کو فون کرنے کی کوشش کرتے ہوئے`SlidesPlugin.kt`, کمپائلش فوراً ناکام ہو جاتی ہے۔

مکانیزم کا تجزئة

Gradle کیش کے تجزیے کے بعد (~/.gradle/caches/modules-2/files-2.1/rubygems/)، ہمیں فائل میں ملتا ہے`ivy-3.1.0.xml`آپ ایک پیشہ ور مترجم ہیں۔ فرانسیسی سے اردو میں ترجمہ کریں۔ تمام بیک ٹک کوڈ اسپینز (…​) کو بالکل ویسے ہی برقرار رکھیں — بیک ٹک کے مواد، اسپیسنگ، یا پوزیشن میں کبھی تبدیلی نہ کریں۔ یہ متن ایک بڑے جملے کا جزو ہو سکتا ہے — مزید سیاق و سباق مانگے بغیر اس جزو کا ترجمہ کریں۔ صرف ترجمہ شدہ متن فراہم کریں — کوئی وضاحت، کوئی تبصرہ، کوئی تعارف، کوئی متبادل، یا کوئی آپشن نہیں ہونا چاہیے۔

<artifact type='gem' url='https://rubygems.org/gems/asciidoctor-revealjs-3.1.0.gem' />

ruby { gems() }`دراصل کر رہا تھاتین الگ آپریشنزبراہ کرم اپنی `token فراہم کریں تاکہ ہم آپ کے اکاؤنٹ تک رسائی حاصل کر سکیں۔

  1. ایوی ریپو کو …​ کی طرف انظار رکھتے ہوئے محفوظ کریں`https://rubygems.org/gems/`

  2. گروپ کو خارج کریں`rubygems`Maven کے ریپوزٹریوں کے لئے ٹکراؤ سے بچنے کے لیے

  3. gem کو کنفیگری میں محفوظ کریں`asciidoctorGems`جس طرح سے JRuby اسے رنٹائم پر لوڈ کرتا ہے

ان تین ذمہ داریوں کو Kotlin میں الگ الگ سے دوبارہ تیار کرنا ہوگا۔

تیس حصوں کا حل

حصہ 1 : آئی وی ریپو RubyGems کے لیے

project.repositories.mavenCentral() {
    content { excludeGroup("rubygems") }
}
project.repositories.ivy {
    url = project.uri("https://rubygems.org/gems/")
    patternLayout { artifact("[module]-[revision].gem") } (1)
    metadataSources { artifact() }
    content { includeGroup("rubygems") }
}
1 اضافہ`.gem`اسے ہارڈ کوڈ کردینا چاہیے۔[ext]`ڈیفالٹ میں حل کرتا ہے.jar`, جس سے ایک غلطی ہوتی ہے`Resource missing`.

نوٹ: آئی وی ریpository (Ivy) مستقیماً بیان کیا گیا پر`project.repositories` اور ایک بلاک میں نہیں`repositories { }`کیونکہ اس بلوک کا ریسیور یہ نہیں`RepositoryHandler`Gradle کا معیار لیکن ایک API grolifant extension کے ساتھ موافق نہیں`ivy`Kotlin DSL.

حصہ 2: اسکیڈاکٹر جیمز پر انحصار

پلگ ان`org.asciidoctor.jvm.gems`پہلے لاگو کیا جانا چاہیے — یہ کنفیگریشن بناتا ہے`asciidoctorGems`اور کام`asciidoctorGemsPrepare`آپ ایک پیشہ ور مترجم ہیں۔ فرانسیسی سے اردو میں ترجمہ کریں۔ تمام بیکٹک کوڈ اسپینز (…​) کو بالکل ویسے ہی برقرار رکھیں — ان کے مواد، سپیسنگ، یا پوزیشن میں کبھی تبدیلی نہ کریں۔ یہ متن کسی بڑے جملے کا ایک حصہ ہو سکتا ہے — مزید سیاق و سباق کی درخواست کیے بغیر اس حصے کا ترجمہ کریں۔ صرف ترجمہ شدہ متن فراہم کریں — کوئی وضاحت، کوئی تبصرہ، کوئی تعارف، کوئی متبادل، یا کوئی آپشن نہ دیں۔

project.plugins.apply("org.asciidoctor.jvm.gems")
project.plugins.apply("org.asciidoctor.jvm.revealjs") (1)

project.dependencies {
    add("asciidoctorGems", "rubygems:asciidoctor-revealjs:3.1.0@gem") (2)
}
1 لاگو کرنے کا ترتيب اہم ہے :`gems`پہلے`revealjs`. <2> معیار`@gem`انحصار پر صحیح ایکسٹینشن لاگو کریں

بخش 3 : settings.gradle.kts

`dependencyResolutionManagement`میں`settings.gradle.kts`پروجیکٹس اپنی اپنی ریپوزٹریوں کو اعلان کرنے کی اجازت دینا چاہیے :

@Suppress("UnstableApiUsage")
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.PREFER_PROJECT)
}

اس لائن کے بغیر، Gradle پلاگن میں اعلان کردہ ریپازٹریوں کو نظرانداز کرتا ہے اور gemز کی حل خراب ہو جاتی ہے۔

API کی انٹروسپکشن بائٹ کوڈز سے

کیوں javap ?

پلاگین`asciidoctor-gradle-jvm-slides`نسخة میں`4.0.0-alpha.1`. اس کی دستاویزات غیر موجودہ یا ناقص ہیں۔ ایکمتبادل معتبر ذریعہ صرف مستخرج کلاسوں کی مستقیم تفتیش ہے۔

کام کی ہئرچھی

javap -p -classpath asciidoctor-gradle-jvm-slides-4.0.0-alpha.1.jar \
  org.asciidoctor.gradle.jvm.slides.AsciidoctorJRevealJSTask

نتیجہ :

public class AsciidoctorJRevealJSTask
  extends org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask
  implements org.asciidoctor.gradle.base.slides.SlidesToExportAware

كشف `forkOptions

جائزہ لیتے`AbstractAsciidoctorTask`:

javap -p -classpath asciidoctor-gradle-jvm-4.0.0-alpha.1.jar \
  org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask | grep -i "fork\|exec\|jvm"

پایا جاتا ہے:

final org.ysb33r.grolifant.api.v4.JavaForkOptions javaForkOptions;
public void forkOptions(org.gradle.api.Action<org.ysb33r.grolifant.api.v4.JavaForkOptions>);
public static final org.asciidoctor.gradle.base.process.ProcessMode JAVA_EXEC;

جافافورک آپشنز (grolifant) کی API

`javaLauncher`یہ کام پر موجود نہیں ہے۔ واقعی API کا`org.ysb33r.grolifant.api.v4.JavaForkOptions`عرض :

public void executable(java.lang.Object);  (1)
public void setExecutable(java.lang.Object);
1 طریقہ`executable(Object)`املا بدل دیتی ہے`executable = …​`جو کامپائل نہیں ہوتا (`val`نہیں دوبارہ قدر دی جا سکتا ہے).

RevealJSExtension

`revealjs { }`ٹاسک کا میتھڈ نہیں ہے بلکہ ایکپروجیکٹ کی توسیعPlease provide the text you would like me to translate.

javap -p -classpath asciidoctor-gradle-jvm-slides-4.0.0-alpha.1.jar \
  org.asciidoctor.gradle.jvm.slides.RevealJSExtension

یہ رسائی کے ذریعے حاصل ہے :

project.extensions.getByType<RevealJSExtension>().apply {
    version = "3.1.0"
    templateGitHub {
        setOrganisation("hakimel")
        setRepository("reveal.js")
        setTag("3.9.1")
    }
}

جاوے ٹولچین کی کنفیگریشن

JavaToolchainService کا مسئلہ

`JavaToolchainService`یہ پروجیکٹ کی اضافہ نہیں ہے۔ مندرجہ ذیل کال ناموظف ہو جاتا ہے:

// ERREUR : Extension of type 'JavaToolchainService' does not exist
project.extensions.getByType<JavaToolchainService>()

درست API ہے`serviceOf`:

import org.gradle.kotlin.dsl.support.serviceOf

project.tasks.getByName<AsciidoctorJRevealJSTask>(TASK_ASCIIDOCTOR_REVEALJS) {
    setInProcess("JAVA_EXEC")
    forkOptions {
        executable(
            project.serviceOf<JavaToolchainService>()
                .launcherFor {
                    languageVersion.set(JavaLanguageVersion.of(17))
                    vendor.set(JvmVendorSpec.ADOPTIUM)
                }
                .get()
                .executablePath
                .asFile
                .absolutePath
        )
    }
}

ڈوکر خودکار تشخیص

سیاق

Asciidoctor/JRuby پلاگین Java 17 کی ضرورت ہوتی ہے۔ Kotlin 2.0.x buildSrc میں Java 25 کی سپورٹ نہیں کرتا۔ (ورژن پارس کراش ہوتا ہے پر`"25.0.2"`) گریڈیل ڈیمون کو اس لیے جاوا 17 پر چلنا پڑتا ہے یا ڈاکر استعمال کرنا پڑے گا۔

استراتژی

  1. Docker دستیاب → اجرا کے زیرے container`eclipse-temurin:17`(پیش فرض رویہ)

  2. ڈوکر غائب + جاوے 17 → مقامی تنفیذ

  3. Docker موجود نہیں + Java > 17 → واضح خطا

val isDockerAvailable = try {
    Runtime.getRuntime().exec(arrayOf("docker", "info")).waitFor() == 0
} catch (e: Exception) {
    false
}

val javaVersion = JavaVersion.current().majorVersion.toInt()

when {
    isDockerAvailable -> project.tasks.register<Exec>(TASK_ASCIIDOCTOR_REVEALJS) {
        group = GROUP_TASK_SLIDER
        description = "Slider settings and generation (via Docker)"
        dependsOn(TASK_CLEAN_SLIDES_BUILD)
        finalizedBy(TASK_DASHBOARD_SLIDES_BUILD)
        commandLine(
            "docker", "run", "--rm",
            "-v", "${project.rootDir.absolutePath}:/workspace",
            "-v", "${System.getProperty("user.home")}/.gradle:/root/.gradle",
            "-w", "/workspace",
            "eclipse-temurin:17",
            "./gradlew", TASK_ASCIIDOCTOR_REVEALJS
        )
        workingDir = project.rootDir
    }
    javaVersion == 17 -> {
        project.repositories.mavenCentral() {
            content { excludeGroup("rubygems") }
        }
        project.repositories.ivy {
            url = project.uri("https://rubygems.org/gems/")
            patternLayout { artifact("[module]-[revision].gem") }
            metadataSources { artifact() }
            content { includeGroup("rubygems") }
        }
        project.extensions.getByType<RevealJSExtension>().apply {
            version = "3.1.0"
            templateGitHub {
                setOrganisation("hakimel")
                setRepository("reveal.js")
                setTag("3.9.1")
            }
        }
        project.tasks.getByName<AsciidoctorJRevealJSTask>(TASK_ASCIIDOCTOR_REVEALJS) {
            setInProcess("JAVA_EXEC")
            forkOptions {
                executable(
                    project.serviceOf<JavaToolchainService>()
                        .launcherFor {
                            languageVersion.set(JavaLanguageVersion.of(17))
                            vendor.set(JvmVendorSpec.ADOPTIUM)
                        }
                        .get()
                        .executablePath
                        .asFile
                        .absolutePath
                )
            }
            // ... reste de la configuration
        }
    }
    else -> error(
        "Docker est requis pour exécuter $TASK_ASCIIDOCTOR_REVEALJS " +
        "avec Java $javaVersion. Installez Docker ou utilisez Java 17."
    )
}

نتیجہ خاتم

صارف buildscript

apply<slides.SlidesPlugin>()

یہ سب ہے۔ پلاگ این پورے ذمہ دار ہے۔

settings.gradle.kts

pluginManagement {
    repositories {
        mavenLocal()
        gradlePluginPortal()
    }
}

plugins {
    id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
}

@Suppress("UnstableApiUsage")
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.PREFER_PROJECT)
}

rootProject.name = "slider-gradle"

جالات اور حل کی خلاصہ

مشکل سبب حل

`ruby { gems() }`Kotlin میں دستیاب نہیں

صرف گرووی DSL ایکسٹینشن

три الگ الگ مکیانزمات : Ivy ریپو + استثناء Maven +asciidoctorGems

Gradle aik dhoondh raha hai`.jar`ایک کی جگہ`.gem`

`[ext]`حل کرتا ہے میں`jar`پیش فرض

سخت کوڈ کرنے والا`.gem`Ivy کے پтерن + مُعَيَّن`@gem`

ivy { }`کمپائل نہیں ہوتا میں`repositories { }

ریسیفر grolifant Kotlin DSL کے ساتھ متوافق نہیں

مستقیم کال`project.repositories.ivy { }`

`javaLauncher`حل نہیں

موجود نہیں ہونے والی خاصیت پر`AsciidoctorJRevealJSTask`

setInProcess("JAVA_EXEC")(empty)forkOptions { executable(…​) }

`executable = …​`کمپائل نہیں ہوتا

ممتلكات`val`میں`JavaForkOptions`بڑا ہاتھی

طریقہ`executable(Object)`جگہ پر

JavaToolchainService`کے ذریعے نہیں ملنا`extensions

یہ ایک گرائل سروس ہے، ایک ایکسٹنشن نہیں

project.serviceOf<JavaToolchainService>()

`revealjs { }`محلول نہیں کام میں

پروجیکٹ کی ایکسٹنشن، کام کا طریقہ نہیں

project.extensions.getByType<RevealJSExtension>()

بِلڈ جاوہ 25 کے ساتھ خراب ہو جاتا ہے

Kotlin 2.0.x دو رقمی Java ورژنوں کو پارس نہیں کرتا

خودکار ڈاکر تشخیص + جاوا 17 کا فالبک

تحقیق کا طریقہ : جاویپ سے نامعلوم API پڑھنا

اصل

جب دستاویز غائب یا پوری نہ ہو، bytecodes سچائی کا ذریعہ ہوتے ہیں۔ javap`یہ JDK کا معیاری آلہ ہے جو فائلز ڈیکومپائل کرتا ہے.class`قابل پڑھنے والے جاوا سائنچرز میں, بغیر سروس کوڈ کی ضرورت

مرحلہ 1: گریڈل کیش میں جار کو ڈھونڈیں

Gradle تمام اپنی وابستگی ڈاؤنلوڈ کرتا ہے میں`~/.gradle/caches/modules-2/files-2.1/`. پہلا قدم یہ ہے کہ وہ jar جس میں کلاس جس کو معائنہ کرنا ہے موجود ہو:

find ~/.gradle/caches -name "asciidoctor-gradle-jvm-slides*.jar" 2>/dev/null

نتیجہ :

/home/user/.gradle/caches/modules-2/files-2.1/org.asciidoctor/
asciidoctor-gradle-jvm-slides/4.0.0-alpha.1/.../
asciidoctor-gradle-jvm-slides-4.0.0-alpha.1.jar

مرحلہ 2: jar کی کلاسوں کی فہرست بنانا

ایک کلاس کا تفتیش کرنے سے پہلے، یہ جان لیا جاتا ہے کہ کلاس جار میں موجود ہے:

jar tf asciidoctor-gradle-jvm-slides-4.0.0-alpha.1.jar | grep -i "RevealJS\|revealjs"

یہ تمام دستیاب کلاسوں کا مظاہرہ کرتا ہے: AsciidoctorJRevealJSTask, RevealJSExtension, RevealJSOptions, etc.

مرحلہ 3 : کلاس کا جائزہ لیں

javap -p -classpath asciidoctor-gradle-jvm-slides-4.0.0-alpha.1.jar \
org.asciidoctor.gradle.jvm.slides.AsciidoctorJRevealJSTask

اختیار`-p`یہ تمام رکنیں، خصوصی رکنیں شامل دکھاتا ہے۔ نتیجہ فوراً کلیدی لائن دکھاتا ہے :

public class AsciidoctorJRevealJSTask
extends org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask

مرحلہ 4: ہyerarkey اوپر جاؤ

کام پھیلاتا ہے`AbstractAsciidoctorTask`. اس کا دور آنے پر اسے جانچا جاتا ہے پہلے اس کے jar کو ڈھونڈ کر :

find ~/.gradle/caches -name "asciidoctor-gradle-jvm-[0-9]*.jar" 2>/dev/null

javap -p -classpath asciidoctor-gradle-jvm-4.0.0-alpha.1.jar \
org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask | grep -i "fork\|exec\|jvm\|java"

یہی جگہ ہے جہاں ہم دریافت کرتے ہیں`forkOptions`, JAVA_EXEC, et javaForkOptions کی قسم`org.ysb33r.grolifant.api.v4.JavaForkOptions`.

مرحلہ 5: غیر معروف انواع کی پیروی کریں

`JavaForkOptions`ایک نامعلوم grolifant کلاس ہے۔ هم اس کا jar ملتے ہیں :

find ~/.gradle/caches -name "grolifant*.jar" 2>/dev/null

پھر اسے جانچا جاتا ہے :

javap -p -classpath grolifant40-legacy-api-2.0.0-alpha.6.jar \
org.ysb33r.grolifant.api.v4.JavaForkOptions

وہاں مل جاتا ہے`executable(java.lang.Object)— بلانے کا صحیح طریقہ، کے مقابل`executable = …​`جسے کمپائل نہیں کیا جا سکتا کیونکہ یہ ایک پراپرٹی ہے`val.

مرحلہ 6: پروجیکٹ کے ایسٹینشنز جانچ کریں

کے لیے`revealjs { }`، سوال تھا : کیا یہ کام کا ایک طریقہ ہے؟ یا ایک پروگرام کی توسیع؟ تفتیش کا`AsciidoctorJRevealJSTask` کسی طریقہ دکھاتا نہیں`revealjs`. پھر ہم جائزہ لیتے ہیں`RevealJSExtension`:

javap -p -classpath asciidoctor-gradle-jvm-slides-4.0.0-alpha.1.jar \
org.asciidoctor.gradle.jvm.slides.RevealJSExtension | head -5
public class RevealJSExtension implements groovy.lang.GroovyObject {
public static final java.lang.String NAME;

موجودگی کا`NAME`یہ تصدیق کرتا ہے کہ یہ پراجیکٹ پر رجسٹر کردہ ایکٹنشن ہے, منصوب کے ذریعے`project.extensions.getByType<RevealJSExtension>()`.

طریقے کا خلاصہ

مرحلہ عمل

1

find ~/.gradle/caches -name "*.jar"— جار کا مقام معلوم کرنا

2

jar tf jar.jar | grep NomClasse— کلاس موجود ہے یا نہیں جانچ کریں

3

javap -p -classpath jar.jar NomCompletClasse— کلاس کا معائنہ کریں

4

شناسائی`extends`اور ہیرارچھی اوپر چڑھنا

5

اپنے جار میں نامعلوم انواع کی پیروی کریں

6

تلاش کرنا`NAME`pour identifier une extension de projet

یہ طریقہ کسی بھی Gradle پلاگین پر قابل اطلاق ہے جس کی API دستاویز شدہ نہیں ہے او جس کا alpha ورژن اب موجودہ توثیق سے مطابقت نہیں رکھتا۔

اگلا مرحلہ

یہ buildSrc پلاگ-إن ایک الگ پروجیکٹ میں نکال دیا جائے گا جو Gradle Plugin Portal یا Maven Local پر شائع ہو جائے گا۔ مصروف کرنے والا buildscript اب اس صورت میں بن جائے گا:

plugins { id("slides") version "1.0.0" }

Et settings.gradle.kts`اس کو صرف کمترین حد تک کم کر دیا جائے گا، کسی ارجاع کے بغیر`foojay-resolver-convention, JDK کی فراہمی پلاگین خود خود منظم کی جاتی ہے یا اس کو prerequisite کے طور پر document کیا گیا ہے۔

متعلقہ مضامین