This article will be a series. (unfinished) I'm thinking about the following configuration.
・ Problem raising-(Posted) I will explain the background and theme of this article, and the completed drawing. ・ Gradle environment construction-This article Describes version control by gradle and integration of java / js build environment.
・ IDE environment construction- (not posted) Explains the environment construction procedure when developers perform programming, unit tests, and manual debugging.
Please refer to Previous article for the purpose of the content. In this article, for example, the project will delve into the standardization team (or) procedure. However, gradle is too deep to explain, so for the time being, I would like to make it so that the whole feeling can be read.
The elements under workspace explained this time are like this.
Draft file structure for workspace(Assuming windows environment)
/workspace : gradle, eclipse,VS Code common workspace
/gradle :gradle home
/wrapper :Storage location of gradle wrapper
/tasks :When creating your own task
/xxTask.gradle
/buildSrc :When making your own plug-in
/src :
/main :
/groovy :
/xxPlugin.groovy
/build.gradle :Build definitions that can be applied across projects
/gradle.properties:If you need properties
/settings.gradle:Enumerate project folders
/gradlew.bat :Parent gradle-wrapper
First is the command interface design. We will proceed with the work aiming at the state where the display is displayed when the user performs gradlew tasks.
workspace
C:\develop\workspace>gradlew tasks
> Task :tasks
------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------
Help tasks
----------
dependencies - Displays all dependencies declared in root project 'workspace'.
help - Displays a help message.
projects - Displays the sub-projects of root project 'workspace'.
properties - Displays the properties of root project 'workspace'.
tasks - Displays the tasks runnable from root project 'workspace' (some of the displayed tasks may belong to subprojects).
Version control tasks
------------
pull -Update your workspace with the contents of the remote repository
push -Reflect changes in the workspace to the remote repository
Build tasks
---------
clean -Clear the workspace and build files for each project
assemble -Build a library or application for each project
test -Test the library or application for each project
apidoc -Output API specifications of each project
package -Place the library of each project so that it can be referenced by other projects.
Workspace setting tasks
---------------
init -Initialize the workspace
clone -Duplicate the local repository from the remote repository
Is it important to make version control commands available from gradle and to keep build commands common in java / js projects? Of course, it is the same even if other languages come in. This ensures that the commands you type are always the same, whether version control is SVN or Git, the language is java, js, or any other language.
workspace/projectX
C:\develop\workspace\projectX>gradlew tasks
> Task :projectX:tasks
------------------------------------------------------------
All tasks runnable from project :projectX
------------------------------------------------------------
Help tasks
----------
dependencies - Displays all dependencies declared in project ':projectX'.
help - Displays a help message.
projects - Displays the sub-projects of project ':projectX'.
properties - Displays the properties of project ':projectX'.
tasks - Displays the tasks runnable from project ':projectX'.
Build tasks
---------
clean -Clear the build file in the project
assemble -Build a library or application in your project
test -Test the library or application in your project
apidoc -Output the API specifications of the project
package -Arrange the libraries in the project so that they can be referenced by other projects.
This is an example, but the commands in the project that developers will use frequently have some functional restrictions. In this example, I tried to use only build commands.
Now let's dig into how to create a menu like the one above. By the way, as mentioned above, it is a TIPS-like description to focus on the main points. Please note that there is no corner for the entire source code.
I think you can make an image of Oita with just this
workspace/settings.gradle
// project1:java project
// project2;js project
include 'project1', 'project2'
workspace/gradle.properties
project1.type=java
project2.type=js
workspace/build.gradle
// rootproject(workspace)All projects including
configure(allprojects) {
println "Settings common to all projects> $project"
...
}
// rootproject
configure(rootproject) {
println "workspace settings> $project"
...
}
// rootproject(workspace)All projects not including
configure(subprojects) {
println "Settings common to projects other than root> $project"
...
}
//java project
configure(subprojects.findAll{ projectType(it) == 'java'}) {
println "Java project common settings> $project"
...
}
//js project
configure(subprojects.findAll{ projectType(it) == 'js'}) {
println "Common settings for js projects> $project"
...
}
//Function to get the project type
// gradle.Get the contents defined in properties
String projectType(Project p) {
def t
try { t = getProperty("${p.name}.type") } catch (e) {}
return t ?: 'others'
}
If you execute the task with the above settings, you will get the following output.
workspace
C:\develop\workspace>gradlew projects
> Configure project :
Settings common to all projects> root project 'workspace'
Settings common to all projects> project ':project1'
Settings common to all projects> project ':project2'
root project settings> root project 'workspace'
Java project common settings> project ':project1'
Settings common to javascript projects> project ':project2'
> Task :projects
------------------------------------------------------------
Root project
------------------------------------------------------------
Root project 'workspace'
+--- Project ':project1'
\--- Project ':project2'
Now you can apply the task settings in any scope you like.
An interface that is too versatile for inexperienced users can be a hindrance to understanding. Let's refresh by disabling.
workspace/build.gradle
configure(allprojects) {
println "Settings common to all projects> $project"
task('buildEnvironment').enabled = false
task('components').enabled = false
task('dependencyInsight').enabled = false
task('dependentComponents').enabled = false
task('model').enabled = false
task('properties').enabled = false
task('wrapper').enabled = false
task('init').enabled = false
}
Try hitting tasks with the above settings.
workspace
C:\develop\workspace>gradlew tasks
> Configure project :
Settings common to all projects> root project 'workspace'
> Task :tasks
------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------
Help tasks
----------
dependencies - Displays all dependencies declared in root project 'workspace'.
help - Displays a help message.
projects - Displays the sub-projects of root project 'workspace'.
tasks - Displays the tasks runnable from root project 'workspace' (some of the displayed tasks may belong to subprojects).
It was refreshing. I can't do anything with this, though.
I don't really want to use the existing init task in this model. I don't want to fix the initial assets and I want to support multiple languages. So I will overwrite it.
workspace/build.gradle
configure(rootproject) {
println "root project settings> $project"
//Init task overwrite
apply from: 'gradle/InitTask.gradle'
}
configure(subprojects) {
println "Settings common to projects other than root> $project"
//Init task suppression
task('init').enabled = false
}
workspace/gradle/InitTask.gradle
//Save the original task
def __originInitTask__ = init
//--------------------------------------
//Project initialization task definition
//(Overwrite existing task init)
//--------------------------------------
task init(overwrite: true).doLast {
println ':init '
//Some setting process
//For example, delete all folders and files under workspace here.
//By the way, build while processing the task.It seems to work fine even if gradle is removed.
...
//Initialization main processing
//For example, zip the minimum workspace configuration and
//It is recommended to download and expand it.
//It's easy to operate and implement.
//Download zip
ant.get(
src: 'http://xxx.xxx.xxx/templete.zip',
dest: "${rootDir}/build/tmp/downloads/templete.zip")
//Copy from zip to workspace
copy {
from zipTree "${rootDir}/build/tmp/downloads/templete.zip"
into "${rootDir}"
}
}
//Inherit necessary attributes
//init.description = __originInitTask__.description
//init.group = __originInitTask__.group
//init.dependsOn = __originInitTask__.dependsOn
//Attribute overwrite
init.description = 'Initialize the workspace'
init.group = 'Workspace settings'
You now have an init task for remote maintenance. It can be expected to be effective as a preparatory task for connecting to a version control system, or as a restore command when the environment is unexpectedly corrupted. Of course, let's overwrite tasks other than init if necessary. By the way,
workspace
gradlew init --type java-library --test-framework spock
Regarding java, it may be okay to create a spock environment in advance and put it in the version control system. Is js handmade?
I want to create a clone task that works with a version control system to build a set of project folders. With git installation and windows OS premise, it seems like this.
workspace/gradle.properties
project1.type=java
project2.type=js
remoteRepos=https://github.com/XXXX/xxx.git
workspace/build.gradle
//root project
configure(rootProject) {
//init task
apply from: 'gradle/InitTask.gradle'
//clone task
apply from: 'gradle/CloneTask.gradle'
}
workspace/gradle/CloneTask.gradle
task clone(group:'Workspace settings', description:'Duplicate the local repository from the remote repository', type:Exec) {
commandLine 'cmd', '/c', 'git', 'clone', getProperty('remoteRepos')
}
If you don't want users to install git manually, you should consider gradle's git integration plugin.
In some cases, you may want to group them together as a plugin rather than defining them individually. In this model, I want to put together the tasks for building as a plugin.
workspace/build.gradle
//java project
configure(subprojects.findAll{ projectType(it) == 'java'}) {
apply plugin: JavaBuildPlugin
}
workspace/buildSrc/src/main/groovy/JavaBuildPlugin.groovy
import org.gradle.api.Plugin
import org.gradle.api.Project
class JavaBuildPlugin implements Plugin<Project> {
void apply(Project project) {
//Definition of unique task
project.task(group:'Build', description:'プロジェクト内のBuild用ファイルをクリアします', 'clean') {
doLast { ... }
}
project.task(group:'Build', description:'プロジェクト内のBuild用ファイルをクリアします','assemble') {
doLast { ... }
}
project.task(group:'Build', description:'Test the library or application in your project','test') {
doLast { ... }
}
project.task(group:'Build', description:'Output the API specifications of the project','apidoc') {
doLast { ... }
}
project.task(group:'Build', description:'Arrange the libraries in the project so that they can be referenced by other projects.','package') {
doLast { ... }
}
//Default task definition
project.defaultTasks = ['clean', 'assemble', 'test', 'apidoc', 'package']
//Definition of extensions
project.extensions.create("option", OptionalExtension)
}
}
class OptionalExtension {
String opt1
String opt2
}
//How to use extension:
//If you define the following on the build script side, you can receive and process it on the plug-in side.
// option {
// opt1 'Option setting 1'
// opt2 'Option setting 2'
// }
This example is the java version, but if you implement the js version and other language version in the same way, users will be able to handle commands in the same way without writing build.gradle for each project.
Once you have a plugin that is fairly complete, you may want to open it to the public. In that case, don't forget to set the package declaration and plugin-id.
If you reproduce the procedure so far, you should have completed a task list like the "target point" above. I think we have created a relatively standard development environment that is suitable for a hybrid environment in which multiple languages are mixed in one application.
What did you think. Even if I intended to squeeze it, it became quite long. .. .. I think there are some things that are difficult to understand, and conversely, there are places where you should write here, so please comment if you notice.
Next time, I'd like to delve into the procedure for doing program debug tests using the IDE.