<|start_filename|>Utilities/ReadSMFRecords/ReadSMF.groovy<|end_filename|>
@groovy.transform.BaseScript com.ibm.dbb.groovy.ScriptLoader baseScript
import com.ibm.dbb.build.*
import com.ibm.dbb.build.smf.*

import com.ibm.jzos.ZFile
import com.ibm.jzos.ZFileConstants
import com.ibm.jzos.ZFileException
import com.ibm.jzos.RecordReader

// load the tools.groovy utility script
def scriptDir = new File(getClass().protectionDomain.codeSource.location.path).parent
def tools = loadScript(new File("$scriptDir/tools.groovy"))

// parse command line arguments and load build properties
def opts = tools.parseArgs(args)
def properties = tools.loadProperties(opts)
tools.validateRequiredProperties(["hlq", "datasets"])

def startTime = new Date()
properties.startTime = startTime.format("yyyyMMdd.hhmmss.mmm")
println("** Read SMF start at $properties.startTime")

// Set name or working dataset...After running the utility, this dataset contains the raw SMF records you've requested.
def smfwrk="${properties.hlq}.SMF.WRK"
try
{
    ZFile.remove("//'${smfwrk}'");
}
catch (ZFileException ex)
{}

// Define options for various datasets we will use
def sysprintOptions = "tracks space(5,5) unit(vio) blksize(80) lrecl(80) recfm(f,b) new"
def smfoutOptions = "CYL space(800,200) unit(SYSDA) new keep"
def smfwrkOptions = "new keep CYL space(100,10) lrecl(32756) dsorg(PS) recfm(V,B) BLKSIZE(32760)"

// Log files for the Dump Utility(IFASMFDP) and IDCAMS
def smflogFile = new File("${properties.workDir}/smfDump.log")
def reprologFile = new File("${properties.workDir}/repro.log")

// Commands for dump utility.
// For each dataset defined in SYS1.PARMLIB(SMFPRMxx) DSNAME parameter, add a INDD statement to commands.
// Also add a single OUTDD statement to indicate what SMF records types to dump	
def smfDumpParms = ""
def i = 0
properties.datasets.split(',').each{ dataset ->
	smfDumpParms += "INDD(SMFIN${++i},OPTIONS(DUMP))\n"
}
// By default, gets types 0-255. Use -i option to specify specific type
smfDumpParms += """OUTDD(SMFOUT,TYPE(${(properties.recordType == null)?"0:255":properties.recordType}))"""

// Set up SMF Dump utility to dump the SMF records to a temporary dataset...SMFOUT
def smfDump = new MVSExec().pgm("IFASMFDP")
i = 0
properties.datasets.split(',').each{ dataset ->
	smfDump.dd(new DDStatement().name("SMFIN${++i}").dsn(dataset).options("shr"))
}
smfDump.dd(new DDStatement().name("SMFOUT").dsn("&&SMFOUT").options(smfoutOptions).pass(true))
smfDump.dd(new DDStatement().name("SYSIN").instreamData(smfDumpParms))
smfDump.dd(new DDStatement().name("SYSPRINT").options(sysprintOptions))
smfDump.copy(new CopyToHFS().ddName("SYSPRINT").file(smflogFile).hfsEncoding(properties.logEncoding))

// Set up IDCAMS to copy SMF records from the temporary data to one we can use and read
def repro = new MVSExec().pgm("IDCAMS")
repro.dd(new DDStatement().name("SMFWRK").dsn(smfwrk).options(smfwrkOptions))
repro.dd(new DDStatement().name("SYSIN").instreamData(" REPRO INFILE(SMFOUT) OUTFILE(SMFWRK)"))
repro.dd(new DDStatement().name("SYSPRINT").options(sysprintOptions))
repro.copy(new CopyToHFS().ddName("SYSPRINT").file(reprologFile).hfsEncoding(properties.logEncoding))

// Run the Dump and IDCAMS commands
def rc = new MVSJob().executable(smfDump).executable(repro).maxRC(4).execute()
println("IFASMFDP/IDCAMS rc=$rc")

StringBuffer report = new StringBuffer()
tools.startReport(report)
// Now data is in ${smfwrk}. We will read this data directly from dataset so we can read record by record 
if ( rc == 0 && ZFile.dsExists("//'${smfwrk}'") )
{
	tools.startReportTable(report)
	RecordReader reader = null;
	def count = 0
	try
	{
		// Read each record from the working dataset
		reader = RecordReader.newReader("//'${smfwrk}'", ZFileConstants.FLAG_DISP_SHR);
		byte[] buffer = new byte[reader.getLrecl()];
		while ((bytesRead = reader.read(buffer)) >= 0)
		{
			byte[] data = Arrays.copyOf(buffer, bytesRead)
			def smfRec = new SmfRecord(data, true)
			if ( !tools.isSmfTypeInteresting(smfRec.getType()) )
				continue
			// Add SMF information to the html table
			tools.reportSMFRecord( report, data )
			count++
		}
	}
	finally
	{
		if (reader != null)
		{
			reader.close(); 
		}
	}
	tools.endReportTable(report)
	report.append("""
Total records: $count
""")
}
tools.endReport(report)
tools.writeReport(report)


<|start_filename|>Migration/sclm/groovy/DBBScriptTemplateConverter.groovy<|end_filename|>
/*
 * This script cannot be called as a standalone script since it requires
 * additional binding variable passed in from the parent script.
 *
 * This script is used in conjunction with the SCRIPT.template to generate
 * the DBB script.groovy script.
 *
 * @see GenerateBuildScrips.groovy.
 */
import groovy.transform.Field
import com.ibm.dbb.build.*

/*
 * This scriptXml represents the <script> node in DBB.xml
 */
def scriptXml = getBinding().getVariable('scriptXml')

/*
 * The File object of the DBB.xml file
 */
def dbbXmlFile = getBinding().getVariable('dbbXmlFile')

/*
 * The location of the generated output groovy scripts
 */
def outputDir = getBinding().getVariable('outputDir')

/*
 * A map to store all variables per Executable.
 * We need this map when generate the body of each
 * Executable and the invocation of this Executable.
 */
@Field def execVarsMap = [:]

/*
 * We only want to generate the execVarsMap once per script.
 */
@Field def isInit = false

def init()
{
    if (!isInit)
    {
        /*
         * Find all the ${} variables needed per Executable.
         */
        scriptXml.execute.each { execute ->

            def candidates = []
            execute.'**'.each { child ->
                candidates += child.attributes().values().findAll { value ->
                    value.contains('${')
                }
            }
            candidates.unique()
            def vars = []
            candidates.each { candidate ->
                vars += candidate.findAll(/\$\{([^\$\{\}]+)+\}/) { match, group ->
                    group
                }
            }
            vars.unique()

            def execVars = []
            execute.property.each { property ->
                execVars << property.@name
            }

            vars -= execVars

            execVarsMap."${execute.@name}" = vars
        }
        //println execVarsMap
        isInit = true
    }
}

/*
 * Generate the body of an Executable.
 *
 * @see ${DBBScriptTemplateConverter.generateExecuteMethods()} in SCRIPT.template
 */
def generateExecuteMethods()
{
    def outputs = []
    scriptXml.execute.each { execute ->
        def execOutput = []

        /*
         * The name of the Executable could contain invalid characters when
         * used for the name of the Groovy method.  Convert all invalid
         * characters to '_'
         */
        def executeName = convertToJavaIdentifier(execute.@name)
        execOutput << "def ${executeName}(Map args) {"
        def vars = execVarsMap."${execute.@name}"
        vars.each { var ->
            execOutput << "    def ${var} = args.${var}"
        }

        execute.property.each { property ->
            if (property.@name.startsWith('DBB_CONDITIONAL_')) {
                execOutput << "    final def ${property.@name} = ${property.@value}"
            }
            else {
                execOutput << "    final def CONST_${property.@name} = \"${property.@value}\""
                execOutput << "    def ${property.@name} = BuildProperties.getFileProperty(\"${property.@name}\", FILE) ?: CONST_${property.@name}"
            }
        }

        /* Make the generated script looking nicer if no variables */
        if (vars.size() > 0 || execute.property.size() > 0)
            execOutput << ''

        if (execute.@type == 'mvs' || execute.@type == 'tso' || execute.@type == 'ispf')
        {
            def tempOutput = ''
            def methodName = executeName
            if (execute.@type == 'mvs')
            {
                tempOutput += "    def $methodName = new MVSExec()"
                tempOutput += execute.@file ? ".file(\"${execute.@file}\")" : ''
                tempOutput += execute.@pgm ? ".pgm(\"${execute.@pgm}\")" : ''
                tempOutput += execute.@ddnames ? ".ddnames(\"${execute.@ddnames}\")" : ''
                if (execute.@parm) {
                    //handle parm variable substitution
                    def parms = []
                    execute.@parm.split(',').each {
                        def segment = it.trim()
                        if (segment.startsWith('SSI')) {
                            //SSI_INFO is specific to RTC, ignore for now
                        }
                        /*
                        else if (segment.contains('@{ssi_info}')) {
                            def ssiInfo = String.format("%08x", System.currentTimeMillis()).toUpperCase()
                            segment = segment.replace('@{ssi_info}', ssiInfo)
                            parms << segment
                        }
                        */
                        else {
                            //handle param contains variable
                            def varName = segment.startsWith('&amp;') ? segment.drop(5) : segment
                            varName = varName.startsWith('&') ? varName.drop(1) : varName
                            parms << (varName.size() == segment.size() ? segment : '${'+varName+'}')
                        }
                    }
                    tempOutput += ".parm(\"${parms.join(',')}\")"
                }
                tempOutput += execute.@freePgmAllocatedDDs ? ".freePgmAllocatedDDs(\"${execute.@freePgmAllocatedDDs}\")" : ''
            }
            else
            {
                tempOutput += "    def $methodName = "
                tempOutput += (execute.@type == 'tso') ? 'new TSOExec()' : 'new ISPFExec()'
                tempOutput += execute.@file ? ".file(\"${execute.@file}\")" : ''
                tempOutput += execute.@command ? ".command(\"${execute.@command}\")" : ''
                tempOutput += execute.@options ? ".options(\"${execute.@options}\")" : ''
                tempOutput += execute.@confDir ? ".confDir(\"${execute.@confDir}\")" : ''
                tempOutput += execute.@logLevel ? ".logLevel(\"${execute.@logLevel}\")" : ''
                tempOutput += execute.@logFile ? ".logFile(\"${execute.@logFile}\")" : ''
                tempOutput += execute.@logEncoding ? ".logEncoding(\"${execute.@logEncoding}\")" : ''
                tempOutput += execute.@reuseIspfSession ? ".reuseIspfSession(\"${execute.@reuseIspfSession}\")" : ''
                tempOutput += execute.@keepCommandScript ? ".keepCommandScript(\"${execute.@keepCommandScript}\")" : ''
                tempOutput += execute.@response ? ".response(\"${execute.@response}\")" : ''
                tempOutput += execute.@shExec ? ".shExec(\"${execute.@shExec}\")" : ''
                tempOutput += execute.@gatewayType ? ".gatewayType(\"${execute.@gatewayType}\")" : ''
                tempOutput += execute.@procedureName ? ".procedureName(\"${execute.@procedureName}\")" : ''
                tempOutput += execute.@accountNumber ? ".accountNumber(\"${execute.@accountNumber}\")" : ''
                tempOutput += execute.@groupId ? ".groupId(\"${execute.@groupId}\")" : ''
                tempOutput += execute.@regionSize ? ".regionSize(\"${execute.@regionSize}\")" : ''
            }
            execOutput << tempOutput

            execute.dd.each { dd ->
                if (dd.@condition) {
                    execOutput << "    if (${dd.@condition}) {"
                }
                execOutput << (dd.@condition ? "    " : "") + convertDDToDDStatement(dd, methodName)
                dd.dd.each { subdd ->
                    execOutput << convertDDToDDStatement(subdd, methodName)
                }
                if (dd.@condition) {
                    execOutput << '    }'
                }
            }
            execOutput << "    ${methodName}.execute()"
        }
        else if (execute.@type == 'jcl')
        {
            def tempOutput = "    def $methodName = new JCLExec()"
            tempOutput += execute.@dataset ? ".dataset(\"${execute.@dataset}\")" : ''
            tempOutput += execute.@member ? ".member(\"${execute.@member}\")" : ''
            tempOutput += execute.@file ? ".file(\"${execute.@file}\")" : ''
            tempOutput += execute.@text ? ".text(\"${execute.@text}\")" : ''
            tempOutput += execute.@jclEncoding ? ".jclEncoding(\"${execute.@jclEncoding}\")" : ''
            tempOutput += execute.@confDir ? ".confDir(\"${execute.@confDir}\")" : ''
            tempOutput += execute.volser ? ".volser(\"${execute.@volser}\")" : ''

            execOutput << tempOutput
            execOutput << "     ${methodName}.execute()"

        }

        execOutput << '}'
        outputs << execOutput.join('\n')
    }

    outputs.join('\n\n')
}

/*
 * Generate the invocation of each Executable.  Need to
 * pass in the correct required variables.
 *
 * @see ${DBBScriptTemplateConverter.generateExecuteMethodInvocations()} in SCRIPT.groovy
 */
def generateExecuteMethodInvocations()
{
    def outputs = []
    scriptXml.execute.each { execute ->
        def executeName = convertToJavaIdentifier(execute.@name)
        def invocationOutput = "rc = ${executeName}("
        def vars = execVarsMap."${execute.@name}"
        invocationOutput += vars?.collect {"$it : $it"}.join(', ')
        invocationOutput += ")"
        outputs << invocationOutput

        def maxRC = execute.@maxRC ?: 0
        if (maxRC)
            outputs << "if (failOnError && rc > $maxRC)"
        else
            outputs << "if (failOnError && rc)"
        outputs << '{' << "    println \"${executeName} failed, the return code (" + '$rc' + ") is greater than maxRC (${maxRC})\""
        outputs << "    System.exit(1)" << "}" << ""
    }
    outputs.join('\n')
}

/*
 * Generate the resolution rule for resolving dependencies. The logic is:
 * 1. Go through all DDAllocation and DDConcatenation and group them by DDName.
 * 2. For each of the collected DD in step 1, make sure they start with {HLQ} and
 *    can be mapped to a folder using the information in datasetMappings.properties.
 * 3. Generate the Groovy script based on the information collected in step 2.
 *
 * @see ${DBBScriptTemplateConverter.generateResolutionRules()} in SCRIPT.template
 */
def generateResolutionRules()
{
    outputs = []
    def datasetMappingsFile = new File(outputDir, 'datasetMappings.properties')
    def properties = BuildProperties.getInstance()
    properties.load(datasetMappingsFile)

    scriptXml.execute.each { execute ->
        concats = [:]
        def prevDDName
        execute.dd.each { dd ->

            if (dd.@dsn) {
                if (dd.@name) {
                    def ddnameKey = convertToJavaIdentifier(dd.@name)
                    def dds = concats."$ddnameKey"
                    if (!dds) {
                        dds = [] as Set
                        concats."$ddnameKey" = dds
                    }
                    dds << dd

                    dd.dd.each { subdd ->
                        dds << subdd
                    }
                }
            }
        }

        def ddResRuleMap = [:]
        concats.each { name,dds ->
            def paths = [] as Set
            dds.each { dd ->
                def fullyQualifiedDsn = dd.@dsn.toUpperCase()
                def dsn = fullyQualifiedDsn - '${HLQ}.'
                dsn = dsn.take(dsn.indexOf('(')) ?: dsn
                def patterns = properties.getFilePropertyPatterns('datasetMapping', dsn)
                patterns.each { pattern ->
                    paths << pattern
                }
            }
            ddResRuleMap."$name" = paths
        }

        ddResRuleMap.each {
            def ddName = it.key
            def paths = it.value
            def varName = (scriptXml.execute.size() > 1 ? "${execute.@name}_$ddName" : ddName) + "_rule"
            if (paths)
            {
                outputs << "def $varName = new ResolutionRule().library('$ddName')"
                paths.each { path ->
                    outputs << "${varName}.addPath(collection, sourceDir, '$path')"
                }
                outputs << "resolver.addResolutionRule($varName)"
            }
        }

        outputs << ""
    }

    outputs.join('\n')
}

/*
 * Utility method to convert an executor name into
 * a valid Java/Groovy method name.
 */
def convertToJavaIdentifier(def text)
{
    def newText = ''
    text.getChars().eachWithIndex { ch, index ->
        boolean isValid = (index == 0 ? Character.isJavaIdentifierStart(ch) : Character.isJavaIdentifierPart(ch))
        newText += (isValid ? ch : '_')
    }
    newText
}

def convertDDToDDStatement(def dd, def methodName)
{
    def ddOutput = ''
    if (dd.@dsn || dd.@name) {
        ddOutput += "    ${methodName}.dd(new DDStatement()"
        ddOutput += dd.@name ? ".name(\"${dd.@name}\")" : ""
        ddOutput += dd.@dsn ? ".dsn(\"${dd.@dsn}\")" : ""
        ddOutput += dd.@options ? ".options(\"${dd.@options}\")" : ""
        ddOutput += dd.@report ? ".report(${Boolean.valueOf(dd.@report)})" : ""
        ddOutput += dd.@output ? ".output(${Boolean.valueOf(dd.@output)})" : ""
        ddOutput += dd.@pass ? ".pass(${Boolean.valueOf(dd.@pass)})" : ""
        ddOutput += dd.@deployType ? ".deployType(\"${dd.@deployType}\")" : ""
        ddOutput += dd.@instreamData ? ".instreamData(\"${dd.@instreamData}\")" : ""
        ddOutput += ')'
    }
    ddOutput
}


<|start_filename|>Utilities/BuildManager/build.groovy<|end_filename|>
import groovy.transform.Field
import java.nio.file.*

Properties properties = new Properties()
File propertiesFile = new File('resources/config.properties')
propertiesFile.withInputStream {
	properties.load(it)
}

assert properties.dbb_home

println("Building JAR for project...")
println("Creating temporary directory...")
def tempBinDir = new File("bin/")
if (tempBinDir.exists())
		tempBinDir.deleteDir()
	tempBinDir.mkdirs()
		
def ant = new AntBuilder()

def classpath = ant.path
{
   fileset(dir: "$properties.dbb_home/lib")
   {
	 include(name: "*.jar")
  }
  fileset(dir: "$properties.dbb_home/groovy-2.4.12/lib/")
  {
	  include(name: "*.jar")
  }
}

ant.javac(srcdir: "src", destdir: "$tempBinDir", classpath: "$classpath", encoding: 'UTF-8', includeantruntime: 'false', debug: 'on', debuglevel: 'lines,vars,source')
ant.copy(todir: tempBinDir)
{
		fileset(dir: "src", excludes: "**/*.java")
}

def jarFile = "com.ibm.dbb.manager.jar"
	ant.jar(destfile: "resources/$jarFile", basedir: tempBinDir)
	
	tempBinDir.deleteDir()
	println("Successfuly built JAR for project")


<|start_filename|>Build/IDE/build/scripts/CobolCompile.groovy<|end_filename|>
import com.ibm.dbb.repository.*
import com.ibm.dbb.dependency.*
import com.ibm.dbb.build.*

// receive passed arguments
def file = args[0]
println("* Building $file using ${this.class.getName()}.groovy script")

// define local properties
def properties = BuildProperties.getInstance()
def srcPDS = "${properties.hlq}.COBOLLIB"
def copybookPDS = "${properties.hlq}.COPYBOOK"
def objectPDS = "${properties.hlq}.COBOL"
def member = CopyToPDS.createMemberName(file)
def logFile = new File("${properties.workDir}/${member}.log")

// create a reference to the Tools.groovy utility script
File scriptFile = new File("$properties.sourceDir/Build/IDE/build/Tools.groovy")
Class groovyClass = new GroovyClassLoader(getClass().getClassLoader()).parseClass(scriptFile)
GroovyObject tools = (GroovyObject) groovyClass.newInstance()

// define the BPXWDYN options for allocated temporary datasets
def tempCreateOptions = "cyl space(5,5) unit(vio) blksize(80) lrecl(80) recfm(f,b) new"

// copy program to PDS
println("Copying ${properties.sourceDir}/$file to $srcPDS($member)")
new CopyToPDS().file(new File("${properties.sourceDir}/$file")).dataset(srcPDS).member(member).execute()

//resolve program dependencies and copy to PDS
println("Resolving dependencies for file $file")
def resolver = tools.getCOBDependencyResolver(file)
def deps = resolver.resolve()
new CopyToPDS().dependencies(deps).dataset(copybookPDS).execute()

// compile the build file
println("Compiling build file $file")
def logicalFile = resolver.getLogicalFile()

// create the appropriate parm list
def parms = "APOST,DATA(31),LIB,NODYNAM,OBJ,OPT,RENT,RES"
if (properties.errPrefix) {
    parms = "$parms,ADATA,EX(ADX(ELAXMGUX))"
}

// define the MVSExec command to compile the program
def compile = new MVSExec().file(file).pgm("IGYCRCTL").parm(parms)

// add DD statements to the MVSExec command
compile.dd(new DDStatement().name("SYSIN").dsn("$srcPDS($member)").options("shr").report(true))
compile.dd(new DDStatement().name("SYSLIN").dsn("$objectPDS($member)").options("shr").output(true))
compile.dd(new DDStatement().name("SYSPRINT").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSADATA").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT1").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT2").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT3").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT4").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT5").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT6").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT7").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT8").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT9").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT10").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT11").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT12").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT13").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT14").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT15").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT16").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT17").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSMDECK").options(tempCreateOptions))

// add a syslib to the MVSExec command with optional CICS concatenation
compile.dd(new DDStatement().name("SYSLIB").dsn(copybookPDS).options("shr"))
//if (properties.team) {
       // for user builds concatenate the team build copbook pds
//       compile.dd(new DDStatement().dsn("${properties.team}.COPYBOOK").options("shr"))
//}

// add a tasklib to the MVSExec command with optional CICS and IDz concatenation
compile.dd(new DDStatement().name("TASKLIB").dsn(properties.SIGYCOMP).options("shr"))
if (properties.SFEKLOAD) {
    compile.dd(new DDStatement().dsn(properties.SFEKLOAD).options("shr"))
}

// add IDz User Build Error Feedback DDs
if (properties.errPrefix) {
    compile.dd(new DDStatement().name("SYSXMLSD").dsn("${properties.hlq}.${properties.errPrefix}.SYSXMLSD.XML").options("mod keep"))
}


// add a copy command to the MVSExec command to copy the SYSPRINT from the temporary dataset to an HFS log file
compile.copy(new CopyToHFS().ddName("SYSPRINT").file(logFile).hfsEncoding(properties.logEncoding))

// execute the MVSExec compile command
def rc = compile.execute()

// update build result
tools.updateBuildResult(file:"$file", rc:rc, maxRC:4, log:logFile)
	


<|start_filename|>Build/IDE/build/scripts/ASMCompile.groovy<|end_filename|>
import com.ibm.dbb.repository.*
import com.ibm.dbb.dependency.*
import com.ibm.dbb.build.*

// receive passed arguments
def file = args[0]
println("* Building $file using ${this.class.getName()}.groovy script")

// define local properties
def properties = BuildProperties.getInstance()
def srcPDS = "${properties.hlq}.ASMLIB"
def macroPDS = "${properties.hlq}.MACRO"
def objectPDS = "${properties.hlq}.ASM"
def member = CopyToPDS.createMemberName(file)
def logFile = new File("${properties.workDir}/${member}.log")

// create a reference to the Tools.groovy utility script
File scriptFile = new File("$properties.sourceDir/Build/IDE/build/Tools.groovy")
Class groovyClass = new GroovyClassLoader(getClass().getClassLoader()).parseClass(scriptFile)
GroovyObject tools = (GroovyObject) groovyClass.newInstance()

// define the BPXWDYN options for allocated temporary datasets
def tempCreateOptions = "cyl space(5,5) unit(vio) new"

// copy program to PDS
println("Copying ${properties.sourceDir}/$file to $srcPDS($member)")
new CopyToPDS().file(new File("${properties.sourceDir}/$file")).dataset(srcPDS).member(member).execute()

//resolve program dependencies
println("Resolving dependencies for file $file")
def resolver = tools.getASMDependencyResolver(file)
def deps = resolver.resolve()
new CopyToPDS().dependencies(deps).dataset(macroPDS).execute()

// compile the build file
println("Compiling program $file")
def logicalFile = resolver.getLogicalFile()

// define the MVSExec command to compile the file
def compile = new MVSExec().file(file).pgm("ASMA90").parm("")

// add DD statements to the MVSExec command
compile.dd(new DDStatement().name("SYSIN").dsn("$srcPDS($member)").options("shr").report(true))
compile.dd(new DDStatement().name("SYSLIN").dsn("$objectPDS($member)").options("shr").output(true))
compile.dd(new DDStatement().name("SYSPRINT").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT1").options(tempCreateOptions))

// add a syslib to the compile command with optional CICS concatenation
compile.dd(new DDStatement().name("SYSLIB").dsn(macroPDS).options("shr"))
if (properties.MACLIB) {
	compile.dd(new DDStatement().dsn(properties.MACLIB).options("shr"))
}
if (properties.MODGEN) {
	compile.dd(new DDStatement().dsn(properties.MODGEN).options("shr"))
}

// add IDz User Build Error Feedback DDs
if (properties.errPrefix) {
    compile.dd(new DDStatement().name("SYSADATA").options("DUMMY"))
    compile.dd(new DDStatement().name("SYSXMLSD").dsn("${properties.hlq}.${properties.errPrefix}.SYSXMLSD.XML").options("mod keep"))
}

// add a copy command to the compile command to copy the SYSPRINT from the temporary dataset to an HFS log file
compile.copy(new CopyToHFS().ddName("SYSPRINT").file(logFile).hfsEncoding("IBM-037"))

// execute the MVSExec compile command
def rc = compile.execute()

// update build result
tools.updateBuildResult(file:"$file", rc:rc, maxRC:4, log:logFile)


<|start_filename|>Snippets/ArchiveFunctions/copy_to_pds.groovy<|end_filename|>
import com.ibm.dbb.build.*
import com.ibm.dbb.build.DBBConstants.CopyMode;

// create PDS
def srcOptions = "cyl space(1,1) lrecl(80) dsorg(PO) recfm(F,B) dsntype(library) msg(1)"
new CreatePDS().dataset("USR.INDIV").options(srcOptions).create()
new CreatePDS().dataset("USR.ALL").options(srcOptions).create()

// copy individual binary file with custom member name
cmd = new CopyToPDS().dataset("USR.INDIV").member("CUSTOM").archive("archive/archive_bin.tar").archivedFile("bin/EPSMLIST").copyMode(CopyMode.BINARY)
cmd.execute()

// copy individual binary file with standard member name
cmd = new CopyToPDS().dataset("USR.INDIV").archive("archive/archive_bin.tar").archivedFile("bin/EPSMLIST").copyMode(CopyMode.BINARY)
cmd.execute()

// copy all binary files
cmd = new CopyToPDS().dataset("USR.ALL").archive("archive/archive_bin.tar").copyMode(CopyMode.BINARY)
cmd.execute()

// copy individual text file with custom member name
cmd = new CopyToPDS().dataset("USR.INDIV").member("TXT").archive("archive/archive_src.tar").archivedFile("src/HELLO.txt")
cmd.execute()

// copy individual text file with custom member name from compressed file
cmd = new CopyToPDS().dataset("USR.INDIV").member("TXTGZ").archive("archive/archive_src.tar.gz").archivedFile("src/HELLO.txt")
cmd.execute()

// copy individual text file with standard member name
cmd = new CopyToPDS().dataset("USR.INDIV").archive("archive/archive_src.tar").archivedFile("src/HELLO.txt")
cmd.execute()

// copy all textmode files
cmd = new CopyToPDS().dataset("USR.ALL").archive("archive/archive_src.tar")
cmd.execute()

<|start_filename|>Build/IDE/build/build.groovy<|end_filename|>
import com.ibm.dbb.build.*
import com.ibm.dbb.build.report.*
import com.ibm.dbb.repository.*
import com.ibm.dbb.dependency.*
import groovy.time.*

/**
 * This is the main build script for the IDz examples.
 *
 * usage: build.groovy [options] buildfile
 *
 * buildFile:  Relative path (from sourceDir) of the file to build. If file
 * is *.txt then assumed to be buildlist file containing a list of relative
 * path files to build. Build list file can be absolute or relative (from
 * sourceDir) path.
 *
 * options:
 *  -c,--collection <name>        Name of the dependency data collection
 *  -C, --clean                   Deletes the dependency collection and build result group
 *                                from the DBB repository then terminates (skips build)
 *  -e,--logEncoding <encoding>   Encoding of output logs. Default is EBCDIC
 *  -E,--errPrefix <uniqueId>     Unique id used for IDz error feedback datasets
 *  -f,--propFile <file>          Absolute path to a default property file
 *  -h,--help                     Prints this message
 *  -i,--id <id>                  DBB repository id
 *  -p,--pw <password>            DBB password
 *  -P,--pwFile <file>            Absolute path to file containing DBB
 *                                password
 *  -q,--hlq <hlq>                High level qualifier for partition data
 *                                sets
 *  -r,--repo <url>               DBB repository URL
 *  -s,--sourceDir <dir>          Absolute path to source directory
 *  -t,--team <hlq>               Team build hlq for user build syslib concatenations
 *  -u,--userBuild                Flag indicating running a user build
 *  -w,--workDir <dir>            Absolute path to the build output directory
 *
 * All command line options can be provided in a properties file passed in
 * using the -f, --propFile <file> argument. Use the argument long form name
 * for the properties name. Property file properties are used as default property
 * values and can be overridden by command line options
 */

// get script directory
def scriptDir = new File(getClass().protectionDomain.codeSource.location.path).parent

// check to see if there is a ./build.properties to load
def properties = BuildProperties.getInstance()
def buildPropFile = new File("$scriptDir/build.properties")
if (buildPropFile.exists())
   BuildProperties.load(buildPropFile)

// load the Tools.groovy utility script
File sourceFile = new File("$scriptDir/Tools.groovy")
Class groovyClass = new GroovyClassLoader(getClass().getClassLoader()).parseClass(sourceFile)
GroovyObject tools = (GroovyObject) groovyClass.newInstance()

// start build
def startTime = new Date()
properties.startTime = startTime.format("yyyyMMdd.hhmmss.mmm")
println("** Build start at $properties.startTime")

// load/set build properties from command line arguments
tools.loadProperties(args)
println("** Build properties at startup:")
println(properties.list())

// initialize build artifacts
tools.initializeBuildArtifacts()

// create workdir (if necessary)
new File(properties.workDir).mkdirs()
println("** Build output will be in $properties.workDir")

// create datasets (if necessary)
tools.createDatasets()

// create build list from input build file
def buildList = tools.getBuildList()

// scan all the files in the process list for dependency data (team build only)
if (!properties.userBuild) {
	println("** Scan the build list to collect dependency data")
	def scanner = new DependencyScanner()
	def logicalFiles = [] as List<LogicalFile>
	
	buildList.each { file ->
    	println("Scanning $file")
    	def logicalFile = scanner.scan(file, properties.sourceDir)
    	logicalFiles.add(logicalFile)
	}

	println("** Store the dependency data in repository collection '$properties.collection'")
	// create collection if needed
	def repo = tools.getDefaultRepositoryClient()
	if (!repo.collectionExists(properties.collection))
    	repo.createCollection(properties.collection)
    	
	repo.saveLogicalFiles(properties.collection, logicalFiles);
	println(repo.getLastStatus())
}

// define build script order
def buildOrder = [
	"ASMCompile",
	"CobolCompile",
	"PliCompile"
	]
	
// build programs
fileCount = tools.buildPrograms(buildOrder, buildList)

// generate build report
def (File jsonFile, File htmlFile) = tools.generateBuildReport()

// finalize build result
tools.finalizeBuildResult(jsonReport:jsonFile, htmlReport:htmlFile, filesProcessed:fileCount)


// Print end build message
def endTime = new Date()
def duration = TimeCategory.minus(endTime, startTime)
def state = (properties.error) ? "ERROR" : "CLEAN"
println("** Build finished at $endTime")
println("** Build State : $state")
println("** Total files processed : $fileCount")
println("** Total build time  : $duration")

// if error signal process error for Jenkins to record failed build
if (properties.error)
   System.exit(1)


<|start_filename|>Automation/Merge/JavaMerge/src/com/ibm/merge/Merge.java<|end_filename|>
package com.ibm.merge;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.ibm.zoautil.DatasetOptions;
import com.ibm.zoautil.DatasetType;
import com.ibm.zoautil.Datasets;
import com.ibm.zoautil.MVSCmd;
import com.ibm.zoautil.RecordFormat;
import com.ibm.zoautil.types.DDStatement;

public class Merge
{

	public static void main(String[] args) throws IOException
	{
		String hlq = "BUILDER";
		String mlq = "DFSORT";

		// Check parameters
		if ( args.length >= 1 )
		{
			if ( args[0].equals( "-?" ) || args[0].equals( "-h" ) )
			{
				System.out.println( "Run ZOAU Merge Java API example" );
				System.out.println( "\tjava com.ibm.merge.Merge <hlq or -?> <mlq>" );
				System.out.println( "\t\thlq - High level qualifier for datasets. Defaults to BUILDER." );
				System.out.println( "\t\tmlq - Mid level data set qualifier for datasets. Defaults to DFSORT." );
				System.exit( 0 );
			}
			else
			{
				hlq = args[0].toUpperCase();
			}
		}
		if ( args.length >= 2 )
		{
			mlq = args[1].toUpperCase();
		}

		String dsPrefix = hlq + "." + mlq;
		System.out.println( "dataset prefix: " + dsPrefix );

		String dsMaster = dsPrefix + ".master";
		String dsNew = dsPrefix + ".new";
		String dsCmd = dsPrefix + ".cmd";
		String dsMerge = dsPrefix + ".merge";

		// Options to create a fixed block 80 sequential data set
		// maxRC of 8 ignores an error if the dataset already exists
		DatasetOptions createDSOptions = new DatasetOptions().type( DatasetType.SEQ ).recordFormat( RecordFormat.FB ).lrecl( 80 ).maxRC( 8 );

		// Create Master dataset
		Datasets.create( dsMaster, createDSOptions );
		Datasets.write( dsMaster, "Charles      Field       278 323 6045" ); // write
		Datasets.write( dsMaster, "David        George      397 132 6025", true ); // append
		Datasets.write( dsMaster, "William      Young       178 333 5045", true ); // append

		// Create New dataset
		Datasets.create( dsNew, createDSOptions );
		Datasets.write( dsNew, "Emma         Hill        149 589 5045" ); // write
		Datasets.write( dsNew, "Sharon       Miller      153 232 6045", true ); // append
		Datasets.write( dsNew, "Steve        Green       748 111 6025", true ); // append

		// Create Cmd dataset
		Datasets.create( dsCmd, createDSOptions );
		Datasets.write( dsCmd, " MERGE FORMAT=CH,FIELDS=(1,9,A)" ); // write

		// Create Merge dataset
		Datasets.create( dsMerge, createDSOptions );

		// Create DD Statements for sort
		List<DDStatement> ddStatements = new ArrayList<DDStatement>();
		ddStatements.add( new DDStatement().ddName( "sortin01" ).dataset( dsMaster ) );
		ddStatements.add( new DDStatement().ddName( "sortin02" ).dataset( dsNew ) );
		ddStatements.add( new DDStatement().ddName( "sysin" ).dataset( dsCmd ) );
		ddStatements.add( new DDStatement().ddName( "sortout" ).dataset( dsMerge ) );
		ddStatements.add( new DDStatement().ddName( "sysout" ).dataset( "*" ) );

		// Sort
		int rc = MVSCmd.execute( "sort", "MSGPRT=CRITICAL,LIST", ddStatements );
		System.out.println( "MVSCmd rc: " + rc );
		if ( rc == 0 )
		{
			String results = Datasets.read( dsMerge );
			System.out.println( "Merged dataset contents:\n" + results );
		}
	}

}


<|start_filename|>Utilities/BuildManager/src/build/daemon/BuildDaemon.java<|end_filename|>
package build.daemon;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.LinkedList;
import java.util.Properties;
import java.util.Queue;

import build.utils.ConfigurationException;

public class BuildDaemon {
	/**
     * Daemon server. Listens for commands manages Build Process objects.
     */
	Properties properties;
	BuildProcessInterface[] buildProcessPool;
	Queue<BuildCommand> buildCommandQueue = new LinkedList<>();
	
	// socket server properties
	ServerSocket serverSocket;
	
	// process queue properties
	String dbbHome;
	String javaHome;
	Integer processQueueLimit;
	
	
	public BuildDaemon(String filePath) throws ConfigurationException, IOException {
		// load properties
		this.properties = new Properties();
		try {
			properties.load(new FileInputStream(filePath));
		} catch (FileNotFoundException e) {
			System.out.println("*** Configuration file not found.");
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		this.verifyProperties();

		// load settings from properties
		this.processQueueLimit = Integer.parseInt(this.properties.getProperty("build_process.groovyz.preload.amount"));
		this.dbbHome = this.properties.getProperty("dbb_home").replace("\n", "");
		// Java Home is optional and can be null
		this.javaHome = this.properties.getProperty("java_home") == null ? "" : this.properties.getProperty("java_home").replace("\n", "");
		
		// Add leading path separator if needed
		if ( this.javaHome.length() > 0 && ! javaHome.endsWith(File.separator) )
			this.javaHome += File.separator;
		if ( this.dbbHome.length() > 0 && ! dbbHome.endsWith(File.separator) )
			this.dbbHome += File.separator;		
		
		// create socket
		System.out.println("*** SERVER START");
		this.serverSocket = new ServerSocket(Integer.parseInt(properties.getProperty("daemon_port")));
		

		// create queue
		System.out.println("*** BUILD PROCESS POOL CREATED");
		this.buildProcessPool = new BuildProcessInterface[this.processQueueLimit];
	}
	
	public void verifyProperties() throws ConfigurationException {
		// verify required properties exist
		if (properties.getProperty("dbb_home") == null) {
			throw new ConfigurationException("*** DBB_HOME needs to be set in the properties file.");
		}
		if (properties.getProperty("daemon_port") == null) {
			throw new ConfigurationException("*** DAEMON_PORT needs to be set in the properties file.");
		}
		
		// confirm proper port format
		try {
			Integer.parseInt(properties.getProperty("daemon_port"));
		} catch (NumberFormatException n) {
			n.printStackTrace();
		}
		
	}
	
	public void preload() throws IOException {
        for (int i = 0; i < processQueueLimit; i++) {
    			try {
				buildProcessPool[i] = new BuildProcessInterface("id_" + i, this.dbbHome, this.javaHome,
						this.properties.getProperty("build_process.groovyz.preload.options"),
						this.properties.getProperty("build_process.groovyz.preload.classpath")
						);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
        }
        System.out.println("*** PROCESSES LOADED.");
    }
	
	public void produce(String command, DataOutputStream outboundConnection) {
		this.buildCommandQueue.add(new BuildCommand(command, outboundConnection));
	}
	
	public BuildCommand consume() {
		return this.buildCommandQueue.poll();
	}
	

	
    public static void main(String[] args) throws IOException, ConfigurationException {
    		BuildDaemon buildDaemon;
    		try {
    			buildDaemon = new BuildDaemon(args[0]);
    		}
    		catch (ArrayIndexOutOfBoundsException e) {
    			throw new ConfigurationException("*** Build Daemon requires a configuration file parameter");
    		}
    		
    		System.out.println("*** BUILD DAEMON START");
    		buildDaemon.preload();
        // handle messages from client
    		
    		// start queue thread
    		Thread command_thread = new Thread(){
    		    public void run(){
    		      while(true) {
    		    	  	try {
					Thread.sleep(25);
					if (buildDaemon.buildProcessPool.length > 0) {
						for (int i = 0; i < buildDaemon.processQueueLimit; i++) {
		        				if (buildDaemon.buildProcessPool[i].status == 0) {
		        					BuildCommand buildCommand = buildDaemon.consume();
		    						if (buildCommand != null) {
			        					// send build command
				        				System.out.printf("*** Sending command to process: %s.", buildDaemon.buildProcessPool[i].identifier);	
				    	        			buildDaemon.buildProcessPool[i].sendCommand(buildCommand.command, buildCommand.outboundConnection);
				    	        			break;
		    						}
			        			}
						}
					}
				} catch (InterruptedException e) {
					break;
				}
    		      }
    		    }
    		  };

    		 command_thread.start();

    		
        while(true) {
        		System.out.println(buildDaemon.javaHome);
	        	Socket connectionSocket;
	        	BufferedReader inboundConnection;
	        	DataOutputStream outboundConnection;
	        	
            connectionSocket = buildDaemon.serverSocket.accept();
	    		inboundConnection = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
	        outboundConnection = new DataOutputStream(connectionSocket.getOutputStream());
	
	
            // read message
	        String inboundMessage;
	        try {
	        		inboundMessage = inboundConnection.readLine().replace("'", "");
	        }
	        catch (NullPointerException e) {
	        		inboundMessage = "ERROR";
	        }


            System.out.println("COMMAND RECEIVED: " + inboundMessage);
            // check for command
            String COMMAND = inboundMessage.split(" ")[0];

            if (COMMAND.contains("kill")) {
            		try {
            			outboundConnection.writeBytes("*** Kill command received. \n");
            		} catch (SocketException e) {
            			System.out.println("*** FAILED TO WRITE TO CLIENT");
            		}
            		
				// send kill command, requires groovy script modification
				for (int i = 0; i < buildDaemon.processQueueLimit; i++) {
					System.out.printf("*** Stopping Groovy Process: %s \n", buildDaemon.buildProcessPool[i].identifier);
					buildDaemon.buildProcessPool[i].sendCommand("__STOP__", outboundConnection);
				}
				// shut down listener threads
				try {
					System.out.println("*** Shutting down process listener threads.");
					// wait for last listener to close
					buildDaemon.buildProcessPool[buildDaemon.processQueueLimit-1].listener.join();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				// shut down command thread
				try {
					System.out.println("*** Shutting down command thread.");
					command_thread.interrupt();
					command_thread.join();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("*** Shutting down command processor.");
				break;
				
            }
            else if (COMMAND.startsWith("groovy")){
            		// pass arguments as well
                String PROCESS_FILE = inboundMessage.split(" ", 2)[1];
	        		buildDaemon.produce(PROCESS_FILE, outboundConnection);
	        	}	
            else {
            		try {
            			outboundConnection.writeBytes("*** (SERVER) Unrecognized command received from client. \n");
            			
            		} catch (SocketException e) {
            			System.out.println("*** FAILED TO WRITE TO CLIENT");
            		}
            		outboundConnection.close();
            }

        }

        // close socket
        buildDaemon.serverSocket.close();
        System.out.println("*** DAEMON SHUTDOWN");
    }
}




<|start_filename|>Snippets/zUnitTestCase/RunZUnitJCL.groovy<|end_filename|>
import com.ibm.dbb.build.CopyToHFS
import com.ibm.dbb.build.DBBConstants
import com.ibm.dbb.build.JCLExec


/*********************************************************************************
 * The following sample shows how to use JCLExec API to execute a ZUnit and
 * display the results in the console.
 * 
 * This sample assumes that user has setup the ZUnit and a JCL to execute the 
 * ZUnit.
 * 
 * This sample requires:
 *    1.  The data set contains the JCL.
 *    2.  The data set contains the output of the ZUnit result.
 *    
 * Sample output:
 * 
 *    Running ZUnit in JCL 'HUNGLAM.ZUNIT.JCL(ZUNIT001)'
 *    The JCL Job HUNGLAM(JOB07890) completed with Max-RC CC 0004
 *    ****************** Module [AZUTC001] ******************
 *    Name:       AZUTC001 Test Case Written In COBOL
 *    Status:     FAIL
 *    Test cases: 4 (3 passed, 1 failed, 0 errors)
 *    Details: 
 *          AZUTC001.test001
 *          AZUTC001.test002
 *       x  AZUTC001.test003
 *          AZUTC001.test004
 * 
 *********************************************************************************/

/* DBB_CONF must be set for running JCLExec */
def confDir = System.getenv("DBB_CONF")

/* The data set contains the ZUnit JCL */
/* For example:  &HLQ.ZUNIT.JCL        */
def jclDataset = 

/* The ZUnit JCL */
/* For example:  ZUNIT001   */
def jclMember = 

/* The data set contains the output member */
/* For example:  &HLQ.ZUNIT.AZURES         */
def resultDataset = 

/* The output member */
/* For example:   AZURS001     */
def resultMember = 

println "Running ZUnit in JCL '$jclDataset($jclMember)'"

/* Execute the JCL */
def exec = new JCLExec()
int rc = exec.dataset(jclDataset).member(jclMember).confDir(confDir).execute()

/* Check the return code from the submitted job */
def maxRC = exec.maxRC
if (maxRC == 'CC 0000')
    println "The JCL Job ${exec.submittedJobId} completed successfully"
else
    println "The JCL Job ${exec.submittedJobId} completed with Max-RC: $maxRC"

/* Copy the result from the data set member to a temporary file on zFS to parse the XML */    
def resultFile = File.createTempFile(resultMember, 'xml')    
def copyRc = new CopyToHFS().dataset(resultDataset).member(resultMember).file(resultFile).copyMode(DBBConstants.CopyMode.BINARY).execute()
    
if (copyRc != 0)
{
    println "Error copying result file from ${resultDataset($resultMember)} to $resultFile"
    System.exit(1)
}

/* Parsing the result file and display summary of the result */
def runnerResult = new XmlParser().parse(resultFile)
def testCase = runnerResult.testCase
println "****************** Module ${testCase.@moduleName} ******************"
println "Name:       ${testCase.@name[0]}"
println "Status:     ${statusToString(testCase.@result[0])}"
println "Test cases: ${testCase.@tests[0]} (${testCase.@passed[0]} passed, ${testCase.@failures[0]} failed, ${testCase.@errors[0]} errors)"
println "Details: "

testCase.test.each { test ->
    if (test.@result == 'pass')
        print '    '
    else
        print ' x  '    
    println "${test.@name}"
}


/**
 * A helper to display the status as either PASS or FAIL
 * @param status the status from the zunit runner
 * @return a string representing the status
 */
static def statusToString(def status)
{
    return status.equalsIgnoreCase('pass') ? 'PASS' : 'FAIL'
}

<|start_filename|>Migration/sclm/groovy/DBBBuildTemplateConverter.groovy<|end_filename|>
/*
 * This script cannot be called as a standalone script since it requires
 * additional binding variable passed in from the parent script.
 * 
 * This script is used in conjunction with the BUILD.template to generate
 * the DBB build.groovy script.
 * 
 * @see GenerateBuildScrips.groovy.
 */

 
/*
 * buildXml represents the XML node <build> in DBB.xml file 
 */
def buildXml = getBinding().getVariable('buildXml')

/*
 * Generate the build order from the name of all <script> nodes
 * in DBB.xml.
 * 
 * @see ${DBBBuildTemplateConverter.getBuildOrder()} in BUILD.template
 */
def getBuildOrder()
{
    def scriptNames = []
    buildXml.scripts.script.each { script ->
        scriptNames << script.@name
    }    
    scriptNames.collect{"'" + it + "'"}.join(',')
}

/*
 * Generate a createPDS() call for each of the datasets in
 * DBB.xml file.
 * 
 * @see ${DBBBuildTemplateConverter.createDatasets()} in BUILD.template
 */
def createDatasets()
{
    def createPDS = []
    buildXml.datasets.dataset.each { dataset ->
        createPDS << "new CreatePDS().dataset(\"${dataset.@dsn}\").options(\"${dataset.@options}\").create()"
    }
    createPDS.collect{'    ' + it}.join('\n')
}

/*
 * Generate code to load property files. Handle both cases where
 * the property file is relative path vs absolute path.
 * 
 * @see ${DBBBuildTemplateConverter.loadPropertyFiles()} in BUILD.template
 */
def loadPropertyFiles()
{
    def outputs = []
    buildXml.propertyFiles.propertyFile.each { propertyFile ->
        if (propertyFile.@name) {        
            outputs << "properties.load(new File('${propertyFile.@name}.properties'))"
        }
        else if (propertyFile.@file) {        
            outputs << "properties.load(new File('${propertyFile.@file}'))"
        }
    }
    outputs.join('\n')
}



<|start_filename|>Build/IDE/build/scripts/PliCompile.groovy<|end_filename|>
import com.ibm.dbb.repository.*
import com.ibm.dbb.dependency.*
import com.ibm.dbb.build.*

// receive passed arguments
def file = args[0]
println("* Building $file using ${this.class.getName()}.groovy script")

// define local properties
def properties = BuildProperties.getInstance()
def srcPDS = "${properties.hlq}.PLILIB"
def copyPDS = "${properties.hlq}.PLILIB"
def objectPDS = "${properties.hlq}.PLI"
def member = CopyToPDS.createMemberName(file)
def logFile = new File("${properties.workDir}/${member}.log")

// create a reference to the Tools.groovy utility script
File scriptFile = new File("$properties.sourceDir/Build/IDE/build/Tools.groovy")
Class groovyClass = new GroovyClassLoader(getClass().getClassLoader()).parseClass(scriptFile)
GroovyObject tools = (GroovyObject) groovyClass.newInstance()

// define the BPXWDYN options for allocated temporary datasets
def tempCreateOptions = "cyl space(5,5) unit(vio) new"

// copy program to PDS
println("Copying ${properties.sourceDir}/$file to $srcPDS($member)")
new CopyToPDS().file(new File("${properties.sourceDir}/$file")).dataset(srcPDS).member(member).execute()

//resolve program dependencies and copy to PDS
println("Resolving dependencies for file $file and copying to $copyPDS")
def resolver = tools.getPLIDependencyResolver(file)
def deps = resolver.resolve()
new CopyToPDS().dependencies(deps).dataset(copyPDS).execute()

// compile the build file
println("Compiling program $file")	
def logicalFile = resolver.getLogicalFile()

// create the appropriate parm list
def compileParms = "AG,GN,M,NEST,NIS,OP,SOURCE,X(S),DEFAULT(NONASGN),SYSTEM(CICS),ATTRIBUTES"
if (properties.errPrefix) {
    compileParms = "$compileParms,XINFO(XML)"
}

// define the MVSExec command to compile the file
def compile = new MVSExec().file(file).pgm("IBMZPLI").parm(compileParms)

// add DD statements to the MVSExec command
compile.dd(new DDStatement().name("SYSIN").dsn("$srcPDS($member)").options("shr").report(true))
compile.dd(new DDStatement().name("SYSLIN").dsn("$objectPDS($member)").options("shr").output(true))
compile.dd(new DDStatement().name("SYSPRINT").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT1").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSTERM").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSPUNCH").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSOUT").options(tempCreateOptions))

// add a syslib to the compile command with optional CICS concatenation
compile.dd(new DDStatement().name("SYSLIB").dsn(copyPDS).options("shr"))

// add a tasklib to the MVSExec command with optional CICS and IDz concatenation
compile.dd(new DDStatement().name("TASKLIB").dsn(properties.SIBMZCMP).options("shr"))
if (logicalFile.isCICS()) {
    compile.dd(new DDStatement().dsn(properties.SDFHLOAD).options("shr"))
}
if (properties.SFEKLOAD) {
    compile.dd(new DDStatement().dsn(properties.SFEKLOAD).options("shr"))
}

// add IDz User Build Error Feedback DDs
if (properties.errPrefix) {
    compile.dd(new DDStatement().name("SYSADATA").options("DUMMY"))
    compile.dd(new DDStatement().name("SYSXMLSD").dsn("${properties.hlq}.${properties.errPrefix}.SYSXMLSD.XML").options("mod keep"))
}

// add a copy command to the compile command to copy the SYSPRINT from the temporary dataset to an HFS log file
compile.copy(new CopyToHFS().ddName("SYSPRINT").file(logFile).hfsEncoding(properties.logEncoding))

// execute the MVSExec compile command
def rc = compile.execute()

// update build result
tools.updateBuildResult(file:"$file", rc:rc, maxRC:4, log:logFile)


<|start_filename|>Utilities/Validation/toolkitValidation.groovy<|end_filename|>
@groovy.transform.BaseScript com.ibm.dbb.groovy.ScriptLoader baseScript
import com.ibm.dbb.repository.*
import com.ibm.dbb.dependency.*
import com.ibm.dbb.build.*

//Get DBB toolkit product info
version = new VersionInfo()
println(" ")
println("Info about this DBB installation")
println("--------------------------------")
println("DBB Version: " + version.getVersion())
println("Build Number: " + version.getBuild())
println("Release Date: " + version.getDate())
println(" ")

// execute IEFBR14
def doAlmostNothing = new MVSExec().pgm("IEFBR14")
def rc = doAlmostNothing.execute()

println("Test MVSExec of IEFBR14")
println("-----------------------")
println("RC: " + rc)
println(" ")


<|start_filename|>Snippets/ArchiveFunctions/scan.groovy<|end_filename|>
// example call: groovyz scan.groovy /usr/PublicSamples/ Snippets/ArchiveFunctions/src/HELLOCBL.cbl
import com.ibm.dbb.build.*
import com.ibm.dbb.dependency.*

def sourceDir = args[0]
def file = args[1]

println("Source Directory: ${sourceDir}")
println("File: ${file}")

// scan tar file
def scanner = new DependencyScanner()
for (f in scanner.scanArchive(file, sourceDir)) {
	println(f)
}

<|start_filename|>Pipeline/PublishSharedInterfaces/PublicCopybook.groovy<|end_filename|>
@groovy.transform.BaseScript com.ibm.dbb.groovy.ScriptLoader baseScript
import com.ibm.dbb.repository.*
import com.ibm.dbb.dependency.*
import com.ibm.dbb.build.*
import com.ibm.dbb.build.report.records.*
import com.ibm.dbb.build.report.*
import groovy.transform.*


// define script properties
@Field BuildProperties props = BuildProperties.getInstance()
@Field def buildUtils= loadScript(new File("${props.zAppBuildDir}/utilities/BuildUtilities.groovy"))
@Field RepositoryClient repositoryClient

println("** Building files mapped to ${this.class.getName()}.groovy script")

// verify required build properties
buildUtils.assertBuildProperties(props.cobol_requiredBuildProperties)

List<String> buildList = argMap.buildList

// reusing the cobol dataset definitions for copybooks
def langQualifier = "cobol"
buildUtils.createLanguageDatasets(langQualifier)

if (props.runzTests && props.runzTests.toBoolean()) {
    langQualifier = "cobol_test"
    buildUtils.createLanguageDatasets(langQualifier)
}

// iterate through build list
buildList.each { buildFile ->
    println "*** Building file $buildFile"

    // create mvs commands
    String member = CopyToPDS.createMemberName(buildFile)
    File logFile = new File( props.userBuild ? "${props.buildOutDir}/${member}.log" : "${props.buildOutDir}/${member}.copy.log")
    if (logFile.exists())
        logFile.delete()

    // compile the cobol program
    int rc = new CopyToPDS().file(new File(buildUtils.getAbsolutePath(buildFile))).dataset(props.cobol_cpyPDS).member(member).output(true).deployType("PublicCopy").execute()
    if (props.verbose) println "CopyToPDS for $buildFile = $rc"
    if (rc!=0){
    String errorMsg = "*! The compile return code ($rc) for $buildFile exceeded the maximum return code allowed ($maxRC)"
    println(errorMsg)
    props.error = "true"
    buildUtils.updateBuildResult(errorMsg:errorMsg,logs:["${member}.log":logFile],client:getRepositoryClient())
	}
}

// end script

<|start_filename|>Build/MortgageApplication/build/BindPackage.groovy<|end_filename|>
@groovy.transform.BaseScript com.ibm.dbb.groovy.ScriptLoader baseScript
import com.ibm.dbb.build.*
import com.ibm.dbb.repository.*
import com.ibm.dbb.dependency.*

/**
* This script builds a DB2 application package for SQL programs in the MortgageApplication sample.  It is 
* called by the CobolCompile.groovy script.  It requires that the properties in MortgageApplication/build/bind.properties 
* be set to the correct values for your system.
*
* **NOTE - This script contains syntax that requires PTF UI54779 be applied to the DBB toolkit. 
*/

// receive passed arguments
def file = argMap.file
println("* Binding $file using ${this.class.getName()}.groovy script")

// define local properties
def properties = BuildProperties.getInstance()
def dbrmPDS = "${properties.hlq}.DBRM"
def clistPDS = "${properties.hlq}.CLIST"
def cmdscpDS = "${properties.hlq}.ISPFGWY.EXEC"
def member = CopyToPDS.createMemberName(file)
def logFile = new File("${properties.workDir}/${member}_bind.log")
def srcOptions = "cyl space(1,1) lrecl(80) dsorg(PO) recfm(F,B) dsntype(library) msg(1)"

// create BIND CLIST if necessary
def clist = new File("${properties.workDir}/bind.clist")
if (!clist.exists()) {
   clist << """PROC 6 SUBSYS COLLID MEMBER LIB OWNER QUAL                       
   DSN SYSTEM(&SUBSYS)                                       
   BIND PACKAGE(&COLLID)    +                                
        MEMBER(&MEMBER)     +
        LIBRARY('&LIB')     +                                
        OWNER(&OWNER)       +                                
        QUALIFIER(&QUAL)    +                                
        ACTION(REPLACE)     +                                
        ISOLATION(CS)                                        
   END                                                       
EXIT CODE(&LASTCC)
"""

   // create CLIST PDS if necessary
   new CreatePDS().dataset(clistPDS).options(srcOptions).create()
   
   // copy CLIST to PDS 
   println("Copying ${properties.workDir}/bind.clist to $clistPDS(BIND)")
   new CopyToPDS().file(clist).dataset(clistPDS).member("BIND").execute()
}

// bind the build file
println("Executing CLIST to bind program $file")	

// define TSOExec to run the bind clist
def bind = new TSOExec().file(file)
                        .command("exec '$clistPDS(BIND)'")
                        .options("'${properties.SUBSYS} ${properties.COLLID} $member $dbrmPDS ${properties.OWNER} ${properties.QUAL}'")
                        .logFile(logFile)
                        .confDir(properties.CONFDIR)
                        .keepCommandScript(true)
bind.dd(new DDStatement().name("CMDSCP").dsn(cmdscpDS).options("shr"))

// execute the bind clist
def rc = bind.execute()

// add the DB2 BIND status to the build result
def tools = loadScript(new File("Tools.groovy"))
tools.updateBuildResult(file:"$file", rc:rc, maxRC:0, log:logFile)


<|start_filename|>Build/MortgageApplication/build/build.groovy<|end_filename|>
@groovy.transform.BaseScript com.ibm.dbb.groovy.ScriptLoader baseScript
import com.ibm.dbb.build.*
import com.ibm.dbb.build.report.*
import com.ibm.dbb.repository.*
import com.ibm.dbb.dependency.*
import groovy.time.*

/**
 * This is the main build script for the Mortgage Application.
 *
 * usage: build.groovy [options] buildfile
 * 
 * buildFile:  Relative path (from sourceDir) of the file to build. If file
 * is *.txt then assumed to be buildlist file containing a list of relative
 * path files to build. Build list file can be absolute or relative (from
 * sourceDir) path.
 * 
 * options:
 *  -b,--buildHash <hash>         Git commit hash for the build
 *  -c,--collection <name>        Name of the dependency data collection
 *  -C, --clean                   Deletes the dependency collection and build result group 
 *                                from the DBB repository then terminates (skips build)
 *  -e,--logEncoding <encoding>   Encoding of output logs. Default is EBCDIC
 *  -E,--errPrefix <uniqueId>     Unique id used for IDz error message datasets
 *  -h,--help                     Prints this message
 *  -i,--id <id>                  DBB repository id
 *  -p,--pw <password>            DBB password
 *  -P,--pwFile <file>            Absolute path to file containing DBB password
 *  -q,--hlq <hlq>                High level qualifier for partition data sets
 *  -r,--repo <url>               DBB repository URL
 *  -s,--sourceDir <dir>          Absolute path to source directory
 *  -t,--team <hlq>               Team build hlq for user build syslib concatenations
 *  -u,--userBuild                Flag indicating running a user build
 *  -w,--workDir <dir>            Absolute path to the build output directory
 *  
 * All command line options can be set in the MortgageApplication/build/build.properties file
 * that is loaded at the beginning of the build. Use the argument long form name for the property's
 * name. The properties in build.properties are used as default property values and can be 
 * overridden by command line options.
 */

println("java.version="+System.getProperty("java.runtime.version"))
println("java.home="+System.getProperty("java.home"))
println("user.dir="+System.getProperty("user.dir"))
 
// load the Tools.groovy utility script
def tools = loadScript(new File("Tools.groovy"))

// parse command line arguments and load build properties
def usage = "build.groovy [options] buildfile"
def opts = tools.parseArgs(args, usage)
tools.validateRequiredOpts(opts)
def properties = tools.loadProperties(opts)
if (!properties.userBuild) 
	tools.validateRequiredProperties(["dbb.RepositoryClient.url", "dbb.RepositoryClient.userId", "password", "collection"])
	
println("** Build properties at startup:")
println(properties.list())

def startTime = new Date()
properties.startTime = startTime.format("yyyyMMdd.hhmmss.mmm")
println("** Build start at $properties.startTime")

// initialize build artifacts
tools.initializeBuildArtifacts()

// create workdir (if necessary)
new File(properties.workDir).mkdirs()
println("** Build output will be in $properties.workDir")

// create datasets (if necessary)
tools.createDatasets()

// create build list from input build file
def buildList
def incremental = false
if (opts.arguments()) {
	buildList = tools.getBuildList(opts.arguments())
}
// incremental build or full build 
else { 
	
	// get the last successful build's buildHash
	println("** Searching for last successful build commit hash for build group $properties.collection")
	def lastBuildHash = null
	def repositoryClient = tools.getDefaultRepositoryClient()
	def lastBuildResult = repositoryClient.getLastBuildResult(properties.collection, BuildResult.COMPLETE, BuildResult.CLEAN)
	// pull hash from last build result
	if (lastBuildResult)
		lastBuildHash = lastBuildResult.getProperty("buildHash")
	
	// if no last build result, do full build
	if (lastBuildHash == null) {
		println("Could not locate last successful build commit hash for build group $properties.collection.  Building all files.")
		buildList = new File("$scriptDir/files.txt") as List<String>
	}
	else {
		lastBuildHash = lastBuildHash.trim()
		println("Last successful build commit hash located. label : ${lastBuildResult.getLabel()} , buildHash : $lastBuildHash")
		println("** Running incremental build")
		GroovyObject script = loadScript(new File("${properties.sourceDir}/Build/MortgageApplication/build/impacts.groovy"))
		// get arguments needed for impacts.groovy
		impactArguments = tools.getImpactArguments()
		// add last build hash to impact arguments
		impactArguments.add("--lastBuildHash")
		impactArguments.add("${lastBuildHash}")
		// invoke impacts.groovy
		script.invokeMethod("_run", impactArguments as String[])
		// copy output of impacts.groovy to buildlist
		buildList = new File("${properties.workDir}/buildList.txt") as List<String>
		incremental = true
	}
}	

// scan all the files in the process list for dependency data (team build only)
if (!incremental) {
	if (!properties.userBuild && buildList.size() > 0) { 
		// create collection if needed
		def repositoryClient = tools.getDefaultRepositoryClient()
		if (!repositoryClient.collectionExists(properties.collection))
			repositoryClient.createCollection(properties.collection) 
			
		println("** Scan the build list to collect dependency data")
		def scanner = new DependencyScanner()
		def logicalFiles = [] as List<LogicalFile>
		
		buildList.each { file ->
			// ignore whitespace files
			if (file.isAllWhitespace())
				return // only applies to local function
			// scan file
			println("Scanning $file")
			def logicalFile = scanner.scan(file, properties.sourceDir)
			// add file to logical file list
			logicalFiles.add(logicalFile)
			
			if (logicalFiles.size() == 500) {
				println("** Storing ${logicalFiles.size()} logical files in repository collection '$properties.collection'")
				repositoryClient.saveLogicalFiles(properties.collection, logicalFiles);
				println(repositoryClient.getLastStatus())  
				logicalFiles.clear() 		
			}
		}

		println("** Storing remaining ${logicalFiles.size()} logical files in repository collection '$properties.collection'")
		repositoryClient.saveLogicalFiles(properties.collection, logicalFiles);
		println(repositoryClient.getLastStatus())
	}
}

def processCounter = 0
if (buildList.size() == 0)
	println("** No files in build list.  Nothing to build.")
else {
	// build programs by invoking the appropriate build script
	def buildOrder = ["BMSProcessing", "Compile", "CobolCompile", "LinkEdit"]
	// optionally execute IMS MFS builds
	if (properties.BUILD_MFS.toBoolean()) 
		buildOrder << "MFSGENUtility"

	println("** Invoking build scripts according to build order: ${buildOrder[1..-1].join(', ')}")
	buildOrder.each { script ->
    	// Use the ScriptMappings class to get the files mapped to the build script
		def buildFiles = ScriptMappings.getMappedList(script, buildList)
		buildFiles.each { file ->
			runScript(new File("${script}.groovy"), ["file":file])
			processCounter++
		}
	}
}

// generate build report
def (File jsonFile, File htmlFile) = tools.generateBuildReport()

// finalize build result
tools.finalizeBuildResult(jsonReport:jsonFile, htmlReport:htmlFile, filesProcessed:processCounter)

// Print end build message
def endTime = new Date()
def duration = TimeCategory.minus(endTime, startTime)
def state = (properties.error) ? "ERROR" : "CLEAN"
println("** Build ended at $endTime")
println("** Build State : $state")
println("** Total files processed : $processCounter")
println("** Total build time  : $duration")

// if error signal process error for Jenkins to record failed build
if (properties.error)
   System.exit(1)


<|start_filename|>Snippets/ArchiveFunctions/cleanup.groovy<|end_filename|>
import com.ibm.dbb.build.*
import com.ibm.dbb.build.DBBConstants.CopyMode;

def delete = new MVSExec().pgm("IEFBR14")
delete.dd(new DDStatement().name("OLDDS").dsn("USR.INDIV").options("old delete"))
def rc = delete.execute()

delete = new MVSExec().pgm("IEFBR14")
delete.dd(new DDStatement().name("OLDDS").dsn("USR.ALL").options("old delete"))
rc = delete.execute()

<|start_filename|>Build/MortgageApplication/build/CobolCompile.groovy<|end_filename|>
@groovy.transform.BaseScript com.ibm.dbb.groovy.ScriptLoader baseScript
import com.ibm.dbb.repository.*
import com.ibm.dbb.dependency.*
import com.ibm.dbb.build.*

// receive passed arguments
def file = argMap.file
println("** Building $file using ${this.class.getName()}.groovy script")

// define local properties
def properties = BuildProperties.getInstance()
def cobolPDS = "${properties.hlq}.COBOL"
def copybookPDS = "${properties.hlq}.COPYBOOK"
def objectPDS = "${properties.hlq}.OBJ"
def loadPDS = "${properties.hlq}.LOAD"
def dbrmPDS = "${properties.hlq}.DBRM"
def member = CopyToPDS.createMemberName(file)
def logFile = new File("${properties.workDir}/${member}.log")

// create a reference to the Tools.groovy utility script
def tools = loadScript(new File("Tools.groovy"))

// define the BPXWDYN options for allocated temporary datasets
def tempCreateOptions = "cyl space(5,5) unit(vio) blksize(80) lrecl(80) recfm(f,b) new"
def tempPrintCreateOptions = "cyl space(5,5) unit(vio) blksize(133) lrecl(133) recfm(f,b) new"

// copy program to PDS
println("Copying ${properties.sourceDir}/$file to $cobolPDS($member)")
new CopyToPDS().file(new File("${properties.sourceDir}/$file")).dataset(cobolPDS).member(member).execute()
def parentDir = ""
if (properties.sourceDir.endsWith("Build")) {
    parentDir = properties.sourceDir
}
else {
    parentDir = properties.sourceDir + "/Build"
}
def parentFolder = new File("$parentDir")
def relativePath = ""
// Check to see if Build folder actually exist under the source directory
if (!parentFolder.exists()) {
    relativePath = properties.sourceDir
}
else {
    def buildDir2 = parentDir + "/Build"
    def buildDir2Folder = new File("$buildDir2")
    if (buildDir2Folder.exists()) {
        relativePath = buildDir2
    }
    else {
        relativePath = parentDir
    }
}

//resolve program dependencies and copy to PDS
println("Resolving dependencies for file $file and copying to $copybookPDS")
//def resolver = tools.getDefaultDependencyResolver(file)
def resolver = tools.getUserBuildDependencyResolver(file, relativePath)
def deps = resolver.resolve()
new CopyToPDS().dependencies(deps).dataset(copybookPDS).execute()

// compile and link-edit the build file
println("Compiling and link editing program $file")	
def logicalFile = resolver.getLogicalFile()

// create the appropriate compile parm list
def compileParms = "LIB"
if (logicalFile.isCICS()) {
    compileParms = "$compileParms,DYNAM,CICS"
}
if (logicalFile.isSQL()) {
    compileParms = "$compileParms,SQL"
}
if (properties.errPrefix) {
    compileParms = "$compileParms,ADATA,EX(ADX(ELAXMGUX))"
}

// define the MVSExec command to compile the program
def compile = new MVSExec().file(file).pgm("IGYCRCTL").parm(compileParms)

// add DD statements to the compile command
compile.dd(new DDStatement().name("SYSIN").dsn("$cobolPDS($member)").options("shr").report(true))
compile.dd(new DDStatement().name("SYSLIN").dsn("&&TEMPOBJ").options(tempCreateOptions).pass(true))
compile.dd(new DDStatement().name("SYSPRINT").options(tempPrintCreateOptions))
compile.dd(new DDStatement().name("SYSUT1").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT2").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT3").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT4").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT5").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT6").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT7").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT8").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT9").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT10").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT11").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT12").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT13").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT14").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT15").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT16").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT17").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSMDECK").options(tempCreateOptions))

// add a syslib to the compile command with optional CICS concatenation
compile.dd(new DDStatement().name("SYSLIB").dsn(copybookPDS).options("shr"))
if (properties.team) {
       // for user builds concatenate the team build copbook pds
       compile.dd(new DDStatement().dsn("${properties.team}.COPYBOOK").options("shr"))
}
if (logicalFile.isCICS()) {
    // create a DD statement without a name to concatenate to the last named DD
    compile.dd(new DDStatement().dsn(properties.SDFHCOB).options("shr"))
}

// add a tasklib to the compile command with optional CICS, DB2, and IDz concatenations
compile.dd(new DDStatement().name("TASKLIB").dsn(properties.SIGYCOMP).options("shr"))
if (logicalFile.isCICS()) {
    compile.dd(new DDStatement().dsn(properties.SDFHLOAD).options("shr"))
}
if (logicalFile.isSQL()) {
    compile.dd(new DDStatement().dsn(properties.SDSNLOAD).options("shr"))
}
if (properties.SFELLOAD) {
    compile.dd(new DDStatement().dsn(properties.SFELLOAD).options("shr"))
}

// add optional DBRMLIB if build file contains DB2 code
if (logicalFile.isSQL()) {
    compile.dd(new DDStatement().name("DBRMLIB").dsn("$dbrmPDS($member)").options("shr").output(true).deployType("DBRM"))
}	

// add IDz User Build Error Feedback DDs
if (properties.errPrefix) {
    compile.dd(new DDStatement().name("SYSADATA").options("DUMMY"))
    compile.dd(new DDStatement().name("SYSXMLSD").dsn("${properties.hlq}.${properties.errPrefix}.SYSXMLSD.XML").options("mod keep"))
}

// add a copy command to the compile command to copy the SYSPRINT from the temporary dataset to an HFS log file
compile.copy(new CopyToHFS().ddName("SYSPRINT").file(logFile).hfsEncoding(properties.logEncoding))


// define the MVSExec command to link edit the program
def linkedit = new MVSExec().file(file).pgm("IEWBLINK").parm("MAP,RENT,COMPAT(PM5)")
	
// add DD statements to the linkedit command
linkedit.dd(new DDStatement().name("SYSLMOD").dsn("$loadPDS($member)").options("shr").output(true).deployType("LOAD"))
linkedit.dd(new DDStatement().name("SYSPRINT").options(tempCreateOptions))
linkedit.dd(new DDStatement().name("SYSUT1").options(tempCreateOptions))
linkedit.dd(new DDStatement().name("SYSLIB").dsn(objectPDS).options("shr"))
linkedit.dd(new DDStatement().dsn(properties.SCEELKED).options("shr"))
if (logicalFile.isCICS()) {
    linkedit.dd(new DDStatement().dsn(properties.SDFHLOAD).options("shr"))
}

// add a copy command to the linkedit command to append the SYSPRINT from the temporary dataset to the HFS log file
linkedit.copy(new CopyToHFS().ddName("SYSPRINT").file(logFile).hfsEncoding(properties.logEncoding).append(true))


// use MVSJob start and stop commands to handle passed DDs
def job = new MVSJob()
job.start()

rc = compile.execute()
tools.updateBuildResult(file:"$file", rc:rc, maxRC:4, log:logFile)

if (rc <= 4) {
	rc = linkedit.execute()
    tools.updateBuildResult(file:"$file", rc:rc, maxRC:0, log:logFile)
	
	// Scan the load module to determine LINK dependencies. Impact resolver can use these to determine that
	// this file gets rebuilt if a LINK dependency changes.
	if (rc == 0 && !properties.userBuild) {
		println("* Scanning $loadPDS($member) for load module dependencies.")
		def scanner = new LinkEditScanner()
		def scannerLogicalFile = scanner.scan(file, loadPDS)
		
		// overwrite original logicalDependencies with load module dependencies
		logicalFile.setLogicalDependencies(scannerLogicalFile.getLogicalDependencies())
		
		// create the outputs collection if needed.
		// NOTE: The outputs collection should be separate from properties.collection otherwise these dependencies will
		//       be overwritten when the source is changed and scanned by source code scanner.
		// NOTE: The outputs collection must be included in ImpactResolver in Tools.groovy to include these outputs
		//       during impact analysis.
		def outputs_collection = "${properties.collection}_outputs"
		def repositoryClient = tools.getDefaultRepositoryClient()
		if (!repositoryClient.collectionExists(outputs_collection)) {
			repositoryClient.createCollection(outputs_collection)
		}
		
		// Store logical file and indirect dependencies to the outputs collection
		repositoryClient.saveLogicalFile( outputs_collection, logicalFile );
	}
}

job.stop()

// run DB2 Bind PACKAGE if bind is turned on (see MortgageApplication/build/bind.properties)
if (logicalFile.isSQL() && properties.RUN_DB2_BIND.toBoolean()) {
    def scriptName = "$properties.sourceDir/MortgageApplication/build/BindPackage.groovy"
    runScript(new File("BindPackage.groovy"), ["file":file])
}


<|start_filename|>Build/MortgageApplication/build/Compile.groovy<|end_filename|>
@groovy.transform.BaseScript com.ibm.dbb.groovy.ScriptLoader baseScript
import com.ibm.dbb.repository.*
import com.ibm.dbb.dependency.*
import com.ibm.dbb.build.*

// receive passed arguments
def file = argMap.file
println("** Building $file using ${this.class.getName()}.groovy script")

// define local properties
def properties = BuildProperties.getInstance()
def cobolPDS = "${properties.hlq}.COBOL"
def copybookPDS = "${properties.hlq}.COPYBOOK"
def objectPDS = "${properties.hlq}.OBJ"
def member = CopyToPDS.createMemberName(file)
def logFile = new File("${properties.workDir}/${member}.log")

// create a reference to the Tools.groovy utility script
def tools = loadScript(new File("Tools.groovy"))

// define the BPXWDYN options for allocated temporary datasets
def tempCreateOptions = "cyl space(5,5) unit(vio) blksize(80) lrecl(80) recfm(f,b) new"

// copy program to PDS
println("Copying ${properties.sourceDir}/$file to $cobolPDS($member)")
new CopyToPDS().file(new File("${properties.sourceDir}/$file")).dataset(cobolPDS).member(member).execute()
def parentDir = ""
if (properties.sourceDir.endsWith("Build")) {
    parentDir = properties.sourceDir
}
else {
    parentDir = properties.sourceDir + "/Build"
}
def parentFolder = new File("$parentDir")
def relativePath = ""
// Check to see if Build folder actually exist under the source directory
if (!parentFolder.exists()) {
    relativePath = properties.sourceDir
}
else {
    def buildDir2 = parentDir + "/Build"
    def buildDir2Folder = new File("$buildDir2")
    if (buildDir2Folder.exists()) {
        relativePath = buildDir2
    }
    else {
        relativePath = parentDir
    }
}

//resolve program dependencies and copy to PDS
println("Resolving dependencies for file $file and copying to $copybookPDS")
//def resolver = tools.getDefaultDependencyResolver(file)
def resolver = tools.getUserBuildDependencyResolver(file, relativePath)
def deps = resolver.resolve()
new CopyToPDS().dependencies(deps).dataset(copybookPDS).execute()

// compile the build file
println("Compiling build file $file")
def logicalFile = resolver.getLogicalFile()

// create the appropriate parm list
def parms = "LIB"
if (logicalFile.isCICS()) {
    parms = "$parms,DYNAM,CICS"
}
if (properties.errPrefix) {
    parms = "$parms,ADATA,EX(ADX(ELAXMGUX))"
}

// define the MVSExec command to compile the program
def compile = new MVSExec().file(file).pgm("IGYCRCTL").parm(parms)

// add DD statements to the MVSExec command
compile.dd(new DDStatement().name("SYSIN").dsn("$cobolPDS($member)").options("shr").report(true))
compile.dd(new DDStatement().name("SYSLIN").dsn("$objectPDS($member)").options("shr").output(true))
compile.dd(new DDStatement().name("SYSPRINT").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT1").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT2").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT3").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT4").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT5").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT6").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT7").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT8").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT9").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT10").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT11").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT12").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT13").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT14").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT15").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT16").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSUT17").options(tempCreateOptions))
compile.dd(new DDStatement().name("SYSMDECK").options(tempCreateOptions))

// add a syslib to the MVSExec command with optional CICS concatenation
compile.dd(new DDStatement().name("SYSLIB").dsn(copybookPDS).options("shr"))
if (properties.team) {
       // for user builds concatenate the team build copbook pds
       compile.dd(new DDStatement().dsn("${properties.team}.COPYBOOK").options("shr"))
}

if (logicalFile.isCICS()) {
    // create a DD statement without a name to concatenate to the last named DD added to the MVSExec
    compile.dd(new DDStatement().dsn(properties.SDFHCOB).options("shr"))
}

// add a tasklib to the MVSExec command with optional CICS and IDz concatenation
compile.dd(new DDStatement().name("TASKLIB").dsn(properties.SIGYCOMP).options("shr"))
if (logicalFile.isCICS()) {
    // create a DD statement without a name to concatenate to the last named DD added to the MVSExec
    compile.dd(new DDStatement().dsn(properties.SDFHLOAD).options("shr"))
}
if (properties.SFELLOAD) {
    compile.dd(new DDStatement().dsn(properties.SFELLOAD).options("shr"))
}

// add IDz User Build Error Feedback DDs
if (properties.errPrefix) {
    compile.dd(new DDStatement().name("SYSADATA").options("DUMMY"))
    compile.dd(new DDStatement().name("SYSXMLSD").dsn("${properties.hlq}.${properties.errPrefix}.SYSXMLSD.XML").options("mod keep"))
}

// add a copy command to the MVSExec command to copy the SYSPRINT from the temporary dataset to an HFS log file
compile.copy(new CopyToHFS().ddName("SYSPRINT").file(logFile).hfsEncoding(properties.logEncoding))

// execute the MVSExec compile command
def rc = compile.execute()

// update build result
tools.updateBuildResult(file:"$file", rc:rc, maxRC:4, log:logFile)
	

<|start_filename|>Build/IDE/ASM_Sample/ASAM1.asm<|end_filename|>

ASAM1    AMODE 31
ASAM1    CSECT
         USING ASAM1,R15
* *************************************************
*  SAMPLE PROGRAM ASAM1
*     AUTHOR: <NAME>
*             IBM CORPORATION
*
*  A SIMPLE PROGRAM THAT:
*   - READS A QSAM FILE
*   - WRITES THE FIRST 80 BYTES OF EACH RECORD TO AN OUTPUT FILE
*     IN CHARACTER AND HEX
*
*  PARAMETERS PASSED FROM CALLING PROGRAM:
*    NONE
*
*  FILES:
*    1. INPUT FILE IS QSAM AND HAS DD NAME = FILEIN
*         LRECL = 80
*    2. OUTPUT FILE IS QSAM OR SYSPRINT AND HAS DD NAME = FILEOUT
*         LRECL = 80
*
************************************************************
*                                  AT ENTRY, R13 = REGISTER SAVE AREA
*                                            R14 = RETURN ADDR
*                                            R15 = ADDR OF THIS PROGRAM
START    STM   R14,R12,12(R13)     SAVE REGISTERS IN PASSED SAVE AREA
         DROP  R15                 NO LONGER NEEDED AS BASE REGISTER
         LR    R12,R15             USE R12 AS THE BASE REGISTER
         USING ASAM1,R12           "
         LA    R14,SAVEAREA        R14 = ADDR OF NEW SAVE AREA
         ST    R13,4(R14)          STORE PREVIOUS SAVE AREA ADDR
         ST    R14,8(R13)          STORE NEW SAVE AREA ADDRESS
         LR    R13,R14             R13 = ADDR OF NEW SAVE AREA
         B     MAINLINE
         DS    0H
         DC    CL32'******** PROGRAM ASAM1 *********'
MAINLINE BAL   R11,OPENFILS
         BAL  R11,MAINLOOP
         BAL   R11,CLOSFILS
*
         MVC  STATUS,=C'RETURNING TO CALLING PROGRAM  '
*
RETURN00 L     R15,RETCODE
         L     R13,4(R13)          R13 = ADDR OF PREVIOUS SAVE AREA
         ST    R15,16(R13)         SAVE RETURN CODE
         LM    R14,R12,12(R13)     RESTORE REGISTERS (EXCEPT 13)
         BR    R14                 RETURN TO CALLER
*******************************************
* PROCEDURE MAINLOOP
*
MAINLOOP ST    R11,MAINLSAV      SAVE RETURN ADDRESS
*     * READ INPUT RECORD
MAINLTOP BAL   R11,READIN
*     * CHECK FOR END-OF-FILE
         CLC   EOFFLAG,=X'FF'      END OF FILE?
         BE    MAINLEX               IF YES - EXIT MAIN LOOP
*     * CALL SUBPROGRAM TO GET HEX CHARACTERS
         MVC   STATUS,=C'CALLING SUBPROGRAM ASAM2      '
         LA    R13,SAVEAREA
****     LINK  EP=ASAM2,(DATALEN,INREC,HEXTOP,HEXBOT),VL=1
*  FOLLOWING LINES COMMENTED OUT WHEN LOAD CHANGED TO STATIC CALL
*****    LOAD  EP=ASAM2
*****    LTR   R15,R15
*****    BNZ   LOADERR
*****    LA    R13,SAVEAREA
*****    LA    R1,PARMLIST     R1 = PARM LIST
*****    LR    R15,R0          R0 = ADD OF LOADED PROGRAM
*****    BALR  R14,R15         BRANCH TO SUBPROGRAM
         CALL  ASAM2,(DATALEN,INREC,HEXTOP,HEXBOT),VL
*     * WRITE LINE: 'RECORD NUMBER NNNNNN'
         UNPK  DIAGRECT,RECCOUNT   FORMAT RECORD COUNT
         OI    DIAGRECT+9,X'F0'
         MVC   DIAGREC,OUTLINE1     REC NUM LINE
         BAL   R11,WRITEOUT
*     * WRITE RULE LINES   ....5...10...15...20...
         MVC   DIAGREC,OUTLINE2
         BAL   R11,WRITEOUT
         MVC   DIAGREC,OUTLINE3
         BAL   R11,WRITEOUT
*     * WRITE DATA LINE 1: (CHARACTER FORMAT)
         MVC   DIAGREC,INREC
         BAL   R11,WRITEOUT
*     * WRITE DATA LINE 2: (TOP HEX LINE)
         MVC   DIAGREC,HEXTOP
         BAL   R11,WRITEOUT
*     * WRITE DATA LINE 3: (BOTTOM HEX LINE)
         MVC   DIAGREC,HEXBOT
         BAL   R11,WRITEOUT
*     * WRITE BLANK LINE
         MVC   DIAGREC,BLANKS
         BAL   R11,WRITEOUT
*     * GO BACK TO TOP OF LOOP
         B     MAINLTOP
*
LOADERR  WTO   '* ASAM1: ERROR LOADING PROGRAM ASAM2 '
         MVI   EOFFLAG,X'FF'
MAINLEX  L     R11,MAINLSAV
         BR    R11                    RETURN TO MAINLINE LOGIC
*
*******************************************
* PROCEDURE OPENFILS
*
OPENFILS ST    R11,OPENFSAV
         MVC  STATUS,=C'IN OPENFILS SUBROUTINE        '
         SLR   R15,R15                SET DEFAULT RETURN CODE TO ZERO
         OPEN  (FILEOUT,OUTPUT)       OPEN DDNAME
         LTR   R15,R15                OPEN RC = 0 ?
         BNZ   BADOPENI                 IF NO - THEN ERROR
         OPEN  (FILEIN,INPUT)         OPEN DDNAME
         LTR   R15,R15                OPEN RC = 0 ?
         BNZ   BADOPENI                 IF NO - THEN ERROR
         L     R11,OPENFSAV
         BR    R11                    RETURN TO MAINLINE LOGIC
BADOPENI WTO   '* ASAM1: ERROR OPENING INPUT FILE    '
         ST    R15,RETCODE
         B     RETURN00
BADOPENO WTO   '* ASAM1: ERROR OPENING OUTPUT FILE   '
         ST    R15,RETCODE
         B     RETURN00
*******************************************
* PROCEDURE CLOSFILS
*
CLOSFILS ST    R11,CLOSFSAV      SAVE RETURN ADDRESS
         MVC   STATUS,=C'IN CLOSFILS PROCEDURE         '
         CLOSE FILEOUT
         CLOSE FILEIN
         L     R11,CLOSFSAV
         BR    R11               RETURN
*******************************************
* PROCEDURE READIN
*
READIN   ST    R11,READISAV
         MVC   STATUS,=C'IN READIN PROCEDURE           '
         SLR   R15,R15                SET DEFAULT RETURN CODE TO ZERO
         GET   FILEIN,INREC           READ INPUT RECORD
         AP    RECCOUNT,=PL1'1'       INCREMENT RECORD COUNTER
         B     READIEX
READIEOF MVI   EOFFLAG,X'FF'
READIEX  L     R11,READISAV
         BR    R11
*
*******************************************
* PROCEDURE WRITEOUT
*
WRITEOUT ST    R11,WRITOSAV
         MVC   STATUS,=C'IN WRITEOUT PROCEDURE         '
         PUT   FILEOUT,DIAGREC         WRITE OUTPUT RECORD
         L     R11,WRITOSAV
         BR    R11
********************************************************
* STORAGE AREAS
*
EYECATCH DC    CL32'*** PROGRAM ASAM1 DATA AREAS ***'
FILECC   DC    H'0'                  MAX RETURN CODE FROM FILE OPENS
RECCOUNT DC    PL4'0'                INPUT RECORD COUNT
PROCCNT  DC    PL4'0'                PROCEDURE COUNT
STATUS   DC    CL30' '               CURRENT PROGRAM STATUS
EOFFLAG  DC    XL1'00'               END OF INPUT FILE FLAG
DATALEN  DC    F'80'                 LENGTH OF DATA PASSED TO SUBPGM
INREC    DC    CL80' '               INPUT RECORD
DIAGREC   DC    CL80' '               OUTPUT RECORD
HEXTOP   DC    CL80' '               TOP ROW OF HEX DATA
HEXBOT   DC    CL80' '               BOTTOM ROW OF HEX DATA
RETCODE  DC    F'0'                  DEFAULT RETURN CODE IS ZERO
MAINLSAV DC    F'0'
OPENFSAV DC    F'0'
CLOSFSAV DC    F'0'
READISAV DC    F'0'
WRITOSAV DC    F'0'
*
*  PARAMETER LIST FOR SUBPGM ASAM2
PARMLIST EQU   *
         DC    AL4(DATALEN)
         DC    AL4(INREC)
         DC    AL4(HEXTOP)
         DC    AL4(HEXBOT)                  SET HIGH ORDER BIT ON
*                                           TO FLAG END OF PARM LIST
OUTLINE1 DS    0CL80
         DC    CL14'RECORD NUMBER '
DIAGRECT DC    CL10'          '
         DC    56C' '
*
OUTLINE2 DS    0CL80
         DC    CL40'....0....1....1....2....2....3....3....4'
         DC    CL40'....4....5....5....6....6....7....7....8'
*
OUTLINE3 DS    0CL80
         DC    CL40'....5....0....5....0....5....0....5....0'
         DC    CL40'....5....0....5....0....5....0....5....0'
*
BLANKS   DC    80C' '
*
*        LTORG
SAVEAREA DC    18F'0'
********************************************************
* FILE DEFINITIONS
*
FILEOUT  DCB   DSORG=PS,RECFM=FB,MACRF=(PM),LRECL=80,                  X
               DDNAME=FILEOUT
FILEIN   DCB   DSORG=PS,RECFM=FB,MACRF=(GM),LRECL=80,                  X
               DDNAME=FILEIN,EODAD=READIEOF
*
* REGISTER EQUATES
*
R0       EQU   0
R1       EQU   1
R2       EQU   2
R3       EQU   3
R4       EQU   4
R5       EQU   5
R6       EQU   6
R7       EQU   7
R8       EQU   8
R9       EQU   9
R10      EQU   10
R11      EQU   11
R12      EQU   12
R13      EQU   13
R14      EQU   14
R15      EQU   15
*
         END

<|start_filename|>Build/HelloWorld/hello_asm.groovy<|end_filename|>
import com.ibm.dbb.build.*

// Change the following variables to match your system
hlq        = "USER"
sourceDir  = "/u/user/build"
macLib     = "SYS1.MACLIB"
//userMacLib = "USER.MACLIB"  //Uncomment if needed

println("Creating ${hlq}.HASRC. . .")
CreatePDS createPDSCmd = new CreatePDS();
createPDSCmd.setDataset("${hlq}.HASRC");
createPDSCmd.setOptions("tracks space(1,1) lrecl(80) dsorg(PO) recfm(F,B) dsntype(library)");
createPDSCmd.create();

println("Creating ${hlq}.HAMOD. . .")
createPDSCmd.setDataset("${hlq}.HAMOD");
createPDSCmd.setOptions("tracks space(1,1) lrecl(80) dsorg(PO) recfm(F,B) dsntype(library)");
createPDSCmd.create();

// copy program to PDS
println("Copying hello.asm to ${hlq}.HASRC")
new CopyToPDS().file(new File("${sourceDir}/hello.asm")).dataset("${hlq}.HASRC").member("HELLO").execute()

// assemble the build file
println("Assembling hello.asm")

// define the MVSExec command to compile the file
def compile = new MVSExec().file("${sourceDir}/hello.asm").pgm("ASMA90").parm("")

// add DD statements to the MVSExec command
compile.dd(new DDStatement().name("SYSIN").dsn("${hlq}.HASRC(HELLO)").options("shr").report(true))
compile.dd(new DDStatement().name("SYSLIN").dsn("${hlq}.HAMOD(HELLO)").options("shr").output(true))
compile.dd(new DDStatement().name("SYSPRINT").options("cyl space(5,5) unit(vio) new"))
compile.dd(new DDStatement().name("SYSUT1").options("cyl space(5,5) unit(vio) new"))

// add a syslib to the compile command with optional CICS concatenation
compile.dd(new DDStatement().name("SYSLIB").dsn("${macLib}").options("shr"))
//compile.dd(new DDStatement().dsn("${userMacLib}").options("shr"))   //Uncomment if user maclib needed

// log 
compile.copy(new CopyToHFS().ddName("SYSPRINT").file(new File("${sourceDir}/hello_asm.log")))

// execute the MVSExec compile command
def rc = compile.execute()

if (rc > 4)
    println("Assembly failed!  RC=$rc")
else
    println("Assembly successful!  RC=$rc")


<|start_filename|>Build/HelloWorld/hello.asm<|end_filename|>
HELLO    CSECT
         USING *,15
         STM   14,12,12(13)
         LR    12,15
         USING HELLO,12
         WTO   'HI'
         XR    15,15
         RETURN (14,12)
         END


<|start_filename|>Snippets/ArchiveFunctions/dependency_resolution.groovy<|end_filename|>
import com.ibm.dbb.build.*
import com.ibm.dbb.dependency.*

def sourceDir = null
def file = null

try {
	sourceDir = args[0] // e.g "/u/user/PublicSamples/"
	file = args[1] // e.g "Snippets/ArchiveFunctions/src/HELLOCBL.cbl"
}
catch (Exception e){
	println("Correct usage: groovyz dependency_resolution.groovy {sourceDir} {file}")
	return
}


println("Source Directory: ${sourceDir}")
println("File: ${file}")

// resolve dependency
def path = new DependencyPath().sourceDir(sourceDir).archive("Snippets/ArchiveFunctions/archive/archive_copybook.tar").directory("copybook")
def rule = new ResolutionRule().library("SYSLIB").path(path)
def resolver = new DependencyResolver().sourceDir(sourceDir).file(file).rule(rule)
resolver.setScanner(new DependencyScanner())

println(resolver.resolve())

// resolve normally
path = new DependencyPath().sourceDir(sourceDir).directory("copybook")
rule = new ResolutionRule().library("SYSLIB").path(path)
resolver = new DependencyResolver().sourceDir(sourceDir).file(file).rule(rule)
resolver.setScanner(new DependencyScanner())

println(resolver.resolve())
