Creating a custom task
In this tutorial, you create and add a custom task to a lifecycle to parse a new --encoding CLI option. This will be used to set the output log file encoding for the Finish task at runtime.
Prerequisites
- Ensure DBB is installed and configured by following the Host Configuration Guide.
- Follow the steps in the zBuilder Getting Started section.
- If you are working from a z/OS UNIX System Services command-line session, ensure your environment is configured for use with Git command line tools. Executing
$DBB_CONF/gitenv.shwill configure your environment for Git provided through IBM Open Enterprise Foundation for z/OS® by default. - Ensure you have a working zBuilder configuration directory setup. If you do not, follow the steps in the Building the Mortgage Application sample tutorial to set one up.
Estimated time
This tutorial takes about 25 minutes to complete.
Steps
1. Create a Groovy task
Create a file called CLILogEncoding.groovy in your $DBB_BUILD/groovy folder with the following IBM-1047 encoded content:
// This causes the script to extend TaskScript, which injects an SLF4j logger into the class as the variable 'log'.
// Groovy scripts are required to extend AbstractLoader at a minimum
@groovy.transform.BaseScript com.ibm.dbb.groovy.TaskScript baseScript
// This package statement isn't necessary, but may be useful for organization when making use of the logger, otherwise
// you may reference this class's logger by its script name in your 'simplelogger.properties' file.
// package <my.package.qualfier>
import com.ibm.dbb.task.TaskConstants
// An instance of org.apache.commons.cli.CommandLine placed into the context by the zBuilder
def cli = context.getCommandLine(TaskConstants.COMMAND_LINE)
if (cli.hasOption("encoding")) {
String encoding = cli.getOptionValue("encoding")
log.debug("Pulled '{}' from the '--encoding' cli option.", encoding)
context.setVariable("CLI_LOG_ENCODING", encoding)
}
// The zBuilder expects an integer return code as the returned value which can be used in subsequent conditions
return 0
This script checks the command line object provided by the zBuilder for an --encoding option with a value associated with it. It then places the value into the CLI_LOG_ENCODING context variable to be used by the Finish task. The only requirement for Groovy scripts is that they extend the com.ibm.dbb.groovy.AbstractLoader class, which this script does with this line at the top:
@groovy.transform.BaseScript com.ibm.dbb.groovy.TaskScript baseScript
The log member is made accessible by extending TaskScript, and the zBuilder makes the BuildContext context and TaskVariables config objects available through the scripts Binding.
2. Create a Java task
-
Create a Java class that extends the
com.ibm.dbb.task.AbstractTaskclass. TheAbstractTaskclass contains helper methods for retrieving common objects such as the ApacheCommandLineobject, which this tutorial interacts with. It also provides methods to assert required context/config and CLI options are set. Additionaly, the task defines theloggerLogger variable that can be used within the task.A constructor with arguments for the
BuildContextandTaskVariablesobjects is required, and should be passed to the super classes' constructor to be placed intocontextandconfigmember variables used within the task. Theexecuteabstract method is the main location for the task code. Its Integer return is a return code that can be used in conditions for subsequent tasks.The code of Java task is as follows. It performs the same operations as the previous Groovy task.
package <my.package.qualifier>; import org.apache.commons.cli.CommandLine; import com.ibm.dbb.build.BuildException; import com.ibm.dbb.task.AbstractTask; import com.ibm.dbb.task.BuildContext; import com.ibm.dbb.task.TaskConstants; import com.ibm.dbb.task.TaskVariables; public class CLILogEncoding extends AbstractTask { // This constructor is required for Java tasks, the context and config variables are assigned to members with the same name. public CLILogEncoding(BuildContext context, TaskVariables config) { super(context, config); } // The main execution method for the task, the zBuilder will call this when executing the task. @Override public Integer execute() throws BuildException { // The AbstractTask class contains convenience methods for verifying required variables, and retrieving common objects by their key CommandLine cli = getCommandLine(); verifyRequiredContextVariable(cli, TaskConstants.COMMAND_LINE); if (cli.hasOption("encoding")) { String encoding = cli.getOptionValue("encoding"); logger.debug("Pulled '{}' from the '--encoding' cli option.", encoding); context.setVariable("CLI_LOG_ENCODING", encoding); } return 0; } } -
Compile the Java code with a Java version 11 or later by using the following command:
javac -encoding UTF8 -classpath "$DBB_HOME/lib/*" <my/package/qualifier>/CLILogEncoding.java
3. Add the created task to a lifecycle
-
Add the
CLILogEncodingtask to the end of thetaskslist in your$DBB_BUILD/dbb-build.yamlfile:######################################################################### # Basic task configurations that can be referenced by multiple lifecycles ######################################################################### tasks: # Creates a CLI_LOG_ENCODING context variable with the value from the added '--encoding' CLI option. - task: CLILogEncodingAs you placed the Groovy script in the
$DBB_BUILD/groovyfolder with the same name as the task definition name, the zBuilder can discover it automatically. Alternatively, you can add thescriptfield to the task definition with a file path to the Groovy script.(Optional) If you are adding a Java task, be sure to add the
classfield to the task definition:- task: CLILogEncoding class: <my.package.qualifier>.CLILogEncoding -
Set the
logEncodingconfiguration variable of theFinishtask to theCLI_LOG_ENCODINGcontext variable that was created by theCLILogEncodingtask. Place the followinglogEncodingvariable definition in a newvariablessection under theFinishtask definition in the same location:- task: Finish variables: - name: logEncoding select: - condition: { exists: "CLI_LOG_ENCODING" } value: "${CLI_LOG_ENCODING}"A
selectvariable is used to set thelogEncodingvariable only when theCLILogEncodingtask has been executed and has found a--encodingoption on the command line. Otherwise, its value is null and theFinishtask outputs log files in the systems default encoding. -
Add the
CLILogEncodingtask to a lifecycle of your choosing. This tutorial uses thefulllifecycle in this case. Add the task name to the list of tasks under the lifecycle definition:lifecycles: # build all programs for the application - lifecycle: full # define the list of tasks to execute during the build lifecycle tasks: - Start - ScannerInit - MetadataInit - FullAnalysis - Languages # Defined in Languages.yaml - CLILogEncoding - FinishIt can be placed anywhere in the task list, so long as it comes before the
Finishtask where its created context variable is used. -
Add the
--encodingCLI option to the lifecycle definition. At the top of the lifecycle definition edited in the previous step, place aclisection with the following content:lifecycles: # build all programs for the application - lifecycle: full cli: options: - longOption: "encoding" hasArg: true description: "Unless set in the application configuration, overrides the default encoding used when writing out log files in the Finish task."In this definition you set the option name, indicate that it has an argument, and a description to be output alongside the option when the command
dbb build full --helpis entered.
4. Execute the task
Execute the full lifecycle by changing directories to the Mortgage Application sample and running the following command:
dbb build full --encoding UTF-8
The output from the new task is displayed in the console:
Language: LinkEdit
> Building 'MortgageApplication/link/epsmlist.lnk'
Task: CLILogEncoding
Task: Finish
The log files will be output and tagged in the requested encoding. This can be verified by executing ls -T logs/ from the same directory:
~/MortgageApplication #>ls -T logs
...
t UTF-8 T=on buildList.txt
This will only affect the created buildList.txt, changedFiles.txt, renamedFiles.txt, and deletedFiles.txt files. It is not covered in this tutorial, but this can be expanded to the language task logs by defining a new select variable with a default and then setting the logEncoding field of the dd statement to a reference of this new variable.