diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..fb209b4 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/precompiled-binary-plugin-dependency.test.iml b/.idea/modules/precompiled-binary-plugin-dependency.test.iml new file mode 100644 index 0000000..500474b --- /dev/null +++ b/.idea/modules/precompiled-binary-plugin-dependency.test.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/remote-versioned-modular-script-plugin-application.cucumberE2eTest.iml b/.idea/modules/remote-versioned-modular-script-plugin-application.cucumberE2eTest.iml deleted file mode 100644 index 4a4ce55..0000000 --- a/.idea/modules/remote-versioned-modular-script-plugin-application.cucumberE2eTest.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/modules/remote-versioned-modular-script-plugin-application.iml b/.idea/modules/remote-versioned-modular-script-plugin-application.iml deleted file mode 100644 index 4a4ce55..0000000 --- a/.idea/modules/remote-versioned-modular-script-plugin-application.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/modules/remote-versioned-modular-script-plugin-application.main.iml b/.idea/modules/remote-versioned-modular-script-plugin-application.main.iml deleted file mode 100644 index 4a4ce55..0000000 --- a/.idea/modules/remote-versioned-modular-script-plugin-application.main.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/modules/remote-versioned-modular-script-plugin-library.iml b/.idea/modules/remote-versioned-modular-script-plugin-library.iml deleted file mode 100644 index 4a4ce55..0000000 --- a/.idea/modules/remote-versioned-modular-script-plugin-library.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/modules/remote-versioned-modular-script-plugin-library.main.iml b/.idea/modules/remote-versioned-modular-script-plugin-library.main.iml deleted file mode 100644 index 4a4ce55..0000000 --- a/.idea/modules/remote-versioned-modular-script-plugin-library.main.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/modules/simple-script-plugin.iml b/.idea/modules/simple-script-plugin.iml deleted file mode 100644 index 4a4ce55..0000000 --- a/.idea/modules/simple-script-plugin.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/GradleLogo.png b/GradleLogo.png new file mode 100755 index 0000000..8edfb9b Binary files /dev/null and b/GradleLogo.png differ diff --git a/README.md b/README.md index 13ec106..1efda37 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,17 @@ -# Gradle Build Tool Example Projects +# Gradle Plugin Development -This repository contains examples of various Gradle features with the emphasis on Gradle plugins. +This repository contains examples and assignments from Gradle Plugin Development Udemy course. + + All examples are written using Groovy Gradle build scripts and additional code in Java 15. Projects were created with IntelliJ IDEA. -Every project comes bundled with Gradle wrapper version 7.0 or 6.8.3. +Every project comes bundled with Gradle wrapper version 7.0 or higher. Below is the menu for easier navigation between sections. Every section contains multiple examples or assignments with the focus on a particular topic. | Module | Description | External Link | | ------------- |:-------------:| -------------:| -| **[task](task/)** | This directory contains assignments and examples with the focus on Gradle tasks. | Task lecture | -| **[script-plugin](script-plugin/)** | Script plugin is the easiest possible way of extracting tasks and any additional build logic from original build.gradle file. | Script plugin lecture | -| **[precompiled-plugin](precompiled-plugin/)** | Going step further one can extract script plugin into precompiled plugin. | Precompiled plugin lecture | -| **[binary-plugin](binary-plugin/)** | Not the fastest way to create a plugin, but it gives you the most options regarding extraction of the build logic and reusability. | Binary plugin lecture | +| **[task](task/)** | This directory contains assignments and examples with the focus on Gradle tasks. The task is sorting files. Those tasks will be the base for plugin development. | Task lecture | For any changes or additional content check [release notes](https://github.com/rivancic/gradle/releases). diff --git a/precompiled-plugin/README.md b/precompiled-plugin/README.md deleted file mode 100644 index 3747d7e..0000000 --- a/precompiled-plugin/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Gradle Precompiled Plugin - -This directory contains assignments and examples with the focus on precompiled Gradle plugins. - -Script or source code for the plugin has to go into **buildSrc** directory based on the Gradle convention. - -| Module | Description | Resources | -| ------------- |:-------------:|-------------:| -| **[precompiled-script-plugin](precompiled-script-plugin)** | Script plugin transformed into precompiled script plugin. This is supported with **groovy-gradle-plugin** plugin. This way plugin can be reused in multiple subprojects. Gradle components can be extracted into separate classes. | Precompiled script plugin resource | -| **[precompiled-plugin](precompiled-plugin)** | Precompiled script plugin transformed into standard precompiled plugin. Now whole part of script plugin is extracted into standalone components. Code is structured as in a standard Java / Groovy / Kotlin application. | Precompiled plugin resource | - -**Precompiled plugin external resources** - -- [https://docs.gradle.org/current/samples/sample_convention_plugins.html](https://docs.gradle.org/current/samples/sample_convention_plugins.html) -- [https://docs.gradle.org/current/userguide/custom_plugins.html](https://docs.gradle.org/current/userguide/custom_plugins.html) -- [https://docs.gradle.org/current/userguide/organizing_gradle_projects.html#organizing_gradle_projects](https://docs.gradle.org/current/userguide/organizing_gradle_projects.html#organizing_gradle_projects) \ No newline at end of file diff --git a/precompiled-plugin/precompiled-plugin/.gitignore b/precompiled-plugin/precompiled-plugin/.gitignore deleted file mode 100644 index 2677823..0000000 --- a/precompiled-plugin/precompiled-plugin/.gitignore +++ /dev/null @@ -1,152 +0,0 @@ - -# Created by https://www.toptal.com/developers/gitignore/api/java,gradle,intellij -# Edit at https://www.toptal.com/developers/gitignore?templates=java,gradle,intellij - -### Intellij ### -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff -.idea/**/workspace.xml -.idea/**/tasks.xml -.idea/**/usage.statistics.xml -.idea/**/dictionaries -.idea/**/shelf - -# Generated files -.idea/**/contentModel.xml - -# Sensitive or high-churn files -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml -.idea/**/dbnavigator.xml - -# Gradle -.idea/**/gradle.xml -.idea/**/libraries - -# Gradle and Maven with auto-import -# When using Gradle or Maven with auto-import, you should exclude module files, -# since they will be recreated, and may cause churn. Uncomment if using -# auto-import. -# .idea/artifacts -# .idea/compiler.xml -# .idea/jarRepositories.xml -# .idea/modules.xml -# .idea/*.iml -# .idea/modules -# *.iml -# *.ipr - -# CMake -cmake-build-*/ - -# Mongo Explorer plugin -.idea/**/mongoSettings.xml - -# File-based project format -*.iws - -# IntelliJ -out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Cursive Clojure plugin -.idea/replstate.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties - -# Editor-based Rest Client -.idea/httpRequests - -# Android studio 3.1+ serialized cache file -.idea/caches/build_file_checksums.ser - -### Intellij Patch ### -# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 - -# *.iml -# modules.xml -# .idea/misc.xml -# *.ipr - -# Sonarlint plugin -# https://plugins.jetbrains.com/plugin/7973-sonarlint -.idea/**/sonarlint/ - -# SonarQube Plugin -# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin -.idea/**/sonarIssues.xml - -# Markdown Navigator plugin -# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced -.idea/**/markdown-navigator.xml -.idea/**/markdown-navigator-enh.xml -.idea/**/markdown-navigator/ - -# Cache file creation bug -# See https://youtrack.jetbrains.com/issue/JBR-2257 -.idea/$CACHE_FILE$ - -# CodeStream plugin -# https://plugins.jetbrains.com/plugin/12206-codestream -.idea/codestream.xml - -### Java ### -# Compiled class file -*.class - -# Log file -*.log - -# BlueJ files -*.ctxt - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -*.war -*.nar -*.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* - -### Gradle ### -.gradle -build/ - -# Ignore Gradle GUI config -gradle-app.setting - -# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) -!gradle-wrapper.jar - -# Cache of project -.gradletasknamecache - -# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 -# gradle/wrapper/gradle-wrapper.properties - -### Gradle Patch ### -**/build/ - -# End of https://www.toptal.com/developers/gitignore/api/java,gradle,intellij diff --git a/precompiled-plugin/precompiled-plugin/.idea/.gitignore b/precompiled-plugin/precompiled-plugin/.idea/.gitignore deleted file mode 100644 index 73f69e0..0000000 --- a/precompiled-plugin/precompiled-plugin/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml -# Editor-based HTTP Client requests -/httpRequests/ diff --git a/precompiled-plugin/precompiled-plugin/.idea/checkstyle-idea.xml b/precompiled-plugin/precompiled-plugin/.idea/checkstyle-idea.xml deleted file mode 100644 index 3460331..0000000 --- a/precompiled-plugin/precompiled-plugin/.idea/checkstyle-idea.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/precompiled-plugin/precompiled-plugin/.idea/compiler.xml b/precompiled-plugin/precompiled-plugin/.idea/compiler.xml deleted file mode 100644 index 443b5d2..0000000 --- a/precompiled-plugin/precompiled-plugin/.idea/compiler.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/precompiled-plugin/precompiled-plugin/.idea/misc.xml b/precompiled-plugin/precompiled-plugin/.idea/misc.xml deleted file mode 100644 index 6915923..0000000 --- a/precompiled-plugin/precompiled-plugin/.idea/misc.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/precompiled-plugin/precompiled-plugin/.idea/modules/precompiled-script-plugin-structured.buildSrc.main.iml b/precompiled-plugin/precompiled-plugin/.idea/modules/precompiled-script-plugin-structured.buildSrc.main.iml deleted file mode 100644 index 4a4ce55..0000000 --- a/precompiled-plugin/precompiled-plugin/.idea/modules/precompiled-script-plugin-structured.buildSrc.main.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/precompiled-plugin/precompiled-plugin/.idea/modules/precompiled-script-plugin-structured.iml b/precompiled-plugin/precompiled-plugin/.idea/modules/precompiled-script-plugin-structured.iml deleted file mode 100644 index 4a4ce55..0000000 --- a/precompiled-plugin/precompiled-plugin/.idea/modules/precompiled-script-plugin-structured.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/precompiled-plugin/precompiled-plugin/.idea/vcs.xml b/precompiled-plugin/precompiled-plugin/.idea/vcs.xml deleted file mode 100644 index b2bdec2..0000000 --- a/precompiled-plugin/precompiled-plugin/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/precompiled-plugin/precompiled-plugin/README.md b/precompiled-plugin/precompiled-plugin/README.md deleted file mode 100644 index 2c7e6e6..0000000 --- a/precompiled-plugin/precompiled-plugin/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# Precompiled Plugin - -In this module you will be able to see why precompiled plugin really offers you to express your build logic in a -more structured way. With writing components of build logic inside standalone classes you will have more a feeling like you are writing -usual Java application than some exotic scripting with DSL language. You could still try to extract tasks in script plugins -but there is no such support as packaging and importing classes from the classpath. - -You can also easily debug logic inside your custom classes inside buildScr with IntelliJ IDEA support. - -In this project we will builds on top of [previous project](../precompiled-script-plugin) and extract tasks into standalone task classes. Also plugin will not be defined anymore in a groovy script file. -We will create a Groovy class that extends Gradle API Plugin interface. - -Build logic is be written in Groovy language. - -## Code structure - -One of the main benefits of using precompiled plugin instead of script plugins is that you can better [structure build code in buildSrc directory.](https://docs.gradle.org/current/userguide/organizing_gradle_projects.html#sec:build_sources) -You will be able to structure code as in your ordinary JVM code. Code intended to be packaged in the plugin itself should be located under the **main** directory. Inside it packages can be used to structure the code. - -

- Gradle precompiled plugin -

- -Tasks and plugins defined in the buildSrc will be available to all the build scripts inside the main project. - -Develop custom task. -https://docs.gradle.org/current/userguide/custom_tasks.html - -## Components of the build script plugin - -### Project - -Applying module that is compiled in buildSrc and made available for all the projects - -### buildSrc - -buildSrc directory contains source code for the Gradle plugin. Content of this directory is automatically processed by -the Gradle itself. Content of the buildSrc is the same as of any other Java based project. -Source code should reside in src/main/[groovy/java/kotlin]. -Plugin is represented by the class extending the Plugin interface -Content will be compiled and result persisted in internal build folder. - -### Plugin name - -// TODO show how to specify plugin name instead of using full package name of the class implementing the plugin. - -src/main/resources contains META-INF.gradle-plugins/{pluginName}.properties file that specifies short version of the plugin name. - \ No newline at end of file diff --git a/precompiled-plugin/precompiled-plugin/build.gradle b/precompiled-plugin/precompiled-plugin/build.gradle deleted file mode 100644 index 45f0165..0000000 --- a/precompiled-plugin/precompiled-plugin/build.gradle +++ /dev/null @@ -1,24 +0,0 @@ -/** - * TODO check if this description is included in precompiled-script-plugin - * TODO Fix this description - * - * Name of the precompiled script plugin for which the source code resides in the buildSrc is defined by the - * file name of the script itself. In case that the filename is precompiled-script-plugin-backup.gradle Then the - * plugin id will be filename without the extension (.gradle). - * - * - */ -plugins { - id "filesPlugin" -} - -// equals - -//apply plugin: "filesPlugin" - -// equals - -//apply plugin: com.rivancic.gradle.precompiled.FilesPlugin diff --git a/precompiled-plugin/precompiled-plugin/buildSrc/src/main/groovy/com/rivancic/gradle/precompiled/FilesPlugin.groovy b/precompiled-plugin/precompiled-plugin/buildSrc/src/main/groovy/com/rivancic/gradle/precompiled/FilesPlugin.groovy deleted file mode 100644 index 309a02e..0000000 --- a/precompiled-plugin/precompiled-plugin/buildSrc/src/main/groovy/com/rivancic/gradle/precompiled/FilesPlugin.groovy +++ /dev/null @@ -1,32 +0,0 @@ -package com.rivancic.gradle.precompiled - -import com.rivancic.gradle.precompiled.tasks.CleanTask -import com.rivancic.gradle.precompiled.tasks.SortFilesTask -import org.gradle.api.Plugin -import org.gradle.api.Project - -/** - * This build script contains two tasks. Main functionality is sorting files by their extension. - * - * Tasks are grouped into "files" group. - * - * Root folder containing files that have to be sorted is parametrized through Gradle properties with the key [tasks.files.folder]. - * Property has to be accessed through the project.ext map as direct reference doesn't work if property key is named with the dot notation. - * - * Second task clears build folder. - */ -class FilesPlugin implements Plugin { - - @Override - void apply(Project project) { - - project.tasks.register('sortFiles', SortFilesTask.class, { - inputDir = project.file(project.properties.get("tasks.files.folder")) - outputDir = project.layout.buildDirectory.dir('files').get().asFile - }) - - project.tasks.register('clean', CleanTask.class, { - inputDir = project.layout.buildDirectory.asFile.get().exists() ? project.layout.buildDirectory : null - }) - } -} diff --git a/precompiled-plugin/precompiled-plugin/buildSrc/src/main/groovy/com/rivancic/gradle/precompiled/tasks/CleanTask.groovy b/precompiled-plugin/precompiled-plugin/buildSrc/src/main/groovy/com/rivancic/gradle/precompiled/tasks/CleanTask.groovy deleted file mode 100644 index 770a00b..0000000 --- a/precompiled-plugin/precompiled-plugin/buildSrc/src/main/groovy/com/rivancic/gradle/precompiled/tasks/CleanTask.groovy +++ /dev/null @@ -1,49 +0,0 @@ -package com.rivancic.gradle.precompiled.tasks - -import org.gradle.api.DefaultTask -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.tasks.CacheableTask -import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.PathSensitive -import org.gradle.api.tasks.PathSensitivity -import org.gradle.api.tasks.TaskAction -import org.gradle.api.tasks.Optional - -import java.nio.file.Files -import java.nio.file.Path - -/** - * - */ -@CacheableTask -abstract class CleanTask extends DefaultTask { - - @PathSensitive(PathSensitivity.RELATIVE) - @InputDirectory - @Optional - abstract DirectoryProperty getInputDir() - - CleanTask() { - group = "files" - description = "Deletes build folder" - } - - @TaskAction - def sort() { - logger.info "==== Clean build ====" - logger.info "" - - def filestodel = inputDir.getOrNull(); - if (filestodel != null) { - try (def stream = Files.walk(filestodel.asFile.toPath())) { - stream.sorted(Comparator.reverseOrder()) - .map(Path::toFile) - .peek(file -> logger.info("File to del ${file.toString()}")) - .map(File::delete).count() - } - } - - logger.info "" - logger.info "=======================" - } -} \ No newline at end of file diff --git a/precompiled-plugin/precompiled-plugin/buildSrc/src/main/groovy/com/rivancic/gradle/precompiled/tasks/FilesTask.groovy b/precompiled-plugin/precompiled-plugin/buildSrc/src/main/groovy/com/rivancic/gradle/precompiled/tasks/FilesTask.groovy deleted file mode 100644 index a07c231..0000000 --- a/precompiled-plugin/precompiled-plugin/buildSrc/src/main/groovy/com/rivancic/gradle/precompiled/tasks/FilesTask.groovy +++ /dev/null @@ -1,40 +0,0 @@ -package com.rivancic.gradle.precompiled.tasks - -import org.gradle.api.DefaultTask -import org.gradle.api.tasks.CacheableTask -import org.gradle.api.tasks.InputDirectory -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.tasks.OutputDirectory -import org.gradle.api.tasks.PathSensitive -import org.gradle.api.tasks.PathSensitivity - -/** - * TODO show all the obstacles to make a task cachable - * - * Annotate with CacheableTask - * - * @InputDirectory -> has to have normalization strategy https://docs.gradle.org/7.0/userguide/validation_problems.html#missing_normalization_annotation - */ -@CacheableTask -abstract class FilesTask extends DefaultTask { - @PathSensitive(PathSensitivity.RELATIVE) - @InputDirectory - abstract DirectoryProperty getInputDir() - - @OutputDirectory - abstract DirectoryProperty getOutputDir() - - FilesTask() { - group = "files" - } - - /** - * Get file extension from its file name - * - * @param filename from which extension will be extracted - * @return extension of the file - */ - static String getExtensionOf(String filename) { - return filename.substring(filename.lastIndexOf(".") + 1) - } -} \ No newline at end of file diff --git a/precompiled-plugin/precompiled-plugin/buildSrc/src/main/groovy/com/rivancic/gradle/precompiled/tasks/SortFilesTask.groovy b/precompiled-plugin/precompiled-plugin/buildSrc/src/main/groovy/com/rivancic/gradle/precompiled/tasks/SortFilesTask.groovy deleted file mode 100644 index 901e19e..0000000 --- a/precompiled-plugin/precompiled-plugin/buildSrc/src/main/groovy/com/rivancic/gradle/precompiled/tasks/SortFilesTask.groovy +++ /dev/null @@ -1,60 +0,0 @@ -package com.rivancic.gradle.precompiled.tasks - -import org.gradle.api.tasks.CacheableTask -import org.gradle.api.tasks.TaskAction - -import java.nio.file.Files -import java.nio.file.StandardCopyOption - -/** - * This method sorts files inside specific directory. - * - *