Using Gradle Plugins

appti·2021년 11월 2일
1

Gradle

목록 보기
4/5

해당 내용은 Gradle 공식 홈페이지의 내용을 정리한 내용입니다.

Using Gradle Plugins

자동화를 위해 Gradle의 핵심 코드들은 거의 제공되지 않습니다.
모든 유용한 기능들은 플러그인에 의해 추가됩니다.
플러그인은 새로운 작업, 도메인 객체, 관례를 추가할 뿐만 아니라 다른 플러그인의 핵심 객체와 객체를 확장합니다.

해당 가이드에서는 플러그인 사용 방법과 관련 용어 및 개념에 대해 설명합니다.

What plugins do

프로젝트에 플러그인을 적용하면 플러그인이 프로젝트의 기능을 확장할 수 있습니다.
다음과 같은 기능을 수행할 수 있습니다.

  • Gradle 모델 확장
  • 규칙에 따라 프로젝트 구성
  • 특정 구성 적용

프로젝트 빌드 스크립트에 로직을 추가하는 대신 플러그인을 적용하면 다음과 같은 이점을 얻을 수 있습니다.

  • 재사용을 촉진하고 여러 프로젝트에서 유사한 논리를 유지 관리하는 오버헤드를 줄입니다.
  • 더 높은 수준의 모듈화를 허용하여 유지보수가 좋아집니다.
  • 명령형 논리를 캡슐화하고 빌드 스크립트가 가능한 선언형 프로그래밍으로 구성될 수 있도록 합니다.

Types of plugins

플러그인은 두 가지 유형을 가지고 있습니다.

스크립트 플러그인

스크립트 플러그인은 빌드 조작에 대한 선언적 접근 방식을 제공하는 추가 빌드 스크립트입니다.
원격 위치에서 외부화하고 접근할 수 있지만 일반적으로 빌드 내에서 사용됩니다.

바이너리 플러그인

바이너리 플러그인은 Plugin 인터페이스를 구현하여 프로그래밍 방식으로 작성되거나 Gradle의 DSL 언어 중 하나를 사용하여 선언적으로 작성됩니다.
바이너리 플러그인은 빌드 스크립트 내, 프로젝트 계층 내 또는 플러그인 jar 외부에 있을 수 있습니다.

Using plugins

플러그인을 사용하기 위해서는 두 단계가 필요합니다.

첫 번째로, 플러그인을 귀결(resolve)야 합니다.
두 번째로, 플러그인 대상(일반적으로는 Project)에 적용해야 합니다.

플러그인을 귀결(Resolving a plugin)한다는 것은 주어진 플러그인을 포함하는 올바른 버전의 jar를 찾아 스크립트 클래스 경로에 추가하는 것을 의미합니다.
플러그인이 귀결되면 해당 API를 빌드 스크립트에서 사용할 수 있습니다.
Gradle 배포의 일부로 제공되는 핵심 바이너리 플러그인은 자동으로 귀결됩니다.

플러그인을 적용(Applying a plugin)한다는 것은 플러그인을 사용하고자 하는 프로젝트에서 플러그인의 Plugin.apply(T)를 실행하는 것을 의미합니다.
모든 플러그인은 여러 번 안전하게 적용할 수 있습니다.

플러그인을 사용하는 가장 일반적인 사용 사례는 플러그인을 귀결하고 현재 프로젝트에 적용(apply)하는 것입니다.
그러므로 DSL 플러그인을 사용하여 한 번에 플러그인을 귀결하고 적용하는 것을 권장합니다.

Binary plugins

바이너리 플러그인의 경우 플러그인의 전역 고유 식별자 또는 이름을 의미하는 플러그인 ID를 통해 적용합니다.
Core Gradle 플러그인은 JavaPlugin을 java와 같이 짧은 이름으로 제공합니다.
다른 모든 바이너리 플러그인은 정규화된 형식의 플러그인 ID(com.github.foo.bar)를 사용해야 하지만 일부 레거시 플러그인은 짧고 정규화되지 않은 형식을 사용할 수 있습니다.
DSL 플러그인을 사용하던지, buildscript 블록을 사용하던지 동일한 플러그인 ID로 적용할 수 있습니다.

Locations of binary plugins

플러그인은 단순히 Gradle의 플러그인 인터페이스를 구현하는 모든 클래스입니다.
Gradle은 JavaPlugin 배포의 일부로 핵심 플러그인을 제공하기 때문에 귀결할 필요가 없습니다.

그러나 비핵심 바이너리 플러그인을 적용하려면 먼저 플러그인을 귀결해야 합니다.
방법은 다음과 같습니다.

  • 플러그인 포털 또는 DSL 플러그인을 사용하는 사용자 지정 저장소의 플러그인 포함
  • buildscript 종속성으로 정의된 외부 jar의 플러그인 포함
  • 플러그인을 프로젝트의 buildSrc 디렉토리 아래에 소스 파일로 정의
  • 플러그인을 빌드 스크립트 내에서 인라인 클래스 선언으로 정의

Applying plugins with the plugins DSL

DSL 플러그인은 플러그인 종속성을 선언하는 간결하고 편리한 방법을 제공합니다.
Gradle 플러그인 포털과 함께 작동하여 핵심 플러그인과 커뮤니티 플러그인 모두에 쉽게 접근할 수 있습니다.
DSL 플러그인 블록은 PluginDependenciesSpec의 인스턴스를 생성합니다.

핵심 플러그인을 적용하기 위해 짧은 플러그인 ID를 사용할 수 있습니다.

plugins {
    id 'java'
}

만약 Gradle 플러그인 포털에서 커뮤니티 플러그인을 적용하려면 정규화된 플러그인 ID를 사용해야 합니다.

plugins {
    id 'com.jfrog.bintray' version '1.8.5'
}

Limitations of the plugins DSL

DSL 플러그인은 Gradle이 사용 중인 플러그인을 초기에 빠르게 결정할 수 있는 방식으로 처리됩니다.
이를 통해 Gradle은 다음과 같은 스마트한 작업을 수행할 수 있습니다.

  • 플러그인 클래스의 로드 및 재사용을 최적화합니다.
  • 서로 다른 플러그인이 서로 다른 버전의 종속성을 사용하는 것을 허용합니다.
  • 편집 지원을 위해 빌드 스크립트의 잠재적 속성 및 값에 대한 자세한 정보를 개발자에게 제공합니다.

이를 위해서는 나머지 빌드 스크립트를 실행하기 전에 Gradle이 추출할 수 있는 방식으로 플러그인을 지정해야 합니다.
또한 사용할 플러그인의 정의가 다소 정적이어야 합니다.

plugins {} 블록은 임의의 코드를 지원하지 않습니다.
멱등성(매번 동일한 결과 생성)과 부작용이 없도록(Gradle이 언제든지 실행하기에 안전함) 제한됩니다.

형식은 다음과 같습니다.

plugins {
    id «plugin id»                                            
    id «plugin id» version «plugin version» [apply «false»]   
}

id «plugin id»의 경우 빌드 스크립트에서 이미 사용 가능한 플러그인이거나 핵심 Gradle 플러그인이어야 합니다.
id «plugin id» version «plugin version» [apply «false»]의 경우 귀결이 필요한 바이너리 Gradle 플러그인의 경우입니다.

서브 프로젝트에서만 해당 플러그인을 사용해야 한다면, apply 옵션을 통해 해당 플러그인이 즉시 적용되지 않도록 설정할 수 있습니다.

plugin {}블록의 경우 buildscript에서 최상위에 위치해야 합니다.
다른 구조(for, if) 안에 존재할 수 없습니다.

Can only be used in build scripts and settings file

plugins {} 블록은 프로젝트 빌드 스크립트와 settings.gradle 파일에서만 사용할 수 있습니다.
스크립트 플러그인이나 초기화 스크립트에서는 사용할 수 없습니다.

만약 plugins {} 블록 사용이 불가능하다면, buildscript {} 블록을 사용하는 것을 권장합니다.

Applying external plugins with same version to subprojects

다중 프로젝트 빌드가 있는 경우 빌드의 일부 또는 전체 하위 프로젝트에 플러그인을 적용하고 싶지만 루트 프로젝트에서는 적용하고 싶지 않을 경우가 있습니다.
plugins {} 블록의 기본 동작은 플러그인을 즉시 귀결 및 적용합니다.
그러므로 apply false 구문을 사용하여 현재 프로젝트에서 플러그인을 적용하지 않도록 Gradle에 지시한 다음 plugins {} 하위 프로젝트의 빌드 스크립트에서 버전 없이 블록을 사용할 수 있습니다.

settings.gradle

include 'hello-a'
include 'hello-b'
include 'goodbye-c'
build.gradle
plugins {
    id 'com.example.hello' version '1.0.0' apply false
    id 'com.example.goodbye' version '1.0.0' apply false
}
hello-a/build.gradle
plugins {
    id 'com.example.hello'
}
hello-b/build.gradle
plugins {
    id 'com.example.hello'
}
goodbye-c/build.gradle
plugins {
    id 'com.example.goodbye'
}

Applying plugins from the buildSrc directory

정의된 ID가 있다면 프로젝트의 buildSrc 디렉토리에 있는 플러그인을 적용할 수 있습니다.

다음 예제는 buildSrc에 my.MyPlugin으로 정의된 플러그인 구현 클래스를 생성하고 플러그인 ID를 my-plugin으로 연결하는 예제입니다.

// buildSrc/build.gradle

plugins {
    id 'java-gradle-plugin'
}

gradlePlugin {
    plugins {
        myPlugins {
            id = 'my-plugin'
            implementationClass = 'my.MyPlugin'
        }
    }
}

위 예제처럼 buildSrc에 my-plugin이라는 플러그인을 정의합니다.

// build.gradle

plugins {
    id 'my-plugin'
}

Plugin Management

settings.gradle 또는 초기화 스크립트에 정의한 pluginManagement {} 블록을 통해 플러그인을 관리할 수 있습니다.

// settings.gradle

pluginManagement {
    plugins {
    }
    resolutionStrategy {
    }
    repositories {
    }
}

rootProject.name = 'plugin-management'
// init.gradle

settingsEvaluated { settings ->
    settings.pluginManagement {
        plugins {
        }
        resolutionStrategy {
        }
        repositories {
        }
    }
}

Custom Plugin Repositories

기본적으로 plugins {} DSL은 Gradle 플러그인 포털에서 플러그인을 확인합니다.
빌드에 사용할 수 있는 플러그인을 더 많이 제어하기 위해 개인 Maven 또는 lvy 리포지토리에서 플러그인을 해결할 수 있습니다.

사용자 정의 플러그인 저장소를 지정하려면 pluginManagement {} 블록 내부에 repositories {} 내부 블록을 사용하십시오.

// settings.gradle

pluginManagement {
    repositories {
        maven {
            url './maven-repo'
        }
        gradlePluginPortal()
        ivy {
            url './ivy-repo'
        }
    }
}

위 예제는 Gradle이 ../maven-repo 플러그인을 확인할 때 Maven 저장소를 먼저 살펴본 다음 Maven 저장소에서 플러그인을 찾을 수 없는 경우 Gradle 플러그인 포털을 확인하도록 합니다.
마지막으로 lvy 저장소 ../ivy-repo를 확인합니다.

Gradle 플러그인 포털을 확인하고 싶지 않을 경우 gradlePluginPortal() 행을 생략하면 됩니다.

이 방식으로 플러그인 버전을 설정할 경우 하나의 이점을 얻을 수 있습니다.
빌드 스크립트의 plugins {}블록과 pluginManagement.plugins {}에 동일하게 제한된 문법이 없다는 것입니다.
pluginManagement {} 블록을 사용할 경우 gradle.properties나 다른 메커니즘을 통해 플러그인 버전을 가져올 수 있습니다.

// settings.gradle

pluginManagement {
  plugins {
        id 'com.example.hello' version "${helloPluginVersion}"
    }
}
// build.gradle

plugins {
    id 'com.example.hello'
}
// gradle.properties

helloPluginVersion=1.0.0

플러그인 버전은 gradle.properties 설정 스크립트에서 로드 되고 구성되므로 버전을 지정하지 않고도 모든 프로젝트에 플러그인을 추가할 수 있습니다.

Plugin Resolution Rules

플러그인 귀결 규칙을 사용하면 plugins {} 블록으로 이루어진 플러그인 요청을 수정할 수 있습니다.

귀결 규칙을 추가하려면 pluginManagement {} 블록 내부에 resolutionStrategy {} 블록을 사용하면 됩니다.

// settings.gradle

pluginManagement {
    resolutionStrategy {
        eachPlugin {
            if (requested.id.namespace == 'com.example') {
                useModule('com.example:sample-plugins:1.0.0')
            }
        }
    }
    repositories {
        maven {
            url './maven-repo'
        }
        gradlePluginPortal()
        ivy {
            url './ivy-repo'
        }
    }
}

위 예제는 플러그인 ID에서 Maven/Ivy 좌표로의 기본 제공 매핑을 사용하는 대신 지정된 플러그인 구현 아티팩트를 사용하도록 Gradle에게 지시합니다.

사용자 지정 Maven 및 Ivy 플러그인 저장소에는 플러그인을 실제로 구현하는 아티팩트 외에 플러그인 마커 아티팩트가 포함되어야 합니다.

Plugin Marker Artifacts

plugins {} DSL 블록은 전역적으로 고유한 플러그인 ID 및 버전 속성으로 플러그인 선언만 허용하므로 Gradle은 플러그인 구현 Artifact의 좌표(coordinates)를 조회할 방법이 필요합니다.

이를 위해 Gradle은 좌표가 plugin.id:plugin.id.gradle.plugin:plugin.version
인 Plugin Marker Artifacts를 찾습니다.

이 Marker는 실제 플러그인 구현에 의존해야 합니다.
이러한 Marker는 java-gradle-plugin에 의해 자동화됩니다.

그 예로, 다음과 같은 sample-plugins의 전체 예시는 com.example.hello 플러그인와 com.example.goodbye 플러그인 양쪽을 java-gradle-plugin, maven-publish 플러그인, ivy-publish 플러그인의 조합을 통해 Ivy와 Maven Repository로 publishing하는 방법을 보여줍니다.

// build.gradle

plugins {
    id 'java-gradle-plugin'
    id 'maven-publish'
    id 'ivy-publish'
}

group 'com.example'
version '1.0.0'

gradlePlugin {
    plugins {
        hello {
            id = 'com.example.hello'
            implementationClass = 'com.example.hello.HelloPlugin'
        }
        goodbye {
            id = 'com.example.goodbye'
            implementationClass = 'com.example.goodbye.GoodbyePlugin'
        }
    }
}

publishing {
    repositories {
        maven {
            url '../../consuming/maven-repo'
        }
        ivy {
            url '../../consuming/ivy-repo'
        }
    }
}

위 예제는 플러그인 ID에서 Maven/Ivy 좌표로의 기본 제공 매핑을 사용하는 대신 지정된 플러그인 구현 아티팩트를 사용하도록 Gradle에 지시합니다.

gradle publish를 샘플 디렉토리에서 실행하면 다음과 같이 Maven repository 레이아웃이 생성됩니다.(Ivy layout도 이와 유사합니다.)

Legacy Plugin Application

플러그인 DSL의 도입으로 사용자는 플러그인을 적용하는 레거시 방법을 사용할 이유가 거의 없습니다.
현재 작동 방식의 제한으로 인해 빌드 작성자가 플러그인 DSL을 사용할 수 없는 경우에 대비하여 문서화되어 있습니다.

Applying Binary Plugins

// build.gradle

apply plugin: 'java'

플러그인은 플러그인 ID를 사용하여 적용할 수 있습니다.
위 예시의 경우 짧은 이름 java를 사용하여 JavaPlugin을 적용하고 있습니다.

플러그인 ID를 사용하든 대신 플러그인의 클래스를 지정하여 플러그인을 적용할 수도 있습니다.

// build.gradle

apply plugin: JavaPlugin

JavaPluginJavaPlugin을 의미합니다.
이 클래스는 org.gradle.api.plugins 패키지가 모든 빌드 스크립트에서 자동으로 가져오기 때문에 엄격하게(strictly) 가져올 필요가 없습니다.(Default imports 참조.)

또한 Java에서와 같이 Groovy에서 클래스 리터럴을 식별하기 위해 .class를 추가할 필요가 없습니다.

Applying plugins with the buildscript block

외부 jar 파일로 공개된 바이너리 플러그인은 빌드 스크립트 클래스 경로에 플러그인을 추가한 다음 플러그인을 적용(apply)하여 프로젝트에 추가할 수 있습니다.
빌드 스크립트에 대한 외부 종속성에 설명된 대로 buildscript {} 블록을 사용하여 외부 jar를 빌드 스크립트 클래스 경로에 추가할 수 있습니다.

// build.gradle

buildscript {
    repositories {
        gradlePluginPortal()
    }
    dependencies {
        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.5'
    }
}

apply plugin: 'com.jfrog.bintray'

Script plugins

// build.gradle

apply from: 'other.gradle'

스크립트 플러그인은 자동으로 귀결(resolved)되며 로컬 파일 시스템이나 원격 위치의 스크립트에서 적용할 수 있습니다.
파일 시스템 위치는 프로젝트 디렉토리에 상대적인 반면(상대 경로) 원격 스크립트 위치는 HTTP URL로 지정됩니다.
여러 스크립트 플러그인(어느 형식이든)을 주어진 대상에 적용할 수 있습니다.

Finding community plugins

Gradle에는 다양한 기능을 위한 플러그인을 제공하는 플러그인 개발자 커뮤니티가 있습니다.
Gradle 플러그인 포털은 커뮤니티 플러그인을 검색하기 위한 인터페이스를 제공합니다.

More on plugins

플러그인의 내부 동작에 대한 자세한 내용은 사용자 정의 플러그인을 참조하십시오.

profile
안녕하세요

0개의 댓글