Bagaimana cara mengimpor satu skrip Gradle ke yang lain?


97

Saya memiliki skrip gradle kompleks yang merangkum banyak fungsi di sekitar membangun dan menyebarkan sejumlah proyek netbeans ke sejumlah lingkungan.

Skrip ini bekerja dengan sangat baik, tetapi pada intinya semuanya dikonfigurasi melalui setengah lusin peta yang menyimpan informasi proyek dan lingkungan.

Saya ingin memisahkan tugas ke file lain, sehingga saya dapat dengan mudah mendefinisikan peta saya dalam file build sederhana, dan mengimpor tugas dari file lain. Dengan cara ini, saya dapat menggunakan tugas inti yang sama untuk sejumlah proyek dan mengonfigurasi proyek tersebut dengan satu set peta sederhana.

Adakah yang bisa memberi tahu saya bagaimana saya dapat mengimpor satu file gradle ke file lain, dengan cara yang mirip dengan tugas Ant? Sejauh ini saya telah memeriksa dokumen Gradle tanpa hasil.

Informasi tambahan

Setelah tanggapan Tom di bawah ini, saya pikir saya akan mencoba dan menjelaskan dengan tepat apa yang saya maksud.

Pada dasarnya saya memiliki skrip gradle yang menjalankan sejumlah subproyek. Namun, subproyek adalah semua proyek Netbeans, dan datang dengan skrip ant build mereka sendiri, jadi saya punya tugas di gradle untuk memanggil masing-masing ini.

Masalah saya adalah saya memiliki beberapa konfigurasi di bagian atas file, seperti:

projects = [
    [name:"MySubproject1", shortname: "sub1", env:"mainEnv", cvs_module="mod1"],
    [name:"MySubproject2", shortname: "sub2", env:"altEnv", cvs_module="mod2"]
]

Saya kemudian menghasilkan tugas seperti:

projects.each({
    task "checkout_$it.shortname" << {
         // Code to for example check module out from cvs using config from 'it'.
    }
})

Saya memiliki banyak cuplikan pembuatan tugas semacam ini, dan semuanya generik - semuanya bergantung pada konfigurasi dalam daftar proyek.

Jadi yang saya inginkan adalah cara untuk meletakkan ini dalam skrip terpisah dan mengimpornya dengan cara berikut:

projects = [
    [name:"MySubproject1", shortname: "sub1", env:"mainEnv", cvs_module="mod1"],
    [name:"MySubproject2", shortname: "sub2", env:"altEnv", cvs_module="mod2"]
]

import("tasks.gradle") // This will import and run the script so that all tasks are generated for the projects given above.

Jadi dalam contoh ini, task.gradle akan memiliki semua kode pembuatan tugas generik, dan akan dijalankan untuk proyek yang ditentukan dalam file build.gradle utama. Dengan cara ini, task.gradle adalah file yang dapat digunakan oleh semua proyek besar yang terdiri dari sejumlah sub-proyek dengan file build ant Netbeans.


3
Pertimbangkan konstruksi "apply from: 'other.gradle'" untuk mengimpor deklarasi eksternal. (Lihat "12.4. Mengonfigurasi proyek menggunakan skrip build eksternal" di sini gradle.org/0.9-preview-1/docs/userguide/… )
Petr Gladkikh

@PetrGladkikh apply fromsegera menjalankan tugas eksternal. Ini mungkin tidak disukai dalam logika eksekusi (yaitu saya ingin menjalankan tugas saat saya mau, tidak langsung).
IgorGanapolsky

Pernyataan ini dalam komentar di atas tidak benar : apply fromsegera jalankan tugas eksternal. Jangan sampai menyesatkan. Tugas eksternal dikonfigurasi, tidak dijalankan.
Jarekczek

Jawaban:



17

Jawaban atas pertanyaan ternyata ada di sistem Plugins, di mana Anda dapat menambahkan fungsionalitas yang diinginkan dalam satu set plugin yang dapat berupa file keren yang terletak di direktori buildSrc/src/main/groovy . Plugin juga dapat dibundel sebagai Jar meskipun saya belum mencobanya.

Detail di sini: Plugin Kustom


Asal tahu saja tautannya rusak - inilah pembaruan gradle.org/docs/current/userguide/…
JARC


4

Nah, sulit untuk mengatakan apa yang paling baik untuk Anda tanpa benar-benar melihat file build Anda.

Saya dapat berasumsi bahwa menyiapkan lingkungan Anda sebagai multi-project build akan memberi Anda abstraksi yang Anda cari.

Di root proyek build.gradleAnda, Anda menentukan semua hal khusus domain Anda serta hal-hal yang berlaku untuk semua subproyek Anda:

repositories {
    add(new org.apache.ivy.plugins.resolver.FileSystemResolver()) {
        name = 'destRepo'
        addIvyPattern( file( project.properties['repo.dest.dir']).absolutePath + '/[organisation]/[module]/ivys/ivy(-[revision]).xml')
        addArtifactPattern( file( project.properties['repo.dest.dir']).absolutePath + '/[organisation]/[module]/[type]s/[artifact](-[revision]).[ext]')
        descriptor = 'optional'
        checkmodified = true
    }
    ...
}
...
subprojects {
    sourceCompatibility = 1.5
    targetCompatibility = 1.5
    group = 'my.group'
    version = '1.0'
    uploadArchives {
        uploadDescriptor = true
        repositories {
            add rootProject.repositories.destRepo
        }
    }
    apply{ type my.group.gradle.api.plugins.MyPlugin }
    ...
}

dependsOnChildren()

Direktori root proyek mungkin juga berisi gradle.propertiesfile tempat Anda menentukan properti yang digunakan oleh proyek Anda:

buildDirName=staging
repo.dest.dir=/var/repo
...

Kemudian di file tambahan dari root proyek settings.gradleAnda bernama Anda benar-benar menunjuk ke subproyek Anda:

include 'my-first-component',
        'my-second-component'
...
project(':my-first-component').projectDir = new File(rootDir, 'path/to/first/component')
project(':my-second-component').projectDir = new File(rootDir, 'path/to/second/component')
...

Setiap direktori sub-proyek berisi build.gradlefile yang berisi hal-hal khusus sub-proyek saja.

Tidak masalah jika Anda memanggil gradledari root proyek atau direktori sub-proyek, gradle akan secara otomatis mempertimbangkan semua definisi Anda yang dilakukan di berbagai file.

Perhatikan juga bahwa tidak ada tugas kompilasi yang akan dijalankan untuk root proyek Anda selama Anda tidak memuat plugin apa pun di luar plugin default di tingkat root.


1
Terima kasih telah meluangkan waktu untuk menjawab. Ini bukan sub-proyek yang saya alami, melainkan membuat 'perpustakaan' tugas-tugas umum. Saya telah mengedit pertanyaan asli saya dengan lebih banyak informasi dan cuplikan kode untuk memperjelas semuanya.
Anthony Roy

1
Jadi, alih-alih melakukan impor ("task.gradle") dari sampel Anda, Anda akan memiliki bagian subproyek {} yang menetapkan kode pembuatan tugas umum yang digunakan oleh semua subproyek Anda. Ini harus memberikan abstraksi yang sama yang Anda cari !?
Tom

Apakah Ivy plugin benar-benar diperlukan di sini? Tidak bisakah Gradle digunakan sendiri?
IgorGanapolsky
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.