// Copyright (C) 2023 Gradle, Inc.
//
// Licensed under the Creative Commons Attribution-Noncommercial-ShareAlike 4.0 International License.;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://creativecommons.org/licenses/by-nc-sa/4.0/
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

[[plugin_basics]]
= Plugin Basics

Gradle is built on a plugin system.
Gradle itself is primarily composed of infrastructure, such as a sophisticated dependency resolution engine.
The rest of its functionality comes from plugins.

A plugin is a piece of software that *provides additional functionality to the Gradle build system*.

image::gradle-basic-6.png[]

Plugins can be applied to a Gradle build script to *add new tasks, configurations, or other build-related capabilities*:

The Java Library Plugin - `java-library` :: Used to define and build Java libraries. It compiles Java source code with the `compileJava` task, generates Javadoc with the `javadoc` task, and packages the compiled classes into a JAR file with the `jar` task.
The Google Services Gradle Plugin - `com.google.gms:google-services` :: Enables Google APIs and Firebase services in your Android application with a configuration block called `googleServices{}` and a task called `generateReleaseAssets`.
The Gradle Bintray Plugin - `com.jfrog.bintray` :: Allows you to publish artifacts to Bintray by configuring the plugin using the `bintray{}` block.

== Plugin distribution

Plugins are distributed in three ways:

1. **Core plugins** - Gradle develops and maintains a set of <<plugin_reference#plugin_reference,Core Plugins>>.
2. **Community plugins** - Gradle's community shares plugins via the https://plugins.gradle.org[Gradle Plugin Portal].
3. **Local plugins** - Gradle enables users to create custom plugins using link:{javadocPath}/org/gradle/api/Plugin.html[APIs].

== Applying plugins

*Applying* a plugin to a project allows the plugin to extend the project's capabilities.

You apply plugins in the build script using a *plugin id* (a globally unique identifier / name) and a version:

[source,text]
----
plugins {
    id «plugin id» version «plugin version»
}
----

== 1. Core plugins

Gradle Core plugins are a set of plugins that are included in the Gradle distribution itself.
These plugins provide essential functionality for building and managing projects.

Some examples of core plugins include:

- *java*: Provides support for building Java projects.
- *groovy*: Adds support for compiling and testing Groovy source files.
- *ear*: Adds support for building EAR files for enterprise applications.

Core plugins are unique in that they provide short names, such as `java` for the core link:{javadocPath}/org/gradle/api/plugins/JavaPlugin.html[JavaPlugin], when applied in build scripts.
They also do not require versions.
To apply the `java` plugin to a project:

.build.gradle.kts
[source,kotlin]
----
plugins {
    id("java")
}
----

There are many <<plugin_reference#plugin_reference,Gradle Core Plugins>> users can take advantage of.

== 2. Community plugins

Community plugins are plugins developed by the Gradle community, rather than being part of the core Gradle distribution.
These plugins provide additional functionality that may be specific to certain use cases or technologies.

The link:https://plugins.gradle.org/plugin/org.springframework.boot[Spring Boot Gradle plugin] packages executable JAR or WAR archives, and runs link:https://spring.io/[Spring Boot] Java applications.

To apply the `org.springframework.boot` plugin to a project:

.build.gradle.kts
[source,kotlin]
----
plugins {
    id("org.springframework.boot") version "3.1.5"
}
----

Community plugins can be published at the link:http://plugins.gradle.org/[Gradle Plugin Portal], where other Gradle users can easily discover and use them.

== 3. Local plugins

Custom or local plugins are developed and used within a specific project or organization.
These plugins are not shared publicly and are tailored to the specific needs of the project or organization.

Local plugins can encapsulate common build logic, provide integrations with internal systems or tools, or abstract complex functionality into reusable components.

Gradle provides users with the ability to develop custom plugins using APIs.
To create your own plugin, you'll typically follow these steps:

1. *Define the plugin class:* create a new class that implements the `Plugin<Project>` interface.
+
[source,kotlin]
----
// Define a 'HelloPlugin' plugin
class HelloPlugin : Plugin<Project> {
    override fun apply(project: Project) {
        // Define the 'hello' task
        val helloTask = project.tasks.register("hello") {
            doLast {
                println("Hello, Gradle!")
            }
        }
    }
}
----

2. *Build and optionally publish your plugin:* generate a JAR file containing your plugin code and optionally publish this JAR to a repository (local or remote) to be used in other projects.
+
[source,kotlin]
----
// Publish the plugin
plugins {
    `maven-publish`
}

publishing {
    publications {
        create<MavenPublication>("mavenJava") {
            from(components["java"])
        }
    }
    repositories {
        mavenLocal()
    }
}
----
3. *Apply your plugin:* when you want to use the plugin, include the plugin ID and version in the `plugins{}` block of the build file.
+
[source,kotlin]
----
// Apply the plugin
plugins {
    id("com.example.hello") version "1.0"
}
----

Consult the <<custom_plugins.adoc#custom_plugins,Plugin development chapter>> to learn more.

[.text-right]
**Next Step:** <<gradle_optimizations.adoc#gradle_optimizations,Learn about Incremental Builds and Build Caching>> >>
