Kompleti izvora Gradle

1. Pregled

Izvorni skupovi daju nam moćan način za strukturiranje izvornog koda u našim Gradle projektima.

U ovom brzom vodiču vidjet ćemo kako ih koristiti.

2. Zadani skupovi izvora

Prije nego što uskočimo u zadane postavke, objasnimo prvo što su skupovi izvora. Kao što naziv govori, izvorni skupovi predstavljaju logično grupiranje izvornih datoteka.

Pokriti ćemo konfiguraciju Java projekata, ali koncepti su primjenjivi i na druge vrste projekata Gradle.

2.1. Zadani izgled projekta

Počnimo s jednostavnom strukturom projekta:

skupovi izvora ├── src │ └── glavni │ ├── java │ │ ├── SourceSetsMain.java │ │ └── SourceSetsObject.java │ └── test │ └── SourceSetsTest.java └── build. gradle 

Sada pogledajmo graditi.gradle:

primijeniti dodatak: "java" description = "Primjer skupova izvora" test {testLogging {događaji "prošli", "preskočeni", "neuspjeli"}} ovisnosti {implementacija ('org.apache.httpcomponents: httpclient: 4.5.12') testImplementation ('junit: junit: 4,12')}

Dodatak Java pretpostavlja src / main / java i src / test / java kao zadani direktoriji izvora.

Izradimo jednostavan uslužni zadatak:

zadatak printSourceSetInformation () {doLast {sourceSets.each {srcSet -> println "[" + srcSet.name + "]" print "-> Izvorni direktoriji:" + srcSet.allJava.srcDirs + "\ n" print "-> Izlaz direktoriji: "+ srcSet.output.classesDirs.files +" \ n "println" "}}}

Ovdje ispisujemo samo nekoliko svojstava skupa izvora. Uvijek možemo provjeriti puni JavaDoc za više informacija.

Pokrenimo i vidimo što ćemo dobiti:

$ ./gradlew printSourceSetInformation> Zadatak: izvorni skupovi: printSourceSetInformation [glavni] -> Izvorni direktoriji: [... / source-sets / src / main / java] -> Izlazni direktoriji: [... / source- sets / build / classes / java / main] [test] -> Izvorni direktoriji: [... / source-sets / src / test / java] -> Izlazni direktoriji: [... / source-sets / build / classes / java / test] 

Obavijest imamo dva zadana skupa izvora: glavni i test.

2.2. Zadane konfiguracije

Dodatak Java također automatski stvara neke zadane Gradle konfiguracije za nas.

Slijede posebnu konvenciju imenovanja: .

Koristimo ih za deklariranje ovisnosti u graditi.gradle:

ovisnosti {implementacija ('org.apache.httpcomponents: httpclient: 4.5.12') testImplementation ('junit: junit: 4.12')}

Primijetite da preciziramo provedba umjesto mainImplementacija. Ovo je iznimka od konvencije imenovanja.

Prema zadanim postavkama, testImplementacija konfiguracija se proteže provedba i nasljeđuje sve svoje ovisnosti i izlaze.

Poboljšajmo svoj pomoćni zadatak i vidjet ćemo o čemu se radi:

zadatak printSourceSetInformation () {doLast {sourceSets.each {srcSet -> println "[" + srcSet.name + "]" print "-> Izvorni direktoriji:" + srcSet.allJava.srcDirs + "\ n" print "-> Izlaz direktoriji: "+ srcSet.output.classesDirs.files +" \ n "print" -> Sastavi put do klase: \ n "srcSet.compileClasspath.files.each {print" "+ it.path +" \ n "} println" "} }}

Pogledajmo izlaz:

[glavna] // isti izlaz kao i prije -> Sastavljanje staze: ... / httpclient-4.5.12.jar ... / httpcore-4.4.13.jar ... / commons-logging-1.2.jar .. ./commons-codec-1.11.jar [test] // isti izlaz kao i prije -> Sastavi put do klase: ... / source-sets / build / classes / java / main ... / source-sets / build / resources / glavna ... / httpclient-4.5.12.jar ... / junit-4.12.jar ... / httpcore-4.4.13.jar ... / commons-logging-1.2.jar ... / commons- kodek-1.11.jar ... / hamcrest-core-1.3.jar

The test Izvorni set sadrži izlaze programa glavni u svom putu kompajliranja klasa i također uključuje njegove ovisnosti.

Dalje, kreirajmo naš jedinični test:

javna klasa SourceSetsTest {@Test public void whenRun_ThenSuccess () {SourceSetsObject underTest = new SourceSetsObject ("lorem", "ipsum"); assertThat (underTest.getUser (), je ("lorem")); assertThat (underTest.getPassword (), je ("ipsum")); }}

Ovdje testiramo jednostavan POJO koji pohranjuje dvije vrijednosti. Možemo ga koristiti izravno jer the glavni izlazi su u našem test razredna staza.

Dalje, pokrenimo ovo iz Gradla:

./gradlew clean test> Zadatak: skupovi izvora: test com.baeldung.test.SourceSetsTest> whenRunThenSuccess PASSED 

3. Prilagođeni skupovi izvora

Do sada smo vidjeli neke razumne zadane postavke. Međutim, u praksi nam često trebaju prilagođeni skupovi izvora, posebno za integracijske testove.

To je zato što bismo možda željeli imati određene testne knjižnice samo na putu klase integracijskih testova. Također bismo ih možda željeli izvršiti neovisno o jediničnim testovima.

3.1. Utvrđivanje prilagođenih skupova izvora

Stvorimo zasebni izvorni direktorij za naše integracijske testove:

skupovi izvora ├── src │ └── glavni │ ├── java │ │ ├── SourceSetsMain.java │ │ └── SourceSetsObject.java │ ├── test │ │ └── SourceSetsTest.java │ └── itest │ └── SourceSetsITest.java └── build.gradle 

Dalje, idemo konfigurirajte ga u našem graditi.gradle koristiti sourceSets konstruirati:

sourceSets {itest {java {}}} ovisnosti {implementacija ('org.apache.httpcomponents: httpclient: 4.5.12') testImplementation ('junit: junit: 4.12')} // ostale deklaracije su izostavljene 

Primijetite da nismo naveli nijedan prilagođeni direktorij. To je zato što se naša mapa podudara s nazivom novog skupa izvora (itest).

Možemo prilagodite koji su direktoriji uključeni u srcDirs imovine:

sourceSets {itest {java {srcDirs ("src / itest")}}}

Sjećate se našeg pomoćnog zadatka od početka? Ponovimo ga i pogledajte što ispisuje:

$ ./gradlew printSourceSetInformation> Zadatak: source-sets: printSourceSetInformation [itest] -> Izvorni direktoriji: [... / source-sets / src / itest / java] -> Izlazni direktoriji: [... / source- setovi / graditi / klase / java / itest] -> Sastaviti put do klase: ... / izvor-setovi / graditi / klase / java / glavni ... / izvor-setovi / graditi / resursi / glavni [glavni] // isti izlaz kao prije [test] // isti izlaz kao i prije

3.2. Dodjeljivanje specifičnih ovisnosti skupa izvora

Sjećate se zadanih konfiguracija? Sada dobivamo neke konfiguracije za itest izvorni set također.

Iskoristimo itestImplementacija dodijeliti novu ovisnost:

ovisnosti {implementacija ('org.apache.httpcomponents: httpclient: 4.5.12') testImplementation ('junit: junit: 4.12') itestImplementation ('com.google.guava: guava: 29.0-jre')}

Ovaj se odnosi samo na integracijske testove.

Izmijenimo naš prethodni test i dodajte ga kao test integracije:

javna klasa SourceSetsItest {@Test javna praznina givenImmutableList_whenRun_ThenSuccess () {SourceSetsObject underTest = new SourceSetsObject ("lorem", "ipsum"); Navedi someStrings = ImmutableList.of ("Baeldung", "is", "cool"); assertThat (underTest.getUser (), je ("lorem")); assertThat (underTest.getPassword (), je ("ipsum")); assertThat (someStrings.size (), je (3)); }}

Biti u mogućnosti pokrenuti ga, moramo definirati prilagođeni testni zadatak koji koristi sastavljene izlaze:

// izvor postavlja deklaracije // deklaracije ovisnosti itest zadatka (tip: Test) {description = "Pokreni integracijske testove" group = "verify" testClassesDirs = sourceSets.itest.output.classesDirs classpath = sourceSets.itest.runtimeClasspath}

Te se deklaracije procjenjuju tijekom faze konfiguracije. Kao rezultat, važan je njihov redoslijed.

Na primjer, ne možemo se pozvati na itest izvor postavljen u tijelu zadatka prije nego što je to proglašeno.

Pogledajmo što će se dogoditi ako pokrenemo test:

$ ./gradlew clean itest // neki problemi s kompilacijom NEUSPJEH: Izgradnja nije uspjela s iznimkom. * Što je pošlo po zlu: Izvršenje nije uspjelo za zadatak ': source-sets: compileItestJava'. > Kompilacija nije uspjela; za detalje pogledajte izlaz pogreške kompajlera.

Za razliku od prethodnog izvođenja, ovaj put dobivamo pogrešku u kompilaciji. Dakle, što se dogodilo?

Ovaj novi izvorni set stvara neovisnu konfiguraciju.

Drugim riječima, itestImplementacija ne nasljeđuje JUNIT ovisnost, niti dobiva rezultate od glavni.

Popravimo to u našoj konfiguraciji Gradle:

sourceSets {itest {compileClasspath + = sourceSets.main.output runtimeClasspath + = sourceSets.main.output java {}}} // konfiguracije deklaracije ovisnosti {itestImplementation.extendsFrom (testImplementation) itestRuntimeOnly.extendsFrom (testRuntime)

Ponovimo sada naš test integracije:

$ ./gradlew clean itest> Zadatak: izvorni skupovi: itest com.baeldung.itest.SourceSetsItest> givenImmutableList_whenRun_ThenSuccess PASSED

Test prolazi.

3.3. Eclipse IDE rukovanje

Do sada smo vidjeli kako raditi s izvornim skupovima izravno s Gradleom. Međutim, većinu vremena koristit ćemo IDE (poput Eclipsea).

Kada uvozimo projekt, dobivamo neke probleme sa kompilacijom:

Međutim, ako pokrenemo test integracije iz Gradlea, nećemo dobiti pogreške:

$ ./gradlew clean itest> Zadatak: izvorni skupovi: itest com.baeldung.itest.SourceSetsItest> givenImmutableList_whenRun_ThenSuccess PASSED

Dakle, što se dogodilo? U ovom slučaju, guava ovisnost pripada itestImplementacija.

Nažalost, dodatak Eclipse Buildship Gradle ne upravlja baš ovim prilagođenim konfiguracijama.

Idemo popravite ovo u našem graditi.gradle:

primijeniti dodatak: "eclipse" // prethodne deklaracije eclipse {classpath {plusConfigurations + = [configurations.itestCompileClasspath]}} 

Objasnimo što smo ovdje radili. Dodali smo našu konfiguraciju stazi Eclipse.

Ako osvježimo projekt, problema s kompilacijom više nema.

Međutim, postoji nedostatak ovog pristupa: IDE ne razlikuje konfiguracije.

To znači možemo lako uvoziti guava u našem test izvori (što smo posebno željeli izbjeći).

4. Zaključak

U ovom smo tutorijalu pokrili osnove skupova izvora Gradle.

Zatim smo objasnili kako prilagođeni skupovi izvora rade i kako ih koristiti u Eclipseu.

Kao i obično, cjelokupni izvorni kod možemo pronaći na GitHubu.