This project offers a Common Set of Gradle's Tasks for Backend's and Frontend's Development.
This project is licensed under the terms of the MIT license.
Have a "same" set of Gradle's Tasks for Backend's development and Frontend's development, i.e. same tasks names and "same" tasks functionality, in order to reduce difference between projects and this way facilitated the work of Backend's developers and Frontend's developer, who will be able to move between projects easily.
- Convention over Configuration for Backend and Frontend projects:
- Adds some tasks based on present tasks.
- Automatically complements some existing tasks.
- Adds relationships when some tasks are present.
- Adds tasks description if not present or empty.
- Logs result's location for some tasks.
Code Assessment group: contains code assessment tasks:
assess
task: for assessing the code (Main and Test).- It will be automatically created if it does not exist, and
assessMain
,assessTest
orassessLocal
are present. - It will depend on:
assessMain
, if present.assessTest
, if present.assessLocal
, if present.
- It will be automatically created if it does not exist, and
assessMain
task: for assessing Main code.- It will be automatically created if it does not exist and
codenarcMain
,checkstyleMain
,pmdMain
orassessCss
are present. - It will depend on:
codenarcMain
, if present.checkstyleMain
, if present.pmdMain
, if present.assessCss
, if present.
- It will be automatically created if it does not exist and
assessTest
task: for assessing Test code (Unit and Integration).- It will be automatically created if it does not exist, and
assessUnitTest
,assessIntegrationTest
,codenarcTest
,checkstyleTest
orpmdTest
are present. - It will depend on:
assessUnitTest
, if present.assessIntegrationTest
, if present.codenarcTest
, if present, andassessUnitTest
orassessIntegrationTest
are not defined.checkstyleTest
, if present, andassessUnitTest
orassessIntegrationTest
are not defined.pmdTest
, if present, andassessUnitTest
orassessIntegrationTest
are not defined.
- It will run after:
assessMain
, if present.
- It will be automatically created if it does not exist, and
assessUnitTest
task: for assessing Unit Test code.- It will run after:
assessMain
, if present.
- It will run after:
assessIntegrationTest
task: for assessing Integration Test code.- It will run after:
assessMain
, if present.assessUnitTest
, if present.
- It will run after:
Code Testing group: contains code testing tasks:
test
task: for running tests.- It will be automatically created if it does not exist, and
unitTest
orintegrationTest
are present. - It will depend on:
unitTest
, if present.integrationTest
, if present.
- It will run after:
assessTest
, if present.
- It will be automatically created if it does not exist, and
unitTest
task: for running unit test.- It will run after:
assessUnitTest
, if present.assess
, if present, andassessUnitTest
is not present.
- It will run after:
integrationTest
task: for running integration test.- It will run after:
assessIntegrationTest
, if present.assess
, if present, andassessIntegrationTest
is not present.
- It will run after:
Code Verification group: contains code verification tasks:
coverage
task: for calculating and analyzing code coverage.- It will be automatically created if it does not exist, and
test
,jacocoTestReport
orjacocoTestCoverageVerification
are present. - It will depend on:
unitTest
, if present.test
, ifunitTest
is not present.
- It will be automatically created if it does not exist, and
check
task: for running all checks: assessments and tests.- It will be created if it does not exist and
assess
,test
,coverage
orintegration
are present. - It will depend on:
coverage
, if present.integrationTest
, if present, andcoverage
present.test
, ifcoverage
is not present.
- It will be created if it does not exist and
Build group: contains binaries building tasks:
assemble
task: for assembling binaries.- It will run after:
check
, if present.
- It will run after:
build
task: the master task that will do all the checks and assemble binaries.- It will be created if it does not exist and
assemble
is present. - It will depend on:
assemble
, if present.check
, if present.
- It will be created if it does not exist and
Code Documentation group: contains documentation building tasks:
doc
task: for assembling code documentation.- It will be automatically created if it does not exist, and
javadoc
orgroovydoc
are present. - It will run after:
assessMain
, if present.assess
, if present, andassessMain
not present.
- It will be automatically created if it does not exist, and
The following shows all the Tasks relationships:
- Some relationships are conditional based on existence of other tasks (are show in blue).
Different variations can be generated depending on what is defined, e.g.:
- Project with unit tasks and integration tasks:
- Project with unit tasks, integration tasks and coverage:
- Project with unit tests and integration tests:
- Project without unit tests and without integration tests:
- Project with external tools:
- Minimal project with build:
- Minimal project:
These values are defined in CodeCommonTasksExtension
, and although the idea is to use convention, these values are available anc can be configurable though the codeCommonTasks
extension added when this plugin is applied:
- Groups names.
- Task names.
- External tool to search for.
codeCommonTasks.groupForAssessTasks = 'Code Assessment'
codeCommonTasks.assessTask = 'assess'
codeCommonTasks.assessMainTask = 'assessMain'
codeCommonTasks.assessTestTask = 'assessTest'
codeCommonTasks.assessUnitTestTask = 'assessUnitTest'
codeCommonTasks.assessIntegrationTestTask = 'assessIntegrationTest'
codeCommonTasks.tasksForAssess = ['assessMain', 'assessTest', 'assessLocal']
codeCommonTasks.tasksForMainAssess = ['codenarcMain', 'checkstyleMain', 'pmdMain', 'assessCss']
codeCommonTasks.tasksForTestAssess = ['codenarcTest', 'checkstyleTest', 'pmdTest']
codeCommonTasks.tasksForCoverage = ['jacocoTestReport', 'jacocoTestCoverageVerification']
codeCommonTasks.tasksForDocumentation = ['javadoc', 'groovydoc']
codeCommonTasks.groupForTestTasks = 'Code Testing'
codeCommonTasks.testTask = 'test'
codeCommonTasks.unitTestTask = 'unitTest'
codeCommonTasks.integrationTestTask = 'integrationTest'
codeCommonTasks.groupForVerificationTasks = 'Code Verification'
codeCommonTasks.checkTask = 'check'
codeCommonTasks.coverageTask = 'coverage'
codeCommonTasks.groupForBuildTasks = 'Build'
codeCommonTasks.assembleTask = 'assemble'
codeCommonTasks.buildTask = 'build'
codeCommonTasks.groupForDocumentationTasks = 'Code Documentation'
codeCommonTasks.documentationTask = 'doc'
- None
- Apply the plugin:
plugins {
id 'all.shared.gradle.code-common-tasks' version '1.0.0'
}
Due to delays in the approval on Gradle Plugin Repository[1], is possible that the plugin is not available from there, consequently, add following to settings.gradle
:
pluginManagement {
repositories {
gradlePluginPortal()
maven {
url 'https://dl.bintray.com/gmullerb/all.shared.gradle'
}
}
}
[1] Waited around 5 days for publish's approval of the plugin without answer (new policies and more delays).
[1] Due to new Gradle Plugin Repository policies, delays of several days, without answer, for approval of the plugin publication can happen. For an actual use example, see basecode - settings.gradle.
This will work for Backend development, since Frontend will require some customization.
2 . Apply language plugins:
Groovy:
plugins {
id 'groovy'
}
Java:
plugins {
id 'java'
}
2 . Apply code styling plugins:
Groovy:
plugins {
id 'codenarc'
}
Java:
plugins {
id 'checkstyle'
}
and/or
plugins {
id 'pmd'
}
3 . Define source folder structure:
Groovy:
/src
/main
/groovy
/test
/groovy
Java:
/src
/main
/java
/test
/java
4 . Add code.
5 . Run gradlew build
With Coverage
6 . Apply JaCoCo plugins:
plugins {
id 'jacoco'
}
7 . Configure jacoco plugin and/or tasks.
To see all the tasks added to the project:
gradlew tasks
.
For an actual use example, see this project.
1 . Define some of the tasks with the required values, e.g.:
task assessUnitTest {
dependsOn checkstyleUnitTest, pmdUnitTesTask
}
2 . The plugin will automatically complement tasks that has the "predefined" names.
- If the task description is empty then a description is added.
3 . If the predefined name is not adequate the use codeCommonTasks
extension to change the "predefined name", e.g.:
codeCommonTasks.assessUnitTestTask = 'assessUnitTestNewName'
4 . If the task has a name which is not "predefined", then use complement methods from codeCommonTasks
extension, e.g.:
task someAssessUnitTest {
dependsOn checkstyleUnitTest, pmdUnitTesTask
}
codeCommonTasks.complementAssessUnitTestTask(someAssessUnitTest)
Following complement methods are available:
void complementAssessTask(Task task)
void complementAssessMainTask(Task task)
void complementAssessTestTask(Task task)
void complementAssessUnitTestTask(Task task)
void complementAssessIntegrationTestTask(Task task)
void complementTestTask(Task task)
void complementUnitTestTask(Task task)
void complementIntegrationTestTask(Task task)
void complementCoverageTask(Task task)
void complementCheckTask(Task task)
void complementAssembleTask(Task task)
void complementBuildTask(Task task)
void complementDocumentationTask(Task task)
For an actual use example, see , basecode - back project, basecode - front project and basecode - e2e project.
For Test report location in unitTest
, integrationTest
or test
tasks, define reportAt
, e.g.:
- if the Task is an instance of AbstractTestTask the value is automatically "set".
reportAt
overrides this values.
task unitTest(type: Test) {
ext.reportAt = ..
}
For Coverage report location in unitTest
or test
tasks, define coverageReportAt
, e.g.:
- For some external tools defined in
codeCommonTasks.tasksForCoverage
these values are automatically "set":- jacocoTestReport.
coverageReportAt
overrides this values.
task unitTest(type: Test) {
ext.coverageReportAt = ..
}
For Documentation in doc
tasks, define documentationAt
and documentationType
, e.g.:
- For some external tools defined in
codeCommonTasks.tasksForDocumentation
these values are automatically "set":- javadoc.
- groovydoc.
documentationAt
overrides this values.
task doc() {
ext.documentationType = 'jsDoc'
ext.documentationAt = "$buildDir/docs"
}
Clone or download the project[1], in the desired folder execute:
git clone https://github.com/gmullerb/gradlegpluginbasecode
- No need, only download and run (It's Gradle! Yes!).
/src
/main
/groovy
/test
/groovy
src/main/groovy
: Source code files.- CodeCommonTasksExtension extension of the plugin.
- CodeCommonTasksCreateTasksAction where tasks are created.
- CodeCommonTasksComplementAction where tasks are complemented.
src/test/groovy
: Test code files[1].
-
To build it:
gradlew build
.gradlew
: this will run default tasksgradlew assessCommon
: will check common style of files.gradlew assessGradle
: will check code style of Gradle's.gradlew build
.
-
To assess code:
gradlew assess
. -
To test code:
gradlew test
- This will run jacoco code coverage [1].
-
To publish plugin:
./gradlew -PPLUGIN_ID=all.shared.gradle.pluginName publishPlugins
-PPLUGIN_ID
indicates the plugin id.
-
To get all the tasks for the project:
gradlew tasks --all
[1] May not get 100% since Groovy adds some extra code, that may not be tested.
All all.shared.gradle
plugins define:
- PluginNamePlugin: which contains the class implements
Plugin
interface. - PluginNameExtension: which represent the extension of the plugin.
- If Tasks are define, then their names will be TaskNameTask.
- If Actions are define, then their names will be ActionNameAction.
All all.shared.gradle
plugins have two static
members:
-
String EXTENSION_NAME
: This will have the name of the extension that the plugin add.- if the plugin does not add an extension the this field will not exist.
-
boolean complement(final Project project)
: will apply the plugin and return true if successful, false otherwise.- this methods is exactly equivalent to the instance
apply
method, but without instantiate the class if not required.
- this methods is exactly equivalent to the instance
Both may be useful when applying the plugin when creating custom plugins.
All all.shared.gradle
plugins "silently" fail when the extension can not be added.
CHANGELOG.md
: add information of notable changes for each version here, chronologically ordered [1].
[1] Keep a Changelog
- Use code style verification tools => Encourages Best Practices, Efficiency, Readability and Learnability.
- Start testing early => Encourages Reliability and Maintainability.
- Code Review everything => Encourages Functional suitability, Performance Efficiency and Teamwork.
Don't forget:
- Love what you do.
- Learn everyday.
- Learn yourself.
- Share your knowledge.
- Learn from the past, dream on the future, live and enjoy the present to the max!.
At life:
- Let's act, not complain.
- Be flexible.
At work:
- Let's give solutions, not questions.