사용자 도구

사이트 도구


gradle:customplugins

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판 이전 판
다음 판
이전 판
gradle:customplugins [2012/10/06 20:31]
kwon37xi [사용자 정의 태스크와 플러그인에서 파일 다루기]
gradle:customplugins [2020/05/24 20:43] (현재)
kwon37xi
줄 77: 줄 77:
 종종 지정할 프라퍼티가 많은 경우 확장 객체에 구성 클로저 블록을 추가하여 한번에 설정할 수 있도록 해준다. 종종 지정할 프라퍼티가 많은 경우 확장 객체에 구성 클로저 블록을 추가하여 한번에 설정할 수 있도록 해준다.
  
-  * 구성 클로를 사용하는 플러그인 ''build.gradle'' <code groovy>+  * 구성 클로를 사용하는 플러그인 ''build.gradle'' <code groovy>
 apply plugin: GreetingPlugin apply plugin: GreetingPlugin
  
줄 145: 줄 145:
  
 ===== 독립 프로젝트 ===== ===== 독립 프로젝트 =====
 +독립 프로젝트로 만들면 jar로 배포하여 다른 사람들과 공유할 수 있다. 보통 다음과 같은 최소한의 빌드 스크립트로 시작한다.
  
 +  * 사용자 정의 플러그인을 위한 ''build.gradle'' <code groovy>
 +apply plugin: 'groovy'
 +
 +dependencies {
 +    compile gradleApi()
 +    groovy localGroovy()
 +}
 +</code>
 +
 +Gradle은 [[http://www.gradle.org/docs/current/javadoc/org/gradle/api/Plugin.html|Plugin]] 구현체를 ''META-INF/gradle-plugins''에서 플러그인 이름과 같은 프라퍼티 파일을 통해 찾는다.
 +  * ''src/main/resources/META-INF/gradle-plugins/greeting.properties'' <code properties>
 +implementation-class=org.gradle.GreetingPlugin
 +</code>
 +
 +프라퍼티 파일의 이름이 플러그인의 이름이 된다. ''implementation-class'' 프라퍼티는 Plugin 구현 클래스를 가리킨다.
 +
 +==== 다른 프로젝트에서 플러그인 사용하기 ====
 +''buildscript { }'' 블럭을 통해 클래스패스에 사용자 정의 플래그인 클래스를 추가한다. [[gradle:organizing_build_logic|Gradle Organizing Build Logic]] 참조. 다음 예제는 로컬 리포지토리에 플러그인을 저장해서 사용하는 것을 보여준다.
 +
 +  * 다른 프로젝트에서 사용자 정의 플러그인을 사용하는 ''build.gradle'' <code groovy>
 +buildscript {
 +    repositories {
 +        maven {
 +            url uri('../repo')
 +        }
 +    }
 +    dependencies {
 +        classpath group: 'org.gradle', name: 'customPlugin', version: '1.0-SNAPSHOT'
 +    }
 +}
 +apply plugin: 'greeting'
 +</code>
 +
 +==== 플러그인의 테스트 작성하기 ====
 +[[http://www.gradle.org/docs/current/javadoc/org/gradle/testfixtures/ProjectBuilder.html|ProjectBuilder]] 클래스를 사용하여 [[http://www.gradle.org/docs/current/dsl/org.gradle.api.Project.html|Project]] 인스턴스를 만들어낼 수 있다. 이를 통해 플러그인 구현체를 테스트한다.
 +
 +  * ''src/test/groovy/org/gradle/GreetingPluginTest.groovy'' <code groovy>
 +class GreetingPluginTest {
 +    @Test
 +    public void greeterPluginAddsGreetingTaskToProject() {
 +        Project project = ProjectBuilder.builder().build()
 +        project.apply plugin: 'greeting'
 +
 +        assertTrue(project.tasks.hello instanceof GreetingTask)
 +    }
 +}
 +</code>
 +
 +===== 다중 도메인 객체 처리하기 =====
 +Gradle은 빌드 언어와 잘 작동하는 객체의 컬렉션을 다루는 도우미 클래스를 제공해주고 있다.
 +
 +  * 도메인 객체를 다루는 ''build.gradle'' <code groovy>
 +apply plugin: DocumentationPlugin // DocumentaionPlugin.apply()가 실행된다.
 +
 +// books NamedDomainObjectContainer 값을 구성한다. apply보다 나중에 실행되지만 'books.all { }'의 행위가 다 적용된다.
 +books {
 +    quickStart {
 +        sourceFile = file('src/docs/quick-start')
 +    }
 +    userGuide {
 +    }
 +    developerGuide {
 +    }
 +}
 +
 +task books << {
 +    books.each { book ->
 +        println "$book.name -> $book.sourceFile"
 +    }
 +}
 +
 +class DocumentationPlugin implements Plugin<Project> {
 +    void apply(Project project) {
 +        def books = project.container(Book)
 +        books.all { // 현재 있는, 그리고 앞으로 컬렉션에 추가될 객체를 모두 돌면서 아래 수행
 +            sourceFile = project.file("src/docs/$name")
 +        }
 +        project.extensions.books = books
 +    }
 +}
 +
 +class Book {
 +    final String name // 'name' 필드는 필수이며 상수이고 유일한 값이어야 한다.
 +    File sourceFile
 +
 +    Book(String name) {
 +        this.name = name
 +    }
 +}
 +</code>
 +  * 실행하면 <code>
 +developerGuide -> /home/user/gradle/samples/userguide/organizeBuildLogic/customPluginWithDomainObjectContainer/src/docs/developerGuide
 +quickStart -> /home/user/gradle/samples/userguide/organizeBuildLogic/customPluginWithDomainObjectContainer/src/docs/quick-start
 +userGuide -> /home/user/gradle/samples/userguide/organizeBuildLogic/customPluginWithDomainObjectContainer/src/docs/userGuide
 +</code>
 +
 +[[http://www.gradle.org/docs/current/dsl/org.gradle.api.Project.html#org.gradle.api.Project:container(java.lang.Class)|Project.container()]]는 [[http://www.gradle.org/docs/current/javadoc/org/gradle/api/NamedDomainObjectContainer.html|NamedDomainObjectContainer]]의 인스턴스를 생성한다. 이 클래스에는 객체를 관리하고 구성하는 편리한 메소드들이 들어있다.
 +
 +''project.container'' 메소드를 통해 사용할 객체의 타입은 항상 **''name''** 이라는 프라퍼티를 가지고 있어야 하며, 이 필드는 객체의 이름으로써 유일한 값이면서 상수여야 한다.
 +
 +''project.container(Class)'' 메소드는 객체의 새로운 인스턴스를 생성하면서 하나의 문자열을 인자로 받아 객체의 이름(''name'')으로 지정하려고 시도한다.
 +
 +[[http://www.gradle.org/docs/current/javadoc/org/gradle/api/NamedDomainObjectContainer.html|NamedDomainObjectContainer]]는 [[http://www.gradle.org/docs/current/javadoc/org/gradle/api/DomainObjectCollection.html|DomainObjectCollection]]을 상속하고 있다. [[http://www.gradle.org/docs/current/javadoc/org/gradle/api/DomainObjectCollection.html#all%28org.gradle.api.Action%29|DomainObjectCollection.all()]] 메소드는 컬렉션에 현재 있는 항목들과 그 이후 추가될 항목들까지 돌면서 클로저의 내용을 실행한다. 따라서 여기서 ''books'' 선언이 플러그인 적용보다 늦게 발생했으나 ''books.all {}'' 블럭의 내용이 모두 자동으로 실행되게 된다.
 +
 +===== 태스크간의 의존성 =====
 +플러그인 태스크 간의 의존성은 다음과 같은 형태로 정의할 수 있다.
 +
 +<code groovy>
 +project.task('sometask') {
 +    dependsOn(project.tasks.a, project.tasks.b)
 +}
 +</code>
 +
 +===== 플러그인에 의존성 주입 =====
 +  * [[https://github.com/gradle/gradle/blob/master/design-docs/dependency-injection-for-plugins.md|플러그인 개발시 필요한 의존성을 생성자를 통해 주입하기]]
 +  * ''@Inject'' 애노테이션을 사용한다.
 +  * [[https://github.com/gradle/gradle/blob/master/subprojects/maven/src/main/groovy/org/gradle/api/plugins/MavenPlugin.java|MavenPlugin.java]]에서 ''@Inject'' 사용예를 볼 수 있다.
 +
 +===== 참조 =====
 +  * [[https://dzone.com/articles/functional-tests-gradle-plugin|How to Test Gradle Plugins - DZone Java]]
gradle/customplugins.1349523092.txt.gz · 마지막으로 수정됨: 2012/10/06 20:31 저자 kwon37xi