반응형

Gradle 시작하기

Maven 을 대체할수 있는 Groovy DSL 기반 어쩌구 저쩌구 하는데.. 다 됐고! Spring 이 빌드 시스템을 Maven 에서 Gradle 로 변경했다고 한다.

Gradle 이 왜 Maven 보다 좋은지, 왜 사용해야하는지를 알고 싶다면 글 마지막 부분에 있는 여기 를 참고하도록 하자.

1. Installing Gradle

먼저 여기 를 통해 Gradle 을 다운받자. 바이너리를 받으면 되고 이후에는 적당한 폴더에 압축을 풀면 된다. 그 후에는 가이드 를 따라서 환경변수를 등록하면 된다. 내 경우에는 C:\gradle 에 설치를 했다.

// 환경변수 추가
GRADLE_HOME - 'C:\gradle'
Path - 'C:\gradle\bin'

cmd > gradle -v // 터미널에서 Gradle 버전 확인
------------------------------------------------------------
Gradle 1.10
------------------------------------------------------------

Build time:   2013-12-17 09:28:15 UTC
Build number: none
Revision:     36ced393628875ff15575fa03d16c1349ffe8bb6

Groovy:       1.8.6
Ant:          Apache Ant(TM) version 1.9.2 compiled on July 8 2013
Ivy:          2.2.0
JVM:          1.7.0_45 (Oracle Corporation 24.45-b08)
OS:           Windows 7 6.1 x86


2. Installing Gradle on STS

이건 더 쉽다. Sping Tool Suite 에서 Dashboard -> Install Extension -> Gradle Support

3. Making Build Script

Gradle BuildProjectTask 라는 단위로 나누어진다. 하나의 Build는 여러개의 Project로 나뉠 수 있고 다시 Project는 하나 이상의 Task 로 나뉠 수 있다. Project는 웹 어플리케이션 배포나, Jar 컴파일등의 작업으로 볼 수 있고 이걸 하기 위해서 진행되는 세부적인 작업이 Task라고 보면 된다. 좀 더 정확한 설명을 위해 원문을 첨부한다.

Everything in Gradle sits on top of two basic concepts: projects and tasks.

Every Gradle build is made up of one or more projects. A project represents some component of your software which can be built. What this means exactly depends on what it is that you are building. For example, a project might represent a library JAR or a web application. It might represent a distribution ZIP assembled from the JARs produced by other projects. A project does not necessarily represent a thing to be built. It might represent a thing to be done, such as deploying your application to staging or production environments. Don’t worry if this seems a little vague for now. Gradle’s build-by-convention support adds a more concrete definition for what a project is.

Each project is made up of one or more tasks. A task represents some atomic piece of work which a build performs. This might be compiling some classes, creating a JAR, generating javadoc, or publishing some archives to a repository.


그럼 실제 스크립트를 보도록 하자. 프로젝트 내에 build.gradle 파일이 하나씩 존재하며 gradle build처럼 실행시킬 수 있다.build란 단어 대신에 다른task 이름이 올 수 있다. gradle task1 처럼.


// gradle.build 
// created by STS Gradle Extension with Java Quickstart Option

// Java, Eclipse Project
apply plugin: 'java'
apply plugin: 'eclipse'

sourceCompatibility = 1.5
version = '1.0'
jar {
    manifest {
        attributes 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version
    }
}

// Maven Repository 사용
repositories {
    mavenCentral() 
}

// 사용하는 Maven Repository 지정
dependencies {
    compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
    testCompile group: 'junit', name: 'junit', version: '4.+'
}

test {
    systemProperties 'property': 'value'
}

uploadArchives {
    repositories {
       flatDir {
           dirs 'repos'
       }
    }
}


gradle test 를 통해 테스트만 실행하거나, gradle build를 통해 테스트를 포함해서 빌드를 실행할 수 있다.


다음번에는 조금 더 자세히 빌드 스크립트에 대해서 알아보겠다.

4. 후기

Gradle 에선 Groovy 를 사용한다는데 중간에 Gradle User Guide 보다가 소름 돋아서 후기를 남긴다. 디렉토리 이름을 받아 존재하는 파일들을 배열로 돌려주는 Groovy 코드.

File[] fileList(String dir) {
    file(dir).listFiles({file -> file.isFile() } as FileFilter).sort()
}

이게 함수형 언어를 사용하는 진짜 이유다. Java 였다면 얼마나 코드가 길어졌을까..

 

반응형
LIST
반응형

Gradle

설치

  • 설치 파일 압축을 풀고 설치 경로를 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"

실행속도 높이기

  • ${HOME}/.gradle/gradle.properties
    org.gradle.daemon=true
  • 이제부터 Gradle이 데몬으로 떠서 실행되기 때문에 초기 로딩 시간이 줄어든다.
  • 3시간동안 Gradle 작업이 없으면 데몬이 자동 종료된다.

스크립트에서 사용할 인증 정보 분리해두기

build setup

  • 프로젝트를 시작할 때 gradle init를 실행하면 현재 디렉토리에 Gradle 관련 기본 파일들을 생성해준다.(구버전은 setupBuild)
  • Maven 프로젝트 디렉토리에서 실행하면 자동 컨버팅을 실행한다.
  • 실행시 프로젝트 구조를 Java library로 지정하기(1.7 이후)
    gradle init --type java-library
     
    # --type 을 생략하면 basic 으로 지정된다.
  • Project Types
    • pom
    • basic
    • java-library
    • groovy-library
    • scala-library
  • Project 디렉토리 구조 생성 task
    // 적용된 프로그래밍 언어 플러그인에 따라 소스 트리 구조 자동 생성
    task initSrc << {
        project.sourceSets*.allSource.srcDirTrees.flatten().dir.each { dir ->
            dir.mkdirs()
        }
    }

명령 실행과 옵션

  • 기본적으로 gradle을 통해 실행되는 단위를 “Task 태스크”라고 한다.(Ant의 target, Maven의 phase와 유사한 개념)
  • 태스크는 의존 관계에 따라 단 한 번만 실행된다.
  • -q : quiet. 로그 안 찍음. 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들 다시 컴파일한다.
  • 환경변수 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 태스크들 : 태스크를 실제 수행은 하지 않고, 해당 태스크와 함께 실행되는 모든 태스크 목록을 순서대로 보여준다.

태스크 튜토리얼

  • 의존성 : 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 개발 관련 항목들을 읽어본다.

DSL

  • Groovy 빌드 파일은 기본적으로 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 : 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 옵션을 주면 강제 재컴파일 한다.

이것 저것

디렉토리 생성

  • 여러 태스크에서 특정 디렉토리를 필요로 할 경우에는, 디렉토리 생성 태스크를 만들고 다른 태스크가 그 태스크에 의존하도록 만든다.
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

캐싱 cache

Gradle은 컴파일한 스크립트를 캐싱한다. 프로젝트에서 처음으로 빌드를 실행하면 .gradle 디렉토리가 만들어지고 거기에 컴파일된 스크립트가 들어간다. 다음에 다시 빌드를 실행하면 스크립트에 변경이 없다면 컴파일 해뒀던 것을 실행한다. 그렇지 않으면 재 컴파일을 하고 캐시에 새로운 버전이 들어간다. --recompile-scripts 옵션으로 실행하면 캐시를 삭제하고 모두 다시 컴파일해서 캐시에 새로 저장한다.

자세히 살펴보기

Plugins

읽을꺼리

반응형
LIST

+ Recent posts