// Copyright (C) 2024 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.

[[part3_create_custom_task]]
= Part 3: Creating Tasks

Learn about custom task types, create one, and add it to your plugin.

****
**In this section, you'll:**

- Understand what a custom task type is.
- Create a `SlackTask` class that contains the logic for sending a message.
- Add the necessary dependency for the Slack API client.
- Register the custom task in your plugin's `apply` method.
****

[[part3_begin]]
== Step 0: Before you Begin

1. You initialized your plugin in <<part1_gradle_init_plugin.adoc#part1_begin,part 1>>.
2. You added an extension to your plugin in <<part2_add_extension.adoc#part2_begin,part 2>>.

== Step 1: About Custom Tasks

If your plugin introduces new functionality, you’ll typically define a custom task type.
This allows you to encapsulate specific logic, like sending a Slack message, into a reusable and configurable Gradle task.
We'll then register this task in our plugin so users can execute it with a simple command.

== Step 2: Create a Custom Task Type

Let's create the class that will contain our Slack messaging logic.

====
[.multi-language-text.lang-kotlin]
=====
Create a new file called `SlackTask.kt` in `src/main/kotlin/org/example/` and add the following code:
=====
[.multi-language-text.lang-groovy]
=====
Create a new file called `SlackTask.groovy` in `src/main/groovy/org/example/` and add the following code:
=====
====

====
include::sample[dir="snippets/plugins/plugin-tutorial/kotlin",files="plugin/src/main/kotlin/org/example/SlackTask.kt[]"]
include::sample[dir="snippets/plugins/plugin-tutorial/groovy",files="plugin/src/main/groovy/org/example/SlackTask.groovy[]"]
====

This custom task type does a few important things:

* It extends `DefaultTask`, which gives it all the basic functionality of a Gradle task.
* It uses annotations like `@Input` and `@TaskAction` to clearly define its inputs and its primary action.
* The `@TaskAction` method uses the link:https://github.com/slackapi/java-slack-sdk[Slack API client] to post a message.
* It includes robust error handling: if the Slack API call fails, the task will fail the build with a clear error message.

== Step 3: Add the Slack API Dependency

Since our custom task uses the Slack API client, we need to add it as a dependency in our plugin's `build.gradle(.kts)` file.

====
include::sample[dir="snippets/plugins/plugin-tutorial/kotlin",files="plugin/build.gradle.kts[tags=slack-api]"]
include::sample[dir="snippets/plugins/plugin-tutorial/groovy",files="plugin/build.gradle[tags=slack-api]"]
====

== Step 4: Register it in the Plugin

Now that we've defined our custom `SlackTask` class, we need to register it in our plugin's `apply` method.
This makes it available for users to run with a command like `./gradlew sendTestSlackMessage`.

====
[.multi-language-text.lang-kotlin]
=====
Open your plugin implementation file, `SlackPlugin.kt` (in `src/main/kotlin/org/example/`), and modify it to look like this:
=====
[.multi-language-text.lang-groovy]
=====
Open your plugin implementation file, `SlackPlugin.groovy` (in `src/main/groovy/org/example/`), and modify it to look like this:
=====
====

====
include::sample[dir="snippets/plugins/plugin-tutorial/kotlin",files="plugin/src/main/kotlin/org/example/SlackPlugin.kt[tags=slack-task]"]
include::sample[dir="snippets/plugins/plugin-tutorial/groovy",files="plugin/src/main/groovy/org/example/SlackPlugin.groovy[tags=slack-task]"]
====

This code:

* Registers a new task named `sendTestSlackMessage` of our custom `SlackTask` type.
* Configures the task with a group and description for better help output.
* Binds the task's properties (`token`, `channel`, `message`) to the corresponding properties in our plugin's `SlackExtension`. This is how the user's configuration is passed to the task.

[.text-right]
**Next Step:** <<part4_unit_test.adoc#part4_unit_test,Write a Unit Test>> >>
