====== Gradle ====== * http://www.gradle.org/ * https://plugins.gradle.org/ * [[http://maven.apache.org/|Maven]]을 대체할 수 있는 프로젝트 구성/관리 및 Build tool. * [[http://kwon37xi.egloos.com/4747016|Maven을 넘어 Gradle로 가자]] - Maven 대신 Gradle을 써야하는 이유 * 사실은 [[http://maven.apache.org/|Maven]] + [[http://ant.apache.org/|Ant]] + 스크립트 언어라고 보는 것이 맞다. 프로젝트 구성 뿐만아니라 [[http://groovy.codehaus.org/Using+Ant+from+Groovy|AntBuilder]]와 그루비 스크립트를 통해 Ant의 역할, 배포 스크립트의 역할까지도 가능하다. * [[http://docs.codehaus.org/display/GRADLE/Cookbook|Gradle Cookbook]] * [[http://www.gradleware.com/registered-access?content=books%2Fbuilding-and-testing%2F|Building and testing with gradle 책]] * [[http://www.gradle.org/tooling|Gradle과 각종 개발 도구 플러그인]] * [[http://evgeny-goldin.com/wiki/Gradle|Gradle - Evgeny Goldin]] ===== 설치 ===== * 설치 파일 압축을 풀고 설치 경로를 ''GRADLE_HOME'' 환경변수로 설정 * ''GRADLE_OPTS''에 Gradle 전용 JVM 옵션 설정 * ''GRADLE_USER_HOME'' : 없으면 ''$HOME/.gradle''. 여기에 의존 *.jar 파일등이 저장된다. * ''JAVA_OPTS''에 자바 애플리케이션 공용 JVM 옵션 설정 * ''*.build'' 파일의 인코딩 * 기본적으로 Java의 ''file.encoding'' 시스템 프라퍼티를 따른다. * 윈도우 환경에서 UTF-8로 빌드 파일을 만들려면 ''GRADLE_OPTS=-Dfile.encoding=UTF-8'' 형태로 강제 지정 export GRADLE_OPTS="-Dfile.encoding=UTF-8 -Xmx512m -XX:PermSize=64m -XX:MaxPermSize=256m" # Gradle의 의존성 jar 파일이나 기타 파일들을 저장하는 저장소. 기본은 $HOME/.gradle export GRADLE_USER_HOME="..." ===== 실행속도 높이기 ===== * ''${HOME}/.gradle/gradle.properties'' org.gradle.daemon=true * 이제부터 Gradle이 데몬으로 떠서 실행되기 때문에 초기 로딩 시간이 줄어든다. * 3시간동안 Gradle 작업이 없으면 데몬이 자동 종료된다. ===== 스크립트에서 사용할 인증 정보 분리해두기 ===== * http://stackoverflow.com/questions/12749225/where-to-put-gradle-configuration-i-e-credentials-that-should-not-be-committe * ''~/.gradle/gradle.properties'' mavenUser=admin mavenPassword=admin123 * 빌드 스크립트의 계정/비밀번호 필요한 부분 uploadArchives { repositories { mavenDeployer { repository(url: "http://.../nexus/content/repositories/snapshots/") { authentication(userName: mavenUser, password: mavenPassword) } } } } ===== build Init ===== * [[https://docs.gradle.org/current/userguide/build_init_plugin.html|Build Init Plugin]] * 프로젝트를 시작할 때 ''gradle init''를 실행하면 현재 디렉토리에 Gradle 관련 기본 파일들을 생성해준다.(구버전은 setupBuild) * Maven 프로젝트 디렉토리에서 실행하면 자동 컨버팅을 실행한다. * 실행시 프로젝트 구조를 Java library로 지정하기(1.7 이후) gradle init --type java-application # --type 을 생략하면 basic 으로 지정된다. * Project Types * pom * basic * java-application * java-library * groovy-application * groovy-library * scala-library * Project 디렉토리 구조 생성 task // 적용된 프로그래밍 언어 플러그인에 따라 소스 트리 구조 자동 생성 task initSrc << { project.sourceSets*.allSource.srcDirTrees.flatten().dir.each { dir -> dir.mkdirs() } } ===== 명령 실행과 옵션 ===== * [[https://docs.gradle.org/current/userguide/command_line_interface.html|Gradle Command line interface]] * 기본적으로 gradle을 통해 실행되는 단위를 "Task 태스크"라고 한다.(Ant의 target, Maven의 phase와 유사한 개념) * 태스크는 의존 관계에 따라 단 한 번만 실행된다. * ''-q'' : quiet. 로그 안 찍음. [[http://www.gradle.org/docs/current/userguide/logging.html|Gradle Logging]] * ''-x 태스크'' : 해당 테스크는 실행하지 않음. * ''%%--%%continue'' : 빌드 실패시 즉시 종료하지 않고, 독립적인 태스크들은 모두 수행하고 종료한다. * ''-d|%%--%%debug'' : Debug 정보 및 stacktrace 출력 * 태스크 축약 * dist -> di 형태로 최소한 알아볼 수 있는 만큼만 적어도 됨 * 낙타 표기 compileTest -> cT * ''-b 빌드파일'' : build.gradle 이 아닌 다른 빌드 파일을 선택해 실행한다. 이 경우 settings.gradle 은 무시된다. * ''-p 프로젝트명'' : 멀티 프로젝트에서 어떤 서브 프로젝트를 선택해서 실행 할 경우. -b 대신 -p를 사용할 것. * ''-P프라퍼티이름=값'' : 프라퍼티 지정. 값 없이 프라퍼티만 지정해도 된다. * 이 값은 빌드 스크립트에서 프라퍼티이름으로 바로 접근 가능하다. * 프라퍼티 이름에 "my.property" 형태로 돼 있다면 ''project.get('my.property')'' 형태로 접근 가능하다. * ''%%--%%gui'' : GUI 환경에서 태스크를 실행하고 관리한다. * ''%%--%%recompile-scripts'' : build.gradle들 다시 컴파일한다. * ''%%--%%no-daemon'' : [[gradle:daemon|Gradle Daemon]] 끄기 * ''%%--%%project-cache-dir=/path/to/project-cache'' : 기본적으로 프로젝트 바로 아래에 ''.gradle''로 생성되는 프로젝트별 캐시디렉토리 경로 변경 * ''%%--warning-mode all%%'' : 모든 경고 켜기 * 환경변수 ''TERM=dumb''으로 하면 Gradle의 진행 상황 로그가 안나오게 된다. * Task 상세 도움말은 ''help %%--%%task [태스크이름]'' 으로 볼 수 있다. gradle help --task wrapper ===== 빌드 정보 확인 ===== * ''projects'' : 프로젝트 목록 * ''tasks'' : 태스크 목록 * 기본적으로 태스크 그룹에 속한 것만 보여준다. dist { description = '태스크 설명' group = '태스크의 그룹' } // 혹은 dist.description = '태스크 설명' dist.group = '태스크의 그룹' * ''%%--%%all'' : 태스크 그룹에 상관없이 다 보여줌 * ''[자식프로젝트명:]dependencies'' : Root 혹은 지정 프로젝트의 의존성 트리를 보여준다. * ''--configuration runtime'' : runtime 의존성만 보여준다. * ''[자식프로젝트명:]properties'' : Root 혹은 지정 프로젝트의 속성 값들을 모두 보여준다. * ''%%--%%profile'' : 빌드 수행을 프로파일링하여 성능 정보를 ''./build/reports/profile'' 디렉토리에 저장한다. * ''-m 태스크들'' : 태스크를 실제 수행은 하지 않고, 해당 태스크와 함께 실행되는 모든 태스크 목록을 순서대로 보여준다. ===== 태스크 튜토리얼 ===== * [[gradle:task|Gradle Task]] 심화 * ''build.gradle''로 만든다. * 기본 형태 task hello { doLast { println 'Hello world!' } } // 축약 task count << { 4.times { print "$it " } } * 의존성 : ''task name(depdendsOn: 다른태스크 | [task1, task2, ...]) ...'' 형태로 만든다. * ''task "태스크이름" ...'' : 태스크 이름이 문자열 GString이 될 수 있기 때문에 동적으로 태스크를 생성하는 것이 가능하다. * 태스트의 시작과 끝 액션 task hello << { println 'Hello Earth' } hello.doFirst { println 'Hello Venus' } hello.doLast { println 'Hello Mars' } hello << { println 'Hello Jupiter' } * ''< <''는 doLast와 같은 의미이다. doFirst/doLast는 여러개 선언될 수 있으며 doFirst가 선언된 순서로 먼저 실행되고, 그 뒤에 doLast가 선언된 순서대로 실행된다. * Task Properties : 태스크 안에서 ''ext.프라퍼티명 = 값'' 형태로 선언하면 다른 위치에서 ''태스크명.프라퍼티명'' 으로 해당 값을 읽을 수 있다. * 기본 태스크 defaultTasks 'clean', 'run' task clean << { ... } task run << { ... } * 멀티 프로젝트에서 각 하위 프로젝트는 자신만의 기본 태스크를 선언할 수 있다. 기본 태스크가 없으면 부모의 기본 태스크를 수행한다. * 수행할 태스크에 따라 조건 주기 gradle.taskGraph.whenReady { taskGraph -> if (taskGraph.hasTask(release)) { // release 라는 태스크를 수행할 예정일때 미리 실행할 코드 } else { // release 라는 태스크를 수행할 예정이 아닐 때 미리 실행할 코드 } } ===== Java 개발하기 ===== 다음 java 개발 관련 항목들을 읽어본다. * [[gradle:java|Gradle Java Plugin]] * [[gradle:dependencies|Gradle Dependencies]] * [[gradle:web|Gradle Web Plugin]] ===== DSL ===== * Groovy 빌드 파일은 기본적으로 [[http://www.gradle.org/docs/current/dsl/org.gradle.api.Project.html|Project]] 클래스의 인스턴스이다. * 빌드 파일에 등장하는 변수나 메소드 중에서 미리 선언된 것이 아니라면 Project 클래스에서 해당 속성을 찾는다. * Project 객체는 ''project''로도 접근 가능하다. ==== Project 객체의 기본 프라퍼티들 ==== * project Project : 자기 자신의 인스턴스 * name String : 프로젝트 디렉토리명 * path String : 프로젝트의 Fully Qualified Name * description String : 프로젝트 설명 * projectDir File : 빌드 스크립트가 있는 프로젝트 디렉토리 * buildDir File : ''projectDir/build'' 이 값을 바꾸면 빌드 디렉토리를 바꿀 수 있게 되는 것이다. * group Object : unspecified - 직접 지정 * version Object : unspecified - 직접 지정 * ant AntBuilder : [[http://groovy.codehaus.org/api/groovy/util/AntBuilder.html|AntBuilder]] 인스턴스 ==== 변수 선언 ==== * 로컬 변수 : ''def 변수명''으로 선언. 해당 스크립트 로컬에서만 접근 가능하다. * ext 변수 : 프로젝트 전체와 서브 프로젝트에서도 접근 가능하다. * ext 변수 선언과 사용 ext.javaVersion = '1.7' // 한개씩 선언 ext { // 여러개 한꺼번에 선언 springVersion = '3.1.0.RELEASE' emailNotification = 'build@master.org' } // 가변 Key, 가변 값 형태로 코드를 통해 프라퍼티를 추가할 때는 아래 방식을 사용한다. project.ext['keyname'] = 'value' task hello << { println "javaVersion : ${javaVersion}" println "springVersion : ${springVersion}" println "emailNotification : ${emailNotification}" } ==== 스크립트 컴파일 ==== * 모든 빌드 스크립트는 컴파일하여 ''.gradle'' 에 저장하고 캐시된다. * 빌드 파일이 변경되면 그 때 재컴파일 한다. * ''%%--%%recompile-scripts'' 옵션을 주면 강제 재컴파일 한다. ===== 이것 저것 ===== * http://www.gradle.org/docs/current/userguide/tutorial_this_and_that.html ==== 디렉토리 생성 ==== * 여러 태스크에서 특정 디렉토리를 필요로 할 경우에는, 디렉토리 생성 태스크를 만들고 다른 태스크가 그 태스크에 의존하도록 만든다. classesDir = new File('build/classes') task resources << { classesDir.mkdirs() // do something } task compile(dependsOn: 'resources') << { if (classesDir.isDirectory()) { println '필요한 디렉토리가 존재하네요.' } // do something } ==== Gradle 프라퍼티와 시스템 프라퍼티 ==== * ''-D프라퍼티명=값''으로 시스템 프라퍼티를 추가할 수 있다. * ''gradle.properties''를 통해 프라퍼티를 추가할 수 있다. * ''$USER_HOME/.gradle/gradle.properties'' 혹은 * ''프로젝트홈/gradle.properties'' * ''$USER_HOME''에 있는 것이 우선한다. * 여기 지정된 값을 ''project'' 객체를 통해 접근할 수 있다. * ''-P프라퍼티명=값''으로 ''project'' 객체에 프라퍼티를 추가한다. * 환경변수 ''ORG_GRADLE_PROJECT_프라퍼티이름=값''으로 ''project'' 객체에 프라퍼티를 추가한다. * 시스템 프라퍼티 ''org.gradle.project.프라퍼티이름=값''으로 ''project'' 객체에 프라퍼티를 추가한다. * ''gradle.properties''의 프라퍼티 중에 ''systemProp.''으로 시작하는 프라퍼티는 시스템 프라퍼티로 변환된다. * ''gradle.properties'' gradlePropertiesProp=gradlePropertiesValue systemPropertiesProp=shouldBeOverWrittenBySystemProp envPropertiesProp=shouldBeOverWrittenByEnvProp systemProp.system=systemValue * ''build.gradle'' task printProps << { println commandLineProjectProp println gradlePropertiesProp println systemProjectProp println envProjectProp println System.properties['system'] } * 실행하면 > gradle -q -PcommandLineProjectProp=commandLineProjectPropValue -Dorg.gradle.project.systemProjectProp=systemPropertyValue printProps commandLineProjectPropValue gradlePropertiesValue systemPropertyValue envPropertyValue systemValue === 프로젝트 프라퍼티 검사 === * 프로젝트 프라퍼티는 빌드 스크립트에서 프라퍼티 이름으로 바로 접근 가능하다. 하지만 프라퍼티가 존재하지 않으면 예외가 발생한다. * ''hasProperty('propertyName')''으로 프라퍼티의 존재 여부를 검사할 수 있다. ==== 외부 빌드 스크립트로 프로젝트 구성하기 ==== 외부 ''*.gradle'' 빌드 스크립트를 만들어서 불러올 수 있다. * ''build.gradle''에서 ''other.gradle''을 불러온다. apply from: 'other.gradle' * ''other.gradle'' println "configuring $project" task hello << { println 'hello from other script' } * 실행하면 > gradle -q hello configuring root project 'configureProjectUsingScript' hello from other script ==== 임의의 객체 구성하기 ==== ''configure'' 메소드로 임의의 객체를 구성할 수 있다. * ''build.gradle'' task configure << { pos = configure(new java.text.FieldPosition(10)) { beginIndex = 1 endIndex = 5 } println pos.beginIndex println pos.endIndex } * 실행하면 > gradle -q configure 1 5 ==== 외부 스크립트로 임의의 객체 구성하기 ==== * ''build.gradle'' task configure << { pos = new java.text.FieldPosition(10) // 외부 스크립트 적용 apply from: 'other.gradle', to: pos println pos.beginIndex println pos.endIndex } * ''other.gradle'' beginIndex = 1; endIndex = 5; * 실행하면 > gradle -q configure 1 5 ==== 외부 빌드 스크립트에서 메소드 선언 노출시키기 ==== * [[https://stackoverflow.com/questions/18715137/extract-common-methods-from-gradle-build-script|build.gradle - Extract common methods from Gradle build script - Stack Overflow]] // 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 } // -- 실제 build.gradle 에서는 apply from: "$rootDir/helpers/common-methods.gradle" task myBuildTask { def myVar = commonMethod1("parameter1") otherNameForMethod2(myVar) } ==== 캐싱 cache ==== Gradle은 컴파일한 스크립트를 캐싱한다. 프로젝트에서 처음으로 빌드를 실행하면 ''.gradle'' 디렉토리가 만들어지고 거기에 컴파일된 스크립트가 들어간다. 다음에 다시 빌드를 실행하면 스크립트에 변경이 없다면 컴파일 해뒀던 것을 실행한다. 그렇지 않으면 재 컴파일을 하고 캐시에 새로운 버전이 들어간다. ''%%--%%recompile-scripts'' 옵션으로 실행하면 캐시를 삭제하고 모두 다시 컴파일해서 캐시에 새로 저장한다. ===== 자세히 살펴보기 ===== * [[gradle:task|Gradle Task]] * [[gradle:files|Gradle 파일 다루기]] * [[gradle:ant|Gradle Ant 호출]] * [[gradle:dependencies|Gradle Dependencies]] * [[gradle:buildlifecycle|Gradle Build Lifecycle]] * [[gradle:multiproject|Gradle Multi Project]] * [[gradle:logging|Gradle Logging]] * [[gradle:daemon|Gradle Daemon]] * [[gradle:build_env|Gradle 빌드 환경 설정]] * [[gradle:organizing_build_logic|Gradle Organizing Build Logic]] * [[gradle:customtask|Gradle Custom Task]] * [[gradle:customplugins|Gradle Writing Custom Plugins]] * [[gradle:init_scripts|Gradle Initialization Scripts]] * [[gradle:wrapper|Gradle Wrapper]] * [[gradle:shell_completion|Gradle Shell Completion]] * [[gradle:from_maven|Maven에서 Gradle로]] * [[gradle:jpa_metamodel_generation|Gradle에서 JPA2 MetaModel 생성]] ===== Plugins ===== * [[gradle:plugins|Gradle Plugins]] * [[gradle:java|Gradle Java Plugin]] * [[gradle:web|Gradle Web Plugin]] * [[gradle:jetty|Gradle Jetty Plugin]] * [[gradle:tomcat|Gradle Tomcat Plugin]] * [[gradle:eclipse|Gradle Ecplise Plugin]] * [[gradle:groovy|Gradle Groovy Plugin]] * [[gradle:report|Gradle Report Plugin]] * [[gradle:javascript|Gradle Javascript Plugin]] ===== 읽을꺼리 ===== * [[http://java.dzone.com/articles/gradle-goodness-using-objects|Gradle Goodness: Using Objects for Version]]