Gradle userguide.html

  1. 스크립트를 이용해 유연한 빌드 자동화 툴
  2. 스크립트는 Groovy, Kotlin으로 작성 가능

  3. 변경이 없는 빌드 절차의 결과를 재사용하므로, 빠른 빌드 가능
  4. CLI
  5. ↓ shell

    $ gradle [task...] [option...] # 각 작업은 ' '로 구분 # 여러 옵션 + CLI 해석 불가 옵션들을 gradle.properties에 작성 가능 $ gradle --help # gradle 도움말 $ gradle -b new.gradle # 스크립트 파일 지정. 기본 build.gradle $ gradle -m, --dry-run # 실제 작업은 하지 않고 작업 실행. 실행될 의존 목록 확인 가능 $ gradle -x test # 실행하지 않을 작업 명시 $ gradle --continuous # 입력 소스 변경 시 자동 실행 # 빌드 로직 변경은 자동으로 반영되지 않음. 수동으로 재실행해야 함(6.4 문서 기준) # 자동 빌드의 종료는 Ctrl+D 또는 kill $ gradle -D{propName}={value} # JVM 시스템 속성 # 루트 프로젝트의 gradle.properties에서 'systemProp.' 접두 포함하여 지정 가능 $ gradle -Dgradle.wrapperUser={user} # gradlew HTTP 인증 정보 $ gradle -Dgradle.wrapperPassword={password} # gradlew HTTP 인증 정보 $ gradle -Dgradle.user.home={path} # GRADLE_USER_HOME $ gradle -Dorg.gradle.logging.level=(quiet, warn, lifecycle, info, debug) # 로그 레벨. -q, -w, -i, -d로도 지정 가능 $ gradle -Dorg.gradle.jvmargs={args} # JVM 전달 인자 # -Dorg.gradle.jvmargs="-Xmx1g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8" $ gradle -Dorg.gradle.java.home={path} # JAVA_HOME $ gradle -P{propName}={value} # 프로젝트 속성 # ORG_GRADLE_PROJECT_{propName}={value} 환경 변수로도 설정 가능 # 설정 파일의 org.gradle.project.{propName}={value} 로도 설정 가능 # 존재하지 않는 프로젝트 속성 참조 시 빌드 실패함에 유의 # Project#hasProperty(String) 이용 $ gradle tasks # 작업 목록 출력 $ gradle help --task clean # 작업 도움말 $ gradle init # 프로젝트 스켈레톤 생성 # https://docs.gradle.org/current/userguide/build_init_plugin.html $ gradle {subProject}:{taskName} # 서브프로젝트 작업 실행 # 작업 이름만 지정하는 경우 모든 서브프로젝트에 대해 실행된다 # 서브프로젝트 디렉터리에서 실행하는 경우엔 프로젝트 이름 생략 가능

build.gradle

Task; 작업 custom_tasks.htmlmore_about_tasks.html

↓ gradle

def msg = 'hello world' task hello { doLast { println msg } }

Task dependencies; 작업 의존

↓ gradle

task hello { doLast { println "${it} end" } } task bye { doLast { println "${it} end" } } task doSomething { dependsOn hello finalizedBy bye doFirst { println "I depend on some tasks" } doLast { println "${it} end" } }

결과 ↓

↓ text

$ gradle --daemon -q doSomething task ':hello' end I depend on some tasks task ':doSomething' end task ':bye' end

Dynamic tasks; 동적 작업 정의

↓ gradle

[2, 4, 6].each { def num = it task "hello${num}" { doLast { println "${'hello?' * num}" } } }

Groovy DSL shortcut notations; 그루비 축약 표현

↓ gradle

task hello {} hello.doFirst { println 'doFirst' } hello.doLast { println 'doLast1' } hello.doLast { println 'doLast2' }

결과 ↓

↓ text

> Task :hello doFirst doLast1 doLast2 BUILD SUCCESSFUL in 7s 1 actionable task: 1 executed

Extra task properties; 사용자 정의 속성 정의

↓ gradle

task _init { ext.author = 'Donggi Kim' } task about { doLast { println "Author is '${_init.author}'" } }

Using methods; 사용자 정의 메서드 이용

↓ gradle

task _init { ext.author = 'Donggi Kim' } task about { doLast { println "Running dir is ${runningDir()}" println "Project dir is ${projectDir()}" println "Author is '${_init.author}'" } } String runningDir() { new File('').getAbsolutePath() } String projectDir() { System.getProperty('user.dir') }

결과 ↓

↓ text

> Task :about Running dir is /root/.gradle/daemon/6.4 Project dir is /workspace/donggi-github/Dong-gi.github.io/Repositories/Gradle/project-01 Author is 'Donggi Kim' BUILD SUCCESSFUL in 7s 1 actionable task: 1 executed

Default tasks; 기본 실행 작업

↓ gradle

defaultTasks 'hello' task hello { doLast { println 'hello world' } }

External dependencies; 스크립트에서 외부 클래스 사용

↓ gradle

import org.apache.commons.codec.binary.Base64 buildscript { repositories { mavenCentral() } dependencies { // classpath group: 'commons-codec', name: 'commons-codec', version: '1.2' classpath 'commons-codec:commons-codec:1.2' } } task encode { doLast { def byte[] encodedString = new Base64().encode('hello world\n'.getBytes()) println new String(encodedString) } }
  1. buildscript() 메서드는 ScriptHandler.html 인스턴스를 구성한다
  2. 프로젝트의 buildscript()는 모든 서브 프로젝트에도 적용된다

외부 스크립트 포함

↓ gradle

apply from ${filePath | url}

작업 설명

↓ gradle

task hello { group = 'Core' description = 'Say hello' doLast { println 'hello world' } }

결과 ↓

↓ text

$ gradle tasks ... Core tasks ---------- hello - Say hello ...

기존 작업 덮어쓰기

↓ gradle

plugins { id 'base' } task clean(type: Delete, overwrite: true) { doLast { println 'I like cleaning' } }

특정 조건을 만족하는 경우에만 실행

↓ gradle

def p = this task hello() { onlyIf { p.hasProperty('userName') } doLast { println "Hello ${p.userName}!" } }

결과 ↓

↓ shell

$ gradle hello --daemon -PuserName="World" > Task :hello Hello World!

빌드 절차

Initialization

  • 어떤 프로젝트들을 빌드해야 하는지 결정하고, org.gradle.api.Project.html 인스턴스를 만든다
  • 루트 프로젝트에 존재하는 settings.gradle 스크립트(-c 또는 --settings-file 옵션으로 다른 파일 지정 가능)가 실행된다multi_project_builds
  • -I 또는 --init-script 옵션을 지정하는 경우, init_scripts를 실행한다
  • USER_HOME/.gradle/ 에 init.gradle을 작성하면 초기화 시 실행된다
  • USER_HOME/.gradle/init.d/, GRADLE_HOME/init.d/ 에 임의 .gradle 스크립트를 넣으면 초기화 시 실행된다
  • 후자는 커스텀 gradle 배포에 이용하면 된다

    ↓ gradle

    // 예. 모든 프로젝트는 "libs" 디렉터리를 저장소로 이용한다 allprojects { repositories { flatDir { dirs "libs" } } }

    ↑ 이를 자동으로 적용하려면, gradle을 새로 압축하여 gradlew에서 이용하면 된다
    gradle wrapper 생성 후, gradle-wrapper.properties에
    distributionUrl=${customGradleUrl}

Configuration

Project 인스턴스의 설정이 진행된다. 빌드될 각 프로젝트의 build.gradle 스크립트가 실행된다

Execution

구성 단계에서 실행하기로 결정된 작업들을 실행한다

↓ gradle

task hello {} tasks.whenTaskAdded { task -> task.ext.srcDir = 'src/main/java' } gradle.taskGraph.beforeTask { Task task -> println "executing $task ..." } gradle.taskGraph.afterTask { Task task, TaskState state -> if (state.failure) println "${task} Failed" else println "${task} Succeeded" } gradle.afterProject { project -> if (project.state.failure) println "${project} Failed" else println "${project} Succeeded" } // + gradle.beforeProject, ProjectsLoaded, buildFinished, projectsEvaluated, settingsEvaluated

기본 작업

org.gradle.api.tasks.Copy.html

↓ gradle

task copy(type: Copy) { group = 'Project 01' description = 'Core Gradle의 Copy 태스크를 이용하여 src 디렉터리를 dest로 복사한다' from 'src' into 'dest' caseSensitive = false includeEmptyDirs = false excludes = ['.gradle/'] rename { fileName -> newFileName } rename '(.*).txt', '$1.csv' }

org.gradle.api.tasks.Delete.html

↓ gradle

task makePretty(type: Delete) { delete 'uglyFolder', 'uglyFile' followSymlinks = true }

org.gradle.api.tasks.Exec.html

↓ gradle

task stopTomcat(type: Exec) { workingDir '../tomcat/bin' commandLine './stop.sh' standardOutput = new ByteArrayOutputStream() ext.output = { return standardOutput.toString() } }

org.gradle.api.tasks.JavaExec.html

  • 예1
  • ↓ gradle

    apply plugin: 'java' task runApp(type: JavaExec) { classpath = sourceSets.main.runtimeClasspath main = 'package.Main' args 'appArg1' }
  • 예2
  • ↓ gradle

    apply plugin: 'java' jar { manifest { attributes('Main-Class': 'package.Main') } } task runExecutableJar(type: JavaExec) { classpath = files(tasks.jar) args 'appArg1' }

org.gradle.api.tasks.bundling.Zip.html

↓ gradle

plugins { id 'base' } task zip(type: Zip) { group = 'Project 01' description = 'src 디렉터리를 out.zip으로 압축한다' from 'src' archiveFileName = 'out.zip' }

org.gradle.api.tasks.bundling.Tar.html

Zip 유사

Project

org.gradle.api.Project.html

Script blocks

Properties

↓ gradle

readonly Logger logger // logger.info, logger.error, ... readonly TaskContainer tasks // 프로젝트 작업 목록 // 예 tasks.addRule("Pattern: ping<ID>") { String taskName -> if (taskName.startsWith("ping")) { task(taskName) { doLast { println "Pinging: " + (taskName - 'ping') } } } }

Methods

↓ gradle

File file (Object path) // CharSequence, File, Path, URI, URL 등에 대해 단일 파일 인스턴스 반환 ConfigurableFileCollection files (Object... paths) // +, - 연산 정의됨. 각각 합/차집합 ConfigurableFileTree fileTree (Object baseDir) // ant 패턴 이용 def tree = fileTree('src') tree.include('**/*.java') tree.exclude('**/*Test.java') def newTree = tree.matching { include('**/*.jpg') } tree.visit { fileDetail -> ... } tree.visit(new FileVisitor() { void visitDir(FileVisitDetails detail) {} void visitFile(FileVisitDetails detail) {} }) WorkResult copy (?) // 기본 작업 Copy와 동일 WorkResult delete (action) // 기본 작업 Delete와 동일 File mkdir (Object path) // 경로 상 필요한 모든 디렉터리 생성

Dependency configuration

↓ gradle

repositories { mavenCentral() // 메이븐 중앙 저장소(https://repo1.maven.org/maven2/) 이용 maven { url 'x.y.z' // pom.xml, *.jar 둘 다 여기있는 경우 } maven { url 'x.y.z.pom' // pom.xml은 여기 artifactUrls 'x.y.z.jar' // *.jar는 여기 credentials { // Basic authentication(필요한 경우) username 'name' password 'q1w2e3r4' } } flatDir { // 로컬 저장소 이용 dirs 'libs', 'common/jars' } } dependencies { // 형식 : ${configurationName} ${dependencyNotation} implementation files('libs/xxx-my.jar') implementation files("$buildDir/classes") { builtBy 'compile' } implementation fileTree(dir: 'libs', include: '**/*.jar') implementation 'org.slf4j:slf4j-api:1.7.5' implementation project(':core') // 프로젝트 결과 의존 implementation configuration: 'otherConfig' // 다른 구성 의존 }

Custom configuration

↓ gradle

configurations { myConf myConf2.extendsFrom myConf } task showDepencencies { configurations.myConf.each { println it.absolutePath } }

멀티 프로젝트 설정

종류

  1. 계층형 : 각 프로젝트에 상하 관계가 존재
  2. ↓ gradle

    // settings.gradle include 'sub1', 'sub2:ssub1' // 총 3개의 프로젝트 :sub1, :sub2, :sub2:ssub1를 포함한다
  3. 단층형 : 각 프로젝트는 독립적으로 존재
  4. ↓ gradle

    // settings.gradle includeFlat 'sub1', 'sub2:ssub1' // 총 2개의 프로젝트 :sub1, :sub2:ssub1를 포함한다

관련 Script block

↓ gradle

allprojects {} // 전체 프로젝트 설정 subprojects { // 서브 프로젝트 설정 task commonTask {} } project(':sub1') { // :sub1 프로젝트 설정 task sub1Task {} // 여러 프로젝트 설정을 하나의 build.gradle에 작성하려는 경우 이름 명시 필요 }

JUnit 테스트

    java_testing.html

    ↓ gradle

    dependencies { testImplementation 'junit:junit:4.12' } test { useJUnit() }
  1. 단위 테스트 클래스 지정
  2. ↓ gradle

    task unitTest(type: Test) { include '**/*UT.class' reports.html.destination = file("${reports.html.destination}/unitTest") reports.junitXml.destination = file("${reports.junitXml.destination}/unitTest") }
  3. 단위 테스트 카테고리 지정
  4. ↓ gradle

    task unitTest(type: Test) { useJUnit { includeCategories 'x.y.z.categories.UnitTests' } exclude '**/*Something.class' }
  5. 특정 테스트 클래스 집합만 테스트
  6. ↓ java

    @RunWith(Suite.class) @SuiteClasses({ Test1.class, Test2.class }) public class SomeFuncTest {}

    ↓ gradle

    task someFuncTest(type: Test) { include '**/SomeFuncTest.class' reports.html.destination = file("${reports.html.destination}/someFunc") reports.junitXml.destination = file("${reports.junitXml.destination}/someFunc") }
  7. 특정 소스셋만 테스트
  8. ↓ gradle

    task testSet1Test(type: Test) { testClassesDir = sourceSets.testSet1.output.classesDir classpath = sourceSets.testSet1.runtimeClasspath reports.html.destination = file("${reports.html.destination}/testSet1") reports.junitXml.destination = file("${reports.junitXml.destination}/testSet1") }
  9. 병렬 테스트
  10. ↓ gradle

    test { maxParallelForks = 4 // 병렬 테스트 minHeapSize = '1g' // JVM 옵션 jvmArgs '-XX:+UseG1GC' }

gradle.properties

    sec:gradle_configuration_properties
  1. Gradle properties
  2. ↓ properties

    org.gradle.caching =true|false # 이전 빌드 출력 캐싱 org.gradle.configureondemand =true|false # 작업에 필요한 프로젝트만 구성. incubating org.gradle.daemon.idletimeout=# of milliseconds # 데몬 유지 기간. 기본 3시간(10800000) org.gradle.debug =true|false # -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005 org.gradle.java.home =JAVA_HOME # 기본값은 JAVA_HOME 환경 변수 또는 java 위치 디렉터리 org.gradle.jvmargs =... # JVM 전달 인자 org.gradle.parallel =true|false org.gradle.workers.max =# of worekr processes
  3. System properties
  4. ↓ properties

    gradle.user.home=GRADLE_USER_HOME # ↓ Gradle 다운로드 시 HTTP 인증 정보 systemProp.wrapperUser=username systemProp.wrapperPassword=password
  5. gradle 명령이 참조하는 환경 변수
  6. ↓ shell

    GRADLE_USER_HOME # 기본값 $USER_HOME/.gradle JAVA_HOME # 주의 GRADLE_OPTS # 그래들 클라이언트(콘솔 출력) 실행 시만 사용되는 JVM 인자. 빌드 VM에는 영향없다 JAVA_OPTS # 그래들 클라이언트(콘솔 출력) 실행 시만 사용된다. 빌드 VM에는 영향없다. 기본값 -Xmx64m # 주의 + # 그래들 데몬을 비활성화하면 클라이언트 VM이 직접 빌드 작업을 실행한다
  7. 프록시 설정
  8. ↓ properties

    # http systemProp.http.proxyHost=x.y.z systemProp.http.proxyPort=8888 systemProp.http.proxyUser=user systemProp.http.proxyPassword=password systemProp.http.nonProxyHosts=*.nonproxyrepos.com|localhost # https systemProp.https.proxyHost=x.y.z systemProp.https.proxyPort=8888 systemProp.https.proxyUser=user systemProp.https.proxyPassword=password systemProp.https.nonProxyHosts=*.nonproxyrepos.com|localhost

Gradle 성능 organizing_gradle_projects

  1. Build scan
  2. --scan 옵션으로 실행하면 된다. 서로 다른 gradle 버전의 출력이 같은지 비교하는 데도 이용 가능

    ↓ shell

    $ gradle build --scan
    Gradle build scan result example
    <이미지 - Gradle build scan result example>
  3. 프로젝트에 항상 settings.gradle을 둘 것
  4. 매 실행 시마다 settings.gradle이 있는지 찾으므로, 빈 파일이라도 만들어 두는 것이 좋다

  5. gradle.properties를 모든 프로젝트에 적용시키려는 경우
  6. GRADLE_USER_HOME 디렉터리에 위치시키면 된다

  7. 각 작업의 출력 디렉터리는 혼자만 사용함이 바람직하다
  8. 여러 작업이 동일한 출력 디렉터리를 이용하는 경우, 전체 빌드가 느려지고 빌드 캐시가 무용지물이 된다

디버깅

기본 설정 : suspend=y,address=5005

↓ shell

$ gradle myTask --debug-jvm

재정의 예1

↓ gradle

// build.gradle myTask { jvmArgs=["-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:55555"] }

재정의 예2

↓ gradle

task runApp(type: JavaExec) { // ... debugOptions { enabled = true port = 55555 server = true suspend = false } }

안드로이드

Build variant; 빌드 변형

  • 제품 특성 : free, pro
  • 빌드 타입 : debug, staging, release
  • 빌드 변형 : FreeDebug ~ ProRelease

  • assemble : 모든 빌드 변형 빌드
  • assemblePro : 모든 pro 변형 빌드
  • assembleDebug : 모든 debug 변형 빌드
  • assembleProDebug : ProDebug만 발드

Gradle 플러그인

    plugin_reference.html
  1. 플러그인은 Gradle 코어 기능을 확장하여 새로운 작업, 데이터 모델을 이용하게 한다
  2. 플러그인은 프로젝트와 무관하게 사용 가능하다
  3. 플러그인의 적용apply-T-은 여러 번 호출해도 부작용이 없다
  4. 사용할 플러그인 이름은 Fully qualified name이어야 하지만, 특별히 정의된 짧은 이름도 사용할 수 있다
  5. 예. JavaPlugin → 'java'

  6. groovy, java, kotlin으로 작성 가능

Binary plugin

Plugin.html 인터페이스를 구현한 임의 클래스를 플러그인으로 이용할 수 있다

플러그인 포함 및 적용

'java' 플러그인은 Core Gradle의 일부이므로 적용한다고 선언만하면 되지만, 대개의 플러그인들은 클래스를 찾기 위해 jar를 포함시켜야 한다

↓ gradle

plugins { id 'java' }
  1. 플러그인 포털https://plugins.gradle.org/ 또는 사용자 지정 저장소로부터 포함
    • 플러그인 포함 및 적용
    • ↓ gradle

      plugins { id 'com.jfrog.bintray' version '0.4.1' }
    • 서브 프로젝트만 적용하는 플러그인
    • ↓ gradle

      // settings.gradle include 'hello1', 'hello2', 'bye' // build.gradle plugins { id 'com.example.hello' version '1.0.0' apply false id 'com.example.bye' version '1.0.0' apply false } subprojects { if (name.startsWith('hello')) { apply plugin: 'com.example.hello' } } // bye/build.gradle plugins { id 'com.example.bye' }
  2. 외부 jar 지정
  3. buildSrc로 소스코드 포함(코드를 갖고 있지 않으면 외부에서 사용 불가)
  4. ↓ gradle

    // buildSrc/build.gradle plugins { id 'java-gradle-plugin' } gradlePlugin { plugins { myPlugins { id = 'my-plugin' implementationClass = 'my.MyPlugin' } } }
  5. 스크립트 안의 클래스로 정의(스크립트 외부 사용은 불가)

base 플러그인

Task

Java 플러그인

Task

  • clean - org.gradle.api.tasks.Delete.html
  • build 디렉터리 제거

  • clean{TaskName} - org.gradle.api.tasks.Delete.html
  • 해당 작업 출력 제거

  • compileJava - org.gradle.api.tasks.compile.JavaCompile.html
    • Depends on : 컴파일 경로를 변경하는 모든 작업 + jar
    • 프로덕션(main 소스셋) .java 소스 코드 컴파일
    • org.gradle.api.tasks.compile.CompileOptions.html JavaCompile.options
    • ↓ gradle

      compileJava { options.encoding = 'UTF-8' options.debuf = false // class 파일에 디버깅 정보를 포함할 것인지(기본 true), 사용 레벨은 DebugOptions#getDebugLevel // ↓ test 작업처럼 새로운 JVM 프로세스를 포킹하는 경우, JVM 인자를 따로 지정해야 한다. 기본값 -Xmx512m options.compilerArgs += ['-Xlint:none', '-Xdoclint:none', '-nowarn'] options.listFiles = true // 컴파일 대상 목록 출력 여부(기본 false) options.warnings = false // 경고 출력할 지 여부(기본 true) } // 또는 tasks.withType(JavaCompile) { options.encoding = 'UTF-8' }
  • processResources - org.gradle.api.tasks.Copy.html
  • 프로덕션(main 소스셋) 리소스를 지정 디렉터리로 복사

  • classes
  • Depends on : compileJava, processResources

    원한다면 추가 작업을 덧붙여도 된다

  • jar - org.gradle.api.tasks.bundling.Jar.html
  • Depends on : classes

    main 소스 셋의 클래스 및 리소스로 프로덕션용 jar 빌드

  • javadoc - org.gradle.api.tasks.javadoc.Javadoc.html
  • Depends on : classes

    ↓ gradle

    javadoc { options.links << 'https://docs.oracle.com/en/java/javase/12/docs/api/' }

    API 문서 생성

  • compileTestJava - org.gradle.api.tasks.compile.JavaCompile.html
  • 테스트 .java 소스 코드 컴파일

  • processTestResources - org.gradle.api.tasks.Copy.html
  • 테스트 리소스를 지정 디렉터리로 복사

  • testClasses
  • Depends on : compileTestJava, processTestResources

    원한다면 추가 작업을 덧붙여도 된다

  • test - org.gradle.api.tasks.testing.Test.html
  • Depends on : testClasses + test runtime classpath를 생성하는 작업들

    JUnit 또는 TestNG로 단위 테스트 진행

SourceSet Task

Project layout

  • 기본(default) 구조
  • ↓ text

    src/main/java : 프로덕션 소스 코드 src/main/resources : 프로덕션 리소스 src/test/java : 테스트 소스 코드 src/test/resources : 테스트 리소스 src/{sourceSet}/java src/{sourceSet}/resources
  • 설정 변경
  • ↓ gradle

    sourceSets { main { java { srcDirs = ['src/java'] } resources { srcDirs = ['src/resources'] } } }

SourceSet

  • 기본적으로 main, test 소스셋이 추가된다
  • 속성
  • 한정자타입이름설명
    readonlyStringname소스셋 이름
    readonlySourceSetOutputoutput출력 클래스 + 리소스 파일들
    readonlyFileCollectionoutput.classesDirs클래스 출력 경로, 기본값 {buildDir}/classes/java/{name}
    Fileoutput.resourcesDir리소스 출력 경로, 기본값 {buildDir}/resources/{name}
    FileCollectioncompileClasspath기본값 {name}CompileClasspath 설정
    FileCollectionannotationProcessorPath기본값 {name}AnnotationProcessor 설정
    FileCollectionruntimeClasspath기본값 {output} + {name}RuntimeClasspath 설정
    readonlySourceDirectorySetjava.java 파일들
    Set<File>java.srcDirs자바 소스가 디렉터리들, 기본값 src/{name}/java
    Filejava.outputDir기본값 {buildDir}/classes/java/{name}
    readonlySourceDirectorySetresources.java를 제외한 리소스 파일들
    Set<File>resources.srcDirs리소스 디렉터리들, 기본값 src/{name}/resources
  • 신규 소스셋 추가
  • ↓ gradle

    sourceSets { newSet { compileClasspath = sourceSets.main.output runtimeClasspath = output + compileClasspath } } dependencies { newSetCompile 'a:b:c' newSetRuntime 'a:b:c' }

Contributed extension

가능한 버전은 다음 링크 참고 JavaVersion.html

↓ gradle

java { // 모든 작업에 적용된다. 특정 작업만 적용하려면 해당 작업의 속성 변경 sourceCompatibility = JavaVersion.VERSION_1_8 // 컴파일 버전 targetCompatibility = JavaVersion.VERSION_1_8 // 출력 버전 }

Convention properties

한정자타입이름설명
Stringreporting.baseDir빌드 결과 출력 디렉터리 이름, 기본값 reports
readonlyFilereportsDir{buildDir}/{reporting.baseDir}
StringtestReportDirName테스트 결과 출력 디렉터리 이름, 기본값 tests
readonlyFiletestReportDir{reportsDir}/{testReportDirName}
readonlySourceSetContainersourceSets
StringarchivesBaseName기본값 {projectName}

Dependency configurations

java-library 플러그인

  • jar 파일명에 버전 포함하기
  • ↓ gradle

    // build.gradle version = "0.1.0"

    ↓ shell

    $ ./gradlew jar
  • jar manifest 조정
  • ↓ gradle

    // build.gradle jar { manifest { attributes('Implementation-Title': project.name, 'Implementation-Version': project.version) } }
  • javadoc 생성
  • ↓ shell

    $./gradlew javadoc

Application 플러그인

↓ gradle

applicationName = 'test' mainClassName = 'a.b.C' run { standardInput = System.in } // distZip : jar 빌드 후 실행 스크립트 파일 생성

War 플러그인

↓ gradle

// providedCompile : main 소스셋 컴파일 시 필요하지만, war 파일에서는 제외할 것들 // providedRuntime : main 소스셋 실행 시 필요하지만, war 파일에서는 제외할 것들

↓ gradle

clean { delete << 'src/main/tmp' // clean 작업 시 'src/main/tmp' 디렉터리도 정리 } // 패키지 저장소 명시 repositories { mavenCentral() } dependencies { compile group: 'commons-collections', name: 'commons-collections', version: '3.2.2' providedCompile '' // 빌드 시 사용 && 출력에 미포함 compile '' // 빌드 시 사용 && 출력에 포함 testCompile 'junit:junit:4.11' // 테스트에만 필요 }

사용자 정의 플러그인

  1. 빌드 스크립트에 플러그인 클래스 정의하면 즉시 사용 가능
  2. 프로젝트의 buildSrc에 플러그인 코드를 두면 즉시 사용 가능
  3. Groovy 코드 경로 : buildSrc/src/main/groovy/...

    ↓ 실행 결과

    ↓ text

    > Task :hello hello, world2!
  4. id 설정
    • buildSrc/src/main/resources/META-INF/gradle-plugins/{id}.properties
    • jar : META-INF/gradle-plugins/{id}.properties
    • 또는 http://plugins.gradle.org 에 플러그인 등록
    • publishing-plugins-to-gradle-plugin-portal

      ↓ gradle

      plugins { id "a.b.c" version "1.0" }
  5. 외부 jar에 정의된 플러그인을 사용하려면, 해당 jar를 buildscript.dependencies에 추가해야 한다

Gradle Wrapper; gradlew

Gradle이 설치되지 않았어도, 프로젝트가 필요로 하는 버전의 Gradle을 자동으로 설치해 이용한다

↓ gradle

# 프로젝트 디렉터리에 wrapper 자동 생성. 생성된 jar 파일이 버전 관리 시 제외되지 않도록 유의 $ gradle wrapper # 버전 지정 $ gradle wrapper --gradle-version=6.4 # wrapper 버전 업그레이드 $ ./gradlew wrapper --gradle-version=6.4 # 커스텀 그래들 지정 --gradle-distribution-url # 해시 지정 --gradle-distribution-sha256-sum

다운로드에 필요한 HTTP 기본 인증 정보를 파일로 설정 가능

↓ properties

# USER_HOME/.gradle/gradle.properties 또는 wrapper/gradle-wrapper.properties systemProp.gradle.wrapperUser=username systemProp.gradle.wrapperPassword=password