Asciidoctor RevealJS پلگ ان کی buildSrc Kotlin میں مائیگریشن: ایک Groovy API کی ریورس انجینئرنگ
شائع شدہ: 16 April 2026
سیاق و مقصد
شروع کرنے کا נק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 فراہم کریں تاکہ ہم آپ کے اکاؤنٹ تک رسائی حاصل کر سکیں۔
-
ایوی ریپو کو … کی طرف انظار رکھتے ہوئے محفوظ کریں`https://rubygems.org/gems/`
-
گروپ کو خارج کریں`rubygems`Maven کے ریپوزٹریوں کے لئے ٹکراؤ سے بچنے کے لیے
-
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 پر چلنا پڑتا ہے یا ڈاکر استعمال کرنا پڑے گا۔
استراتژی
-
Docker دستیاب → اجرا کے زیرے container`eclipse-temurin:17`(پیش فرض رویہ)
-
ڈوکر غائب + جاوے 17 → مقامی تنفیذ
-
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 + |
Gradle aik dhoondh raha hai`.jar`ایک کی جگہ`.gem` |
`[ext]`حل کرتا ہے میں`jar`پیش فرض |
سخت کوڈ کرنے والا`.gem`Ivy کے پтерن + مُعَيَّن`@gem` |
|
ریسیفر grolifant Kotlin DSL کے ساتھ متوافق نہیں |
مستقیم کال`project.repositories.ivy { }` |
`javaLauncher`حل نہیں |
موجود نہیں ہونے والی خاصیت پر`AsciidoctorJRevealJSTask` |
|
`executable = …`کمپائل نہیں ہوتا |
ممتلكات`val`میں`JavaForkOptions`بڑا ہاتھی |
طریقہ`executable(Object)`جگہ پر |
|
یہ ایک گرائل سروس ہے، ایک ایکسٹنشن نہیں |
|
`revealjs { }`محلول نہیں کام میں |
پروجیکٹ کی ایکسٹنشن، کام کا طریقہ نہیں |
|
بِلڈ جاوہ 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 |
|
2 |
|
3 |
|
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 کیا گیا ہے۔