문서의 선택한 두 판 사이의 차이를 보여줍니다.
| 양쪽 이전 판 이전 판 다음 판 | 이전 판 | ||
|
gradle:customplugins [2012/10/04 15:09] kwon37xi |
gradle:customplugins [2020/05/24 20:43] (현재) kwon37xi |
||
|---|---|---|---|
| 줄 1: | 줄 1: | ||
| ====== Gradle Custom Plugins ====== | ====== Gradle Custom Plugins ====== | ||
| * [[http:// | * [[http:// | ||
| - | * [[http:// | + | * [[http:// |
| + | |||
| + | Gradle 플러그인은 재사용 가능한 빌드 로직을 패키지화하여 여러 서로다른 프로젝트와 빌드에서 사용할 수 있도록 한 것이다. | ||
| + | |||
| + | 플러그인은 아무 언어로 작성해도 되며 Java 바이트코드로 컴파일해서 제공하기만 하면 된다. | ||
| + | |||
| + | ===== 플러그인 패키징 ===== | ||
| + | |||
| + | ==== 빌드 스크립트 ==== | ||
| + | 빌드 스크립트에 직접 플러그인 소스를 작성해도 된다. 자동으로 컴파일되어 빌드 스크립트의 클래스패스에 추가된다. 플러그인을 선언한 빌드 스크립트 외부에서는 접근할 수 없다. | ||
| + | |||
| + | ==== buildSrc 프로젝트 ==== | ||
| + | 추천하는 방식. | ||
| + | |||
| + | [[gradle: | ||
| + | |||
| + | 이렇게 할 경우 모든 프로젝트의 빌드 스크립트에서 이 플러그인에 접근 가능하다. | ||
| + | |||
| + | ==== 독립 프로젝트 ==== | ||
| + | 플러그인용 독립 프로젝트를 만들고 Jar로 묶어서 배포한다. | ||
| + | |||
| + | ===== 간단한 플러그인 작성 ===== | ||
| + | [[http:// | ||
| + | |||
| + | * 사용자 정의 플러그인 '' | ||
| + | apply plugin: GreetingPlugin | ||
| + | |||
| + | class GreetingPlugin implements Plugin< | ||
| + | void apply(Project project) { | ||
| + | project.task(' | ||
| + | println "Hello from the GreetingPlugin" | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | * 실행하면 < | ||
| + | > gradle -q hello | ||
| + | Hello from the GreetingPlugin | ||
| + | </ | ||
| + | |||
| + | 플러그인이 적용되는 모든 프로젝트에 대해서 플러그인 인스턴스가 각각 하나씩 생성된다. | ||
| + | |||
| + | ===== 빌드에서 입력 받기 ===== | ||
| + | 플러그인들은 대부분 빌드 스크립트에서 설정을 해야할 필요가 있다. 이때 확장 객체(extension object)를 사용한다. Gradle의 Project는 [[http:// | ||
| + | |||
| + | * '' | ||
| + | apply plugin: GreetingPlugin | ||
| + | |||
| + | // 확장 객체 값 사용 | ||
| + | greeting.message = 'Hi from Gradle' | ||
| + | |||
| + | class GreetingPlugin implements Plugin< | ||
| + | void apply(Project project) { | ||
| + | // ' | ||
| + | project.extensions.create(" | ||
| + | |||
| + | // 관련 설정을 사용하는 태스크 추가 | ||
| + | project.task(' | ||
| + | println project.greeting.message | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | class GreetingPluginExtension { | ||
| + | def String message = 'Hello form GreetingPlugin' | ||
| + | } | ||
| + | </ | ||
| + | * 실행하면 < | ||
| + | > gradle -q hello | ||
| + | Hi from Gradle | ||
| + | </ | ||
| + | |||
| + | 이 예제에서 '' | ||
| + | |||
| + | 종종 지정할 프라퍼티가 많은 경우 확장 객체에 구성 클로저 블록을 추가하여 한번에 설정할 수 있도록 해준다. | ||
| + | |||
| + | * 구성 클로저를 사용하는 플러그인 '' | ||
| + | apply plugin: GreetingPlugin | ||
| + | |||
| + | // 확장 객체의 프라퍼티들을 | ||
| + | greeting { | ||
| + | message = ' | ||
| + | greeter = ' | ||
| + | } | ||
| + | |||
| + | class GreetingPlugin implements Plugin< | ||
| + | void apply(Project project) { | ||
| + | project.extensions.create(" | ||
| + | project.task(' | ||
| + | println " | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | class GreetingPluginExtension { | ||
| + | String message | ||
| + | String greeter | ||
| + | } | ||
| + | </ | ||
| + | * 실행하면 < | ||
| + | > gradle -q hello | ||
| + | Hi from Gradle | ||
| + | </ | ||
| + | |||
| + | 클로저 블럭의 이름('' | ||
| + | |||
| + | ===== 사용자 정의 태스크와 플러그인에서 파일 다루기 ===== | ||
| + | [[http:// | ||
| + | |||
| + | * 파일 프라퍼티를 늦게 평가하기 '' | ||
| + | class GreetingToFileTask extends DefaultTask { | ||
| + | |||
| + | def destination | ||
| + | |||
| + | File getDestination() { | ||
| + | project.file(destination) | ||
| + | } | ||
| + | |||
| + | @TaskAction | ||
| + | def greet() { | ||
| + | def file = getDestination() | ||
| + | file.parentFile.mkdirs() | ||
| + | file.write " | ||
| + | } | ||
| + | } | ||
| + | |||
| + | task greet(type: GreetingToFileTask) { | ||
| + | destination = { project.greetingFile } | ||
| + | } | ||
| + | |||
| + | task sayGreeting(dependsOn: | ||
| + | println file(greetingFile).text | ||
| + | } | ||
| + | |||
| + | greetingFile = " | ||
| + | </ | ||
| + | * 실행하면 < | ||
| + | > gradle -q sayGreeting | ||
| + | Hello! | ||
| + | </ | ||
| + | |||
| + | 위 예제에서는 태스크의 '' | ||
| + | |||
| + | ===== 독립 프로젝트 ===== | ||
| + | 독립 프로젝트로 만들면 jar로 배포하여 다른 사람들과 공유할 수 있다. 보통 다음과 같은 최소한의 빌드 스크립트로 시작한다. | ||
| + | |||
| + | * 사용자 정의 플러그인을 위한 '' | ||
| + | apply plugin: ' | ||
| + | |||
| + | dependencies { | ||
| + | compile gradleApi() | ||
| + | groovy localGroovy() | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Gradle은 [[http:// | ||
| + | * '' | ||
| + | implementation-class=org.gradle.GreetingPlugin | ||
| + | </ | ||
| + | |||
| + | 프라퍼티 파일의 이름이 플러그인의 이름이 된다. '' | ||
| + | |||
| + | ==== 다른 프로젝트에서 플러그인 사용하기 ==== | ||
| + | '' | ||
| + | |||
| + | * 다른 프로젝트에서 사용자 정의 플러그인을 사용하는 '' | ||
| + | buildscript { | ||
| + | repositories { | ||
| + | maven { | ||
| + | url uri(' | ||
| + | } | ||
| + | } | ||
| + | dependencies { | ||
| + | classpath group: ' | ||
| + | } | ||
| + | } | ||
| + | apply plugin: ' | ||
| + | </ | ||
| + | |||
| + | ==== 플러그인의 테스트 작성하기 ==== | ||
| + | [[http:// | ||
| + | |||
| + | * '' | ||
| + | class GreetingPluginTest { | ||
| + | @Test | ||
| + | public void greeterPluginAddsGreetingTaskToProject() { | ||
| + | Project project = ProjectBuilder.builder().build() | ||
| + | project.apply plugin: ' | ||
| + | |||
| + | assertTrue(project.tasks.hello instanceof GreetingTask) | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== 다중 도메인 객체 처리하기 ===== | ||
| + | Gradle은 빌드 언어와 잘 작동하는 객체의 컬렉션을 다루는 도우미 클래스를 제공해주고 있다. | ||
| + | |||
| + | * 도메인 객체를 다루는 '' | ||
| + | apply plugin: DocumentationPlugin // DocumentaionPlugin.apply()가 실행된다. | ||
| + | |||
| + | // books NamedDomainObjectContainer 값을 구성한다. apply보다 나중에 실행되지만 ' | ||
| + | books { | ||
| + | quickStart { | ||
| + | sourceFile = file(' | ||
| + | } | ||
| + | userGuide { | ||
| + | } | ||
| + | developerGuide { | ||
| + | } | ||
| + | } | ||
| + | |||
| + | task books << { | ||
| + | books.each { book -> | ||
| + | println " | ||
| + | } | ||
| + | } | ||
| + | |||
| + | class DocumentationPlugin implements Plugin< | ||
| + | void apply(Project project) { | ||
| + | def books = project.container(Book) | ||
| + | books.all { // 현재 있는, 그리고 앞으로 컬렉션에 추가될 객체를 모두 돌면서 아래 수행 | ||
| + | sourceFile = project.file(" | ||
| + | } | ||
| + | project.extensions.books = books | ||
| + | } | ||
| + | } | ||
| + | |||
| + | class Book { | ||
| + | final String name // ' | ||
| + | File sourceFile | ||
| + | |||
| + | Book(String name) { | ||
| + | this.name = name | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | * 실행하면 < | ||
| + | developerGuide -> / | ||
| + | quickStart -> / | ||
| + | userGuide -> / | ||
| + | </ | ||
| + | |||
| + | [[http:// | ||
| + | |||
| + | '' | ||
| + | |||
| + | '' | ||
| + | |||
| + | [[http:// | ||
| + | |||
| + | ===== 태스크간의 의존성 ===== | ||
| + | 플러그인 태스크 간의 의존성은 다음과 같은 형태로 정의할 수 있다. | ||
| + | |||
| + | <code groovy> | ||
| + | project.task(' | ||
| + | dependsOn(project.tasks.a, | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== 플러그인에 의존성 주입 ===== | ||
| + | * [[https:// | ||
| + | * '' | ||
| + | * [[https:// | ||
| + | |||
| + | ===== 참조 ===== | ||
| + | * [[https:// | ||