Gradle derleme komut dosyasından ortak yöntemleri ayıklayın


86

İçinde build.gradlebazı görevler oluşturduğum bir Gradle oluşturma betiğim ( ) var. Bu görevler çoğunlukla yöntem çağrılarından oluşur. Çağrılan yöntemler ayrıca derleme betiğindedir.

Şimdi, durum şu:

Farklı görevler içeren, ancak orijinal betikteki aynı yöntemleri kullanan oldukça fazla derleme betikleri oluşturuyorum. Bu nedenle, bu "ortak yöntemleri" bir şekilde ayıklamak istiyorum, böylece oluşturduğum her yeni komut dosyası için kopyalamak yerine onları kolayca yeniden kullanabilirim.

Gradle PHP olsaydı, aşağıdaki gibi bir şey ideal olurdu:

//script content
...
require("common-methods.gradle");
...
//more script content

Ama elbette bu mümkün değil. Yoksa öyle mi?

Her neyse, bu sonuca nasıl ulaşabilirim? Bunu yapmanın mümkün olan en iyi yöntemi nedir? Gradle belgelerini zaten okudum, ancak bunun için hangi yöntemin en kolay ve en uygun olduğunu belirleyemiyorum.

Şimdiden teşekkürler!


GÜNCELLEME:

Yöntemleri başka bir dosyadan çıkarmayı başardım

(kullanarak apply from: 'common-methods.gradle'),

bu nedenle yapı aşağıdaki gibidir:

parent/
      /build.gradle              // The original build script
      /common-methods.gradle     // The extracted methods
      /gradle.properties         // Properties used by the build script

Bir görevi yerine build.gradlegetirdikten sonra, yeni bir problemle karşılaştım: görünüşe göre yöntemler bulundukları zaman tanınmıyor common-methods.gradle.

Bunu nasıl düzelteceğine dair bir fikrin var mı?


Yöntemleri yazmanız gerektiğinden emin misiniz? Derleme komut dosyalarınızı yöntemler açısından yazarsanız, bazı Gradle güzelliklerini kaçırırsınız, en önemlisi artımlı yapının doğru şekilde çalışmasını sağlamak için fazladan çalışma gerekir. Amaçlanan soyutlama, Görevleri kullanmak ve yeniden kullanmaktır . Ayrıca özel görevler de oluşturabilirsiniz . Belki de şu anda yöntemlerde sahip olduğunuz uygulamaları görevlere koymayı düşünmelisiniz.
Alpar

@Alpar ve diğerleri ; a timestamp()veya currentWorkingDirectory()metotları task-s olarak yapmak için hangi amaca hizmet edildiği (örneğin). Fayda işlevleri ve benzer şeyler nominal olarak skalerdir - Gradle ve çoğu derleme sisteminde yerleşik olarak kodun yeniden kullanımında sınırlamalar olması dışında görev değildirler. Bir şeyi BİR kez yapıp yeniden kullanabileceğim KURU dünyayı seviyorum . Aslında, @Pieter VDE örneğini uzanan ben de bir "kullanmak root.gradlebenim ana proje için" desen - build.gradle dosyası genellikle bazı proje özelliklerini tanımlar ve sonra sadece apply ${ROOT}...
will

Özelliklerle çalışmanın merkezi bir yoluna ihtiyacınız varsa, belki bu soru size yardımcı olabilir: stackoverflow.com/questions/60251228/…
GarouDan

Yanıtlar:


76

Yöntemleri paylaşmak mümkün değildir, ancak aynı şeye indirgenen bir kapanış içeren ekstra özellikler paylaşabilirsiniz. Örneğin, beyan ext.foo = { ... }içinde common-methods.gradle, kullanım apply from:senaryoyu uygulamak ve daha sonra kapatılması çağırmak için foo().


1
Gerçekten hile yapıyor! Ama bununla ilgili bir sorum var: Yöntemlerin bir şeyi döndürmesine ne dersiniz? Fe File foo(String f)olacak ext.foo = { f -> ... }ben sonra sadece böyle bir şey yapabilir: File f = foo(...)?
Pieter VDE

2
Görünüşe göre, önceki yorumumdaki soru mümkün. Bu soruyu cevapladığın için teşekkürler Peter!
Pieter VDE

1
@PeterNiederwieser Neden mümkün değil? Gradle.org aksini düşünüyor: docs.gradle.org/current/userguide/…
IgorGanapolsky

1
@IgorGanapolsky bağlantı için teşekkürler. Gradle.build'de ayrı bir yapı dosyasında oluşturulan bir değeri nasıl kullanabilirim merak ediyorum - bu şekilde çok yararlı olur :)
kiedysktos

@IgorGanapolsky Peter VDEs sorusu bağlamında paylaştığınız bağlantı nasıl yardım etmelidir?
t0r0X

161

Peter'ın cevabına dayanarak , yöntemlerimi şu şekilde dışa aktarıyorum:

İçeriği helpers/common-methods.gradle:

// Define methods as usual
def commonMethod1(param) {
    return true
}
def commonMethod2(param) {
    return true
}

// Export methods by turning them into closures
ext {
    commonMethod1 = this.&commonMethod1
    otherNameForMethod2 = this.&commonMethod2
}

Bu yöntemleri başka bir komut dosyasında şu şekilde kullanıyorum:

// Use double-quotes, otherwise $ won't work
apply from: "$rootDir/helpers/common-methods.gradle"

// You can also use URLs
//apply from: "https://bitbucket.org/mb/build_scripts/raw/master/common-methods.gradle"

task myBuildTask {
    def myVar = commonMethod1("parameter1")
    otherNameForMethod2(myVar)
}

Groovy'de yöntemleri kapatmalara dönüştürme hakkında daha fazla bilgi.


Kapanış adını dahili olarak kullanmak için özel bir neden var mı?
Anoop

1
@AnoopSS İki closure'ı Gradle'ın ekstra özelliklerine ekliyoruz . Bu ekstra özellikler adı verilen bir nesnede toplanmıştır ext.
Matthias Braun

Dahil edilen dosyada tanımlanan değeri bir sınıfımız olarak belirleyebilir miyiz?
GarouDan

Bunun hakkında örnek kod içeren ayrı bir soru göndermek iyi bir fikir olabilir, @GarouDan
Matthias Braun

7

Kotlin dsl kullanarak şu şekilde çalışır:

build.gradle.kts :

apply {
  from("external.gradle.kts")
}

val foo = extra["foo"] as () -> Unit
foo()

external.gradle.kts :

extra["foo"] = fun() {
  println("Hello world!")
}

1
harika, gerçek türü paylaşmanın bir yolu var mı? temelde tür güvenliğini kaybediyorsunuz ve derleyiciler yardım ediyor ... yöntemlerinizi içeren sınıfı paylaşabilirseniz, derleyiciden faydalanabilirsiniz.
2019, 09:44

0

Kotlin DSL için başka bir yaklaşım da şunlar olabilir:

my-plugin.gradle.kts

extra["sum"] = { x: Int, y: Int -> x + y }

settings.gradle.kts

@Suppress("unchecked_cast", "nothing_to_inline")
inline fun <T> uncheckedCast(target: Any?): T = target as T

apply("my-plugin.gradle.kts")

val sum = uncheckedCast<(Int, Int) -> Int>(extra["sum"])

println(sum(1, 2))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.