Version Differences for Miscellaneous Scripts

(Almost Done Alphabetizing)
Line 852:
  }</pre>    }</pre> 
       
- = Update Environment Properties for All Projects =      
- Here's a modification that runs form within AnthillPro. The environment is selected to be the current running environment and the other values are read out of properties (the environment could come from a property as well).      
- ==== AHPSCRIPTS-14 ====      
- <pre>import com.urbancode.anthill3.main.client.AnthillClient;      
- import com.urbancode.anthill3.persistence.UnitOfWork;      
- import com.urbancode.anthill3.domain.project.*;      
- import com.urbancode.anthill3.domain.project.envprops.*;      
- import com.urbancode.anthill3.domain.servergroup.*;      
- import java.util.*;      
       
       
- variableName = PropertyLookup.get("variableName");      
- newVariableValue = PropertyLookup.get("variableValue");      
- boolean isSecure = Boolean.parseBoolean(PropertyLookup.get("isSecure"));      
- environment = EnvironmentLookup.getCurrent();      
       
       
- // Project      
- Project[] projects = ProjectFactory.getInstance().restoreAll();      
       
- // Loop through projects. If it has environment props for this, find the      
- // right one and change it as appropriate.      
- for (int i = 0; i < projects.length; i++) {      
-      
- ProjectEnvironmentProperty[] envPropArray = environment.getEnvironmentPropertiesForProject(projects[i]);      
- boolean foundVariable = false;      
- for (int j = 0; j < envPropArray.length; j++) {      
- if (envPropArray[j].getName().equals(variableName)) {      
- foundVariable = true;      
- envPropArray[j].setValue(newVariableValue);      
- envPropArray[j].store();      
- }      
- }      
-      
- if (!foundVariable) {      
- ProjectEnvironmentProperty newProp = new ProjectEnvironmentProperty(true);      
-      
- newProp.setProject(projects[i]);      
- newProp.setServerGroup(environment);      
- newProp.setName(variableName);      
- newProp.setValue(newVariableValue);      
- newProp.setSetAsEnvProp(false);      
- newProp.setSecureValue(isSecure);      
-      
- newProp.store();      
- }      
-      
- }      
- </pre>      
       
  = Export Project Configuration to XML =    = Export Project Configuration to XML = 
       
Line 1389:
  }     }  
  return output;</pre>    return output;</pre> 
    +  
    + = Overwrite Dependency Pushed Properties =  
       
    + * AnthillPro pushes properties to builds triggered by dependencies, this script overwrites the values for the properties that are defined on the dependent worfklow/project  
       
    + ==== AHPSCRIPTS-101 ====  
    + <pre>import com.urbancode.anthill3.domain.buildrequest.BuildRequest;  
    + import com.urbancode.anthill3.domain.buildrequest.RequestSourceEnum;  
    + import com.urbancode.anthill3.domain.persistent.PersistenceException;  
    + import com.urbancode.anthill3.domain.project.Project;  
    + import com.urbancode.anthill3.domain.project.prop.ProjectProperty;  
    + import com.urbancode.anthill3.domain.property.PropertyValue;  
    + import com.urbancode.anthill3.domain.workflow.Workflow;  
    + import com.urbancode.anthill3.persistence.UnitOfWork;  
    + import com.urbancode.anthill3.runtime.scripting.helpers.BuildRequestLookup;  
    + import com.urbancode.anthill3.runtime.scripting.helpers.ProjectLookup;  
    + import com.urbancode.anthill3.runtime.scripting.helpers.WorkflowLookup;  
       
    + import java.util.HashMap;  
    + import java.util.Map;  
       
       
    + try {  
    + BuildRequest request = BuildRequestLookup.getCurrent();  
    + if (request != null && RequestSourceEnum.DEPENDENCY.equals(request.getRequestSource()) &&  
    + request.getPropertyNames().length > 0) {  
    + Project project = ProjectLookup.getCurrent();  
    + Workflow workflow = WorkflowLookup.getCurrent();  
    + Map<String, PropertyValue> changedPropertyMap = new HashMap<String, PropertyValue>();  
    + for (String property : request.getPropertyNames()) {  
    + PropertyValue initialValue = request.getPropertyValue(property);  
       
    + // check the workflow first  
    + PropertyValue originalValue = workflow.getPropertyValue(property);  
       
    + // if not on the workflow check the project  
    + if (originalValue == null) {  
    + ProjectProperty projectProp = project.getProperty(property);  
    + if (projectProp != null) {  
    + originalValue = new PropertyValue(projectProp.getValue(), false);  
    + }  
    + }  
       
    + // and now see if they match  
    + if (originalValue != null && !originalValue.equals(initialValue)) {  
    + changedPropertyMap.put(property, originalValue);  
    + }  
    + else if (originalValue == null) {  
    + commandOutput.println("Could not find original value for " + property);  
    + }  
    + else {  
    + commandOutput.println("Value did not change for " + property);  
    + }  
    + }  
       
    + if (changedPropertyMap.size() > 0) {  
    + request = (BuildRequest) UnitOfWork.getCurrent().lockAndReload(request);  
    + for (String property : changedPropertyMap.keySet()) {  
    + request.setPropertyValue(property, changedPropertyMap.get(property));  
    + commandOutput.println("Replaced value of " + property + " with " +  
    + changedPropertyMap.get(property).getDisplayedValue());  
    + }  
    + try {  
    + UnitOfWork.getCurrent().commit();  
    + }  
    + catch (PersistenceException pe) {  
    + pe.printStackTrace(commandOutput);  
    + try {  
    + UnitOfWork.getCurrent().cancel();  
    + }  
    + catch (Exception e) {  
    + }  
    + }  
    + }  
    + }  
    + else {  
    + commandOutput.println("Not a dependency request!");  
    + }  
       
       
    + }  
    + catch (Throwable t) {  
    + t.printStackTrace(commandOutput);  
    + }</pre>  
       
    + = Parse Output of a Command and Create Report Containing Errors Found in it =  
    + ==== AHPSCRIPTS-20 ====  
    + <pre>import com.urbancode.anthill3.domain.singleton.serversettings.*;  
    + import com.urbancode.anthill3.domain.workflow.WorkflowCase ;  
    + import com.urbancode.vcsdriver3.*;  
    + import com.urbancode.anthill3.domain.buildlife.*;  
    + import com.urbancode.anthill3.domain.jobtrace.*;  
    + import com.urbancode.anthill3.domain.jobtrace.buildlife.*;  
    + import com.urbancode.anthill3.runtime.paths.*;  
    + import com.urbancode.anthill3.services.jobs.*;  
    + import com.urbancode.devilfish.services.var.VarService;  
    + import java.io.*;  
    + import java.util.*;  
       
    + private org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger("ContextScript");  
       
    + // SETTINGS  
    + // FOUND_TOKEN: indication of build failure  
    + // BUILD_STEP_NAME: Name of the step within the job that should be inspected  
    + // COMMAND_NAME: Command within the build step that should have its logged inspected  
    + // REPORT_NAME: Name of the report to publish.  
    + // LINES_BEFORE: Lines before and including the 'Found Token' to include in the log.  
    + // LINES_AFTER: Lines after the 'Found Token' to include in the log.  
       
    + String FOUND_TOKEN = "error";  
    + String BUILD_STEP_NAME = "Echo";  
    + String COMMAND_NAME = "shell-command";  
    + String REPORT_NAME = "Error Report";  
    + int LINES_BEFORE = 6;  
    + int LINES_AFTER = 1;  
       
    + //-------------------------------------------------------  
    + class LogSection {  
    + int lineNumber = 0;  
    + String text = null;  
       
    + LogSection(int lineNumber, String text) {  
    + this.lineNumber = lineNumber;  
    + this.text = text;  
    + }  
    + }  
       
    + //-------------------------------------------------------  
    + LogSection[] getLogSectionsForStep(StepTrace step) {  
    + CommandTrace[] cmdTraceArray = step.getCommandTraceArray();  
    + CommandTrace antCmdTrace = null;  
    + for (int i = 0; i < cmdTraceArray.length; i++) {  
    + if (cmdTraceArray[i].getName().equalsIgnoreCase(COMMAND_NAME)) {  
    + cmdTrace = cmdTraceArray[i];  
    + log.warn("Found the command we want: " + cmdTraceArray[i].getName());  
    + break;  
    + }  
    + }  
    + if (cmdTrace == null) {  
    + throw new Exception("Expected to find" + COMMAND_NAME + "command in " + BUILD_STEP_NAME + " step");  
    + }  
       
    + String commandOutput = LogHelper.getOutput(cmdTrace);  
    + List resultList = new LinkedList();  
    + String[] logCache = new String[LINES_BEFORE];  
    + if (commandOutput != null) {  
    + StringTokenizer logfile = new StringTokenizer(commandOutput,"\n\r\f");  
    + int index = 0;  
    + while (logfile.hasMoreTokens()) {  
    + String line = logfile.nextToken();  
    + logCache[index % LINES_BEFORE] = line;  
    + if (line.startsWith(FOUND_TOKEN)) {  
    + int lineNumber = index + 1;  
    + StringBuffer result = new StringBuffer();  
    + // put the cached lines into the log.  
    + int startIndex = (index > LINES_BEFORE) ? index - LINES_BEFORE + 1 : 0;  
    + for (int i = startIndex; i <= index; i++) {  
    + if (i == index) {  
    + result.append("<b>");  
    + }  
    + result.append(i + 1).append(": ").append(logCache[i % LINES_BEFORE]).append("\n");  
    + if (i == index) {  
    + result.append("</b>");  
    + }  
    + }  
    + // get lines after if applicable  
    + for (int i = 0; i < LINES_AFTER && logfile.hasMoreTokens(); i++) {  
    + String next = logfile.nextToken();  
    + index++;  
    + result.append(index + 1).append(": ").append(next).append("\n");  
    + }  
    + LogSection marker = new LogSection(lineNumber, result.toString());  
    + resultList.add(marker);  
    + }  
    + index++;  
    + }  
    + }  
    + return (LogSection[]) resultList.toArray(new LogSection[resultList.size()]);  
    + }  
       
    + //-------------------------------------------------------  
       
    + LogSection[] logSections = null;  
    + BuildLifeJobTrace jobTrace = JobTraceLookup.getCurrent();  
    + StepTrace[] stepTraceArray = jobTrace.getStepTraceArray();  
    + StepTrace stepTrace = null;  
    + for (int j = 0; j < stepTraceArray.length && stepTrace == null; j++) {  
    + if (stepTraceArray[j].getName().equalsIgnoreCase(BUILD_STEP_NAME)) {  
    + stepTrace = stepTraceArray[j];  
    + logSections = getLogSectionsForStep(stepTrace);  
    + }  
    + }  
       
    + String reportPath = PublishPathHelper.getInstance().getPublishPath(JobTraceLookup.getCurrent(), REPORT_NAME);  
    + VarService vs = VarService.getInstance();  
    + reportPath = vs.resolve(reportPath);  
       
    + File reportDir = new File(reportPath);  
    + reportDir.mkdirs();  
       
    + File reportFile = new File(reportDir, "Error_Report.html");  
    + FileWriter writer = new FileWriter(reportFile);  
    + writer.write("<html><head><style>");  
    + writer.write(".errors {");  
    + writer.write(" border: 1px solid #f04040;");  
    + writer.write(" background-color: #ffa0a0;");  
    + writer.write(" font-family: arial, helvetica, sans-serif;");  
    + writer.write(" font-size: 11px;");  
    + writer.write(" color: #000000;");  
    + writer.write("}");  
    + writer.write(".errors_header {");  
    + writer.write(" border-bottom: 1px solid #f04040;");  
    + writer.write(" background-color: #f04040;");  
    + writer.write(" font-size: 12px;");  
    + writer.write(" font-weight: bold;");  
    + writer.write(" color: #FFFFFF;");  
    + writer.write(" padding: 4px;");  
    + writer.write("}");  
    + writer.write(".errors_body {");  
    + writer.write(" margin-right: 10px;");  
    + writer.write(" padding-top: 4px;");  
    + writer.write(" padding-left: 4px;");  
    + writer.write(" padding-bottom: 4px;");  
    + writer.write("}");  
    + writer.write(".errors_section {");  
    + writer.write(" margin-left: 15px;");  
    + writer.write(" padding-top: 4px;");  
    + writer.write(" padding-left: 4px;");  
    + writer.write(" padding-bottom: 4px;");  
    + writer.write("}");  
    + writer.write(".errors_output {");  
    + writer.write(" margin-top: 4px;");  
    + writer.write(" margin-left: 15px;");  
    + writer.write(" background-color: #FFFFFF;");  
    + writer.write(" padding-top: 4px;");  
    + writer.write(" padding-left: 4px;");  
    + writer.write(" padding-bottom: 4px;");  
    + writer.write("}");  
       
    + writer.write("</style></head><body>");  
    + writer.write("<div class=\"errors\">");  
    + writer.write("<div class=\"errors_header\">Errors:</div>");  
    + writer.write("<div class=\"errors_body\">");  
    + writer.write("<div class=\"errors_section\">");  
    + writer.write("<b>Step " + (stepTrace.getSeq() + 1) + ": " + stepTrace.getName() + " Failed</b>");  
    + for (int i=0; i<logSections.length; i++) {  
    + writer.write("<ppre class=\"errors_output\">");  
    + writer.write(logSections[i].text);  
    + writer.write("</ppre>");  
    + }  
    + writer.write("</div>");  
    + writer.write("</div>");  
    + writer.write("</div>");  
    + writer.write("</body></html>");  
    + writer.close();</pre>  
       
    + = Parse SVN Revision Number from Checkout Output =  
    + ==== AHPSCRIPTS-66 ====  
    + <pre>// looking for "Checked out revision 19642."  
    + stepName = "Populate Workspace";  
    + revisionStart = "Checked out revision ";  
    + revisionEnd = ".";  
       
    + latestRevision = 0;  
       
    + jobTrace = JobTraceLookup.getCurrent();  
    + steps = jobTrace.getStepTraceArray();  
    + step = null;  
    + for (int s=0; s<steps.length; s++) {  
    + if (stepName.equals(steps[s].getName())) {  
    + step = steps[s];  
    + break;  
    + }  
    + }  
    + commands = step.getCommandTraceArray();  
    + for (int c=0; c<commands.length; c++) {  
    + if (commands[c].getName().startsWith("populate-workspace")) {  
    + log = LogHelper.getOutput(commands[c]);  
    + start = log.lastIndexOf(revisionStart);  
    + if (start < 0) {  
    + commandOutput.println("Revision not found in " + commands[c].getName());  
    + }  
    + else {  
    + start += revisionStart.length();  
    + log = log.substring(start);  
    + end = log.indexOf(revisionEnd);  
    + if (end < 0) {  
    + commandOutput.println("Revision not found in " + commands[c].getName());  
    + }  
    + else {  
    + rev = Long.parseLong(log.substring(0, end).trim());  
    +  
    + if (rev > latestRevision) {  
    + latestRevision = rev;  
    + }  
    + }  
    + }  
    + }  
    + }  
       
    + if (latestRevision > 0) {  
    + BuildRequestLookup.getCurrent().setProperty("svn.revision", String.valueOf(latestRevision));  
    + commandOutput.println("Found revision " + latestRevision);  
    + }  
    + else {  
    + commandOutput.println("Revision not found in " + jobTrace.getName());  
    + }  
    + </pre>  
       
    + = Properties Contained Within Variables =  
       
    + Script Notes:  
    + * The idea here is that the user has identified a couple agent items (a Track and technology type) that span environments. This scirpt filters agents so that the technology type must always match the technology type specified on the workflow property. The tracks are similar but some agents may participate in mulitple tracks (prod is that same for all) so prod would have a track value of something like 1|2|3 to indicate that it supports tracks 1, 2 and 3. So we need to inspect it to see if any match.  
    + * I changed the Track one to just see if the agent value contains the requested value. It should work fine until you get up to track 10, then you have to do 01, 02, etc.  
       
    + ==== AHPSCRIPTS-2 ====  
       
    + <pre>import com.urbancode.anthill3.domain.agent.Agent;  
    + import com.urbancode.anthill3.runtime.scripting.helpers.* ;  
    + import com.urbancode.anthill3.services.agent.AgentRemoteControl;  
    + import com.urbancode.devilfish.services.var.VarServiceClient;  
    + import java.util.*;  
       
    + public class PropertyBasedAgentVarEqualsCriteria extends VariableEqualsCriteria {  
       
    + String propertyname;  
       
    + public PropertyBasedAgentVarEqualsCriteria(String propertyname, String varName) {  
    + super(varName);  
    + this.propertyname = propertyname;  
    + }  
       
    + public Agent[] filter(Agent[] agents) {  
    + String value = PropertyLookup.get(propertyname);  
    + if (value == null || value.length() == 0 || "null".equals(value)) {  
    + value = BuildLifeLookup.getCurrent().getOriginatingWorkflow().getRequest().getProperty(propertyname);  
    + }  
    + this.setValue(value);  
    + return super.filter(agents);  
    + }  
    + }  
       
    + public class PropertyBasedAgentVarContainsCriteria extends Criteria {  
       
    + String propertyname;  
    + String varName;  
       
    + public PropertyBasedAgentVarContainsCriteria(String propertyname, String varName) {  
    + this.propertyname = propertyname;  
    + this.varName = varName;  
    + }  
       
    + public Agent[] filter(Agent[] agents) {  
    + ArrayList resultList = new ArrayList();  
    +  
    + String value = PropertyLookup.get(propertyname);  
    + if (value == null || value.length() == 0 || "null".equals(value)) {  
    + value = BuildLifeLookup.getCurrent().getOriginatingWorkflow().getRequest().getProperty(propertyname);  
    + }  
    +  
    + for (int i = 0; i < agents.length; i++) {  
    + Agent agent = agents[i];  
    +  
    + AgentRemoteControl remote = new AgentRemoteControl(agent);  
    + VarServiceClient client;  
    + try {  
    + client = remote.getVarServiceClient();  
       
    + String varValue = client.getVarValue(varName);  
    + if (varValue != null && varValue.contains(value)) {  
    + resultList.add(agent);  
    + }  
    + }  
    + catch (Exception e) {  
    + throw new RuntimeException(e);  
    + }  
    + }  
    +  
    + Agent[] result = new Agent[resultList.size()];  
    + resultList.toArray(result);  
    + return result;  
    + }  
    + }  
       
       
    + /**** Start Script *****/  
    + return Where.all(  
    + new PropertyBasedAgentVarContainsCriteria("Track", "Track"),  
    + new PropertyBasedAgentVarEqualsCriteria("TechType", "TechType")  
    + );</pre>  
       
    + = Publish Output of Step Command in File in Report =  
       
    + ==== AHPSCRIPTS-111 ====  
    + <pre>import com.urbancode.anthill3.domain.jobtrace.*;  
    + import com.urbancode.anthill3.domain.workflow.*;  
    + import com.urbancode.anthill3.runtime.paths.*;  
    + import com.urbancode.anthill3.services.file.*;  
    + import com.urbancode.devilfish.services.file.FileInfo;  
    + import com.urbancode.devilfish.services.var.VarService;  
    + import java.io.*;  
       
    + private String getStreamAsString(InputStream inStream)  
    + throws IOException {  
    + StringBuffer result = new StringBuffer();  
    + try {  
    + byte[] buffer = new byte[4096];  
    + int length = 0;  
    + while ((length = inStream.read(buffer)) > 0) {  
    + result.append(new String(buffer, 0, length));  
    + }  
    + }  
    + finally {  
    + try {  
    + inStream.close();  
    + }  
    + catch (Exception e) {}  
    + }  
    + return result.toString();  
    + }  
       
       
    + String REPORT_NAME = "DB Log";  
    + String REPORT_FILE = "Database_Log.txt";  
    + String STEP_NAME = "Execute Database Patches"; // change to the name of the step  
       
    + JobTrace jobTrace = JobTraceLookup.getCurrent();  
       
    + StepTrace[] stepTraces = jobTrace.getStepTraceArray();  
    + for (int s=0; s<stepTraces.length; s++) {  
    + if (STEP_NAME.equals(stepTraces[s].getName())) {  
    + // found the step  
    + CommandTrace cmdTrace = stepTraces[s].getCommandTraceArray()[0];  
    + FileInfo outputFile = LogPathHelper.getInstance().getLogFileInfoArray(cmdTrace)[0];  
    + InputStream inStream = FileInfoService.getInstance().getFileInfoAsStream(outputFile);  
    + String output = getStreamAsString(inStream);  
    +  
    + // create a report  
    + String reportPath = PublishPathHelper.getInstance().getPublishPath(JobTraceLookup.getCurrent(), REPORT_NAME);  
    + VarService vs = VarService.getInstance();  
    + reportPath = vs.resolve(reportPath);  
    +  
    + File reportDir = new File(reportPath);  
    + reportDir.mkdirs();  
    +  
    + File reportFile = new File(reportDir, REPORT_FILE);  
    + FileWriter writer = new FileWriter(reportFile);  
    + writer.write(output);  
    + writer.close();  
    +  
    + break;  
    + }  
    + }</pre>  
    +  
    + = Put the Output of a Step in an E-Mail =  
       
    + ==== AHPSCRIPTS-103 ====  
    + <pre>import com.urbancode.anthill3.domain.jobtrace.*;  
    + import com.urbancode.anthill3.domain.workflow.*;  
    + import com.urbancode.anthill3.runtime.paths.*;  
    + import com.urbancode.anthill3.services.file.*;  
    + import com.urbancode.devilfish.services.file.FileInfo;  
    + import java.io.*;  
       
    + private String getStreamAsString(InputStream inStream)  
    + throws IOException {  
    + StringBuffer result = new StringBuffer();  
    + try {  
    + byte[] buffer = new byte[4096];  
    + int length = 0;  
    + while ((length = inStream.read(buffer)) > 0) {  
    + result.append(new String(buffer, 0, length));  
    + }  
    + }  
    + finally {  
    + try {  
    + inStream.close();  
    + }  
    + catch (Exception e) {}  
    + }  
    + return result.toString();  
    + }  
       
       
    + String STEP_NAME = "ant-build"; // change to the name of the step  
       
    + WorkflowCase workflow = (WorkflowCase) context.get("workflow");  
    + JobTrace[] jobTraceArray = workflow.getJobTraceArray();  
       
    + // find the job trace you want in some meaningful way (this uses the first)  
    + JobTrace jobTrace = jobTraceArray[0];  
       
    + StepTrace[] stepTraces = jobTrace.getStepTraceArray();  
    + for (int s=0; s<stepTraces.length; s++) {  
    + if (STEP_NAME.equals(stepTraces[s].getName())) {  
    + // this is the step  
    + CommandTrace cmdTrace = stepTraces[s].getCommandTraceArray()[0];  
    + FileInfo outputFile = LogPathHelper.getInstance().getLogFileInfoArray(cmdTrace)[0];  
    + InputStream inStream = FileInfoService.getInstance().getFileInfoAsStream(outputFile);  
    + context.put("ant-output", getStreamAsString(inStream));  
    + break;  
    + }  
    + }</pre>  
       
    + = Replicate Permissions of One Role to Another =  
    + ==== AHPSCRIPTS-133 ====  
    + <pre>import com.urbancode.anthill3.domain.security.Permission;  
    + import com.urbancode.anthill3.domain.security.PermissionFactory;  
    + import com.urbancode.anthill3.domain.security.Resource;  
    + import com.urbancode.anthill3.domain.security.ResourceType;  
    + import com.urbancode.anthill3.domain.security.ResourceTypeFactory;  
    + import com.urbancode.anthill3.domain.security.Role;  
    + import com.urbancode.anthill3.domain.security.RoleFactory;  
    + import com.urbancode.anthill3.persistence.UnitOfWork;  
    + import java.util.*;  
       
    + /*  
    + Beanshell script to be run in a Evaluate Script Step.  
    + This script will repliact permission from one role to another.  
    + - Adjust the role names for your use before running.  
    + - Adjust the resource types at the bottom to control the types of permissions replicate.  
    + */  
    +  
    + addPermissionToMap(HashMap map, Permission permission) {  
    + resource = permission.getResource();  
    + actions = map.get(resource);  
    + if (actions == null) {  
    + actions = new HashSet();  
    + map.put(resource, actions);  
    + }  
    + actions.add(permission.getAction());  
    + }  
       
    + copyResourceTypePermissions(Role source, Role dest, long resourceTypeId) {  
    + resourceType = ResourceTypeFactory.getInstance().restore(resourceTypeId);  
    +  
    + permissions = PermissionFactory.getInstance().restoreAllForResourceType(resourceType);  
    +  
    + sourceMap = new HashMap();  
    + destMap = new HashMap();  
    +  
    + for (Permission permission : permissions) {  
    + if (source.equals(permission.getRole())) {  
    + addPermissionToMap(sourceMap, permission);  
    + }  
    + else if (dest.equals(permission.getRole())) {  
    + addPermissionToMap(destMap, permission);  
    + }  
    + }  
    +  
    + for (Resource resource : sourceMap.keySet()) {  
    + sourceActions = sourceMap.get(resource);  
    + destActions = destMap.get(resource);  
    +  
    + if (destActions != null) {  
    + sourceActions.removeAll(destActions);  
    + }  
    +  
    + for (String action : sourceActions) {  
    + // create the permission  
    + commandOutput.println("Adding " + action + " to " + resource);  
    + Permission permission = new Permission(resource, action, dest);  
    + permission.store();  
    + }  
    + }  
    + }  
       
    + source = RoleFactory.getInstance().restoreForName("Source");  
    + dest = RoleFactory.getInstance().restoreForName("Destination");  
       
    + copyResourceTypePermissions(source, dest, ResourceType.TYPE_PROJECT);  
    + copyResourceTypePermissions(source, dest, ResourceType.TYPE_ENVIRONMENT);  
    + copyResourceTypePermissions(source, dest, ResourceType.TYPE_WORKFLOW);  
    + copyResourceTypePermissions(source, dest, ResourceType.TYPE_CODESTATON);  
    + copyResourceTypePermissions(source, dest, ResourceType.TYPE_REPOSITORY);  
    + copyResourceTypePermissions(source, dest, ResourceType.TYPE_FOLDER);  
    + copyResourceTypePermissions(source, dest, ResourceType.TYPE_LIBRARY_WORKFLOW);  
    + copyResourceTypePermissions(source, dest, ResourceType.TYPE_LIBRARY_JOB);  
    + copyResourceTypePermissions(source, dest, ResourceType.TYPE_AGENT);  
    + copyResourceTypePermissions(source, dest, ResourceType.TYPE_ENV_GROUP);  
       
    + UnitOfWork.getCurrent().commit();</pre>  
    +  
    + = Retrieve Stamp From Dependent Project so it is Passed as Property =  
       
    + * This script assumes that some Project A, is dependent on some Project B. This script would be placed in an Evaluate Script Step, on a Generic Build Job. The script, looks up the most recent stamp value for Project B, and then saves the stamp as a BuildRequest Property. This allows the property to be passed/referenced by using the format  
    + ** ${property: stampValue}  
       
    + ==== AHPSCRIPTS-15 ====  
    + <pre>import com.urbancode.anthill3.domain.buildlife.*;  
    + import com.urbancode.anthill3.runtime.scripting.helpers.*;  
    + import com.urbancode.codestation2.domain.buildlife.CodestationCompatableBuildLife ;  
    + import com.urbancode.codestation2.domain.project.*;  
    + import java.util.ArrayList ;  
    + import java.lang.Object;  
    + import com.urbancode.anthill3.persistence.UnitOfWork;  
    + import com.urbancode.anthill3.domain.buildrequest.BuildRequestStatusEnum;  
    + import com.urbancode.anthill3.domain.buildrequest.RequestSourceEnum ;  
    + import com.urbancode.anthill3.domain.persistent.Handle;  
    + import com.urbancode.anthill3.domain.persistent.Persistent;  
    + import com.urbancode.anthill3.domain.buildrequest.*;  
    + UnitOfWork uow = UnitOfWork.getCurrent ();  
    + static final String PROJECT_NAME = "Project B";  
       
    + //Get most current buildlife.  
    + BuildLife blife = BuildLifeLookup.getCurrent();  
    + BuildRequest br = BuildRequestLookup.getCurrent();  
    + //Get dependency Array  
    + CodestationCompatableBuildLife[] dArray =blife.getDependencyBuildLifeArray();  
       
    + String stamp = null;  
    + for (int i = 0; i < dArray.length && stamp == null; i++) {  
    + if (dArray[i].getCodestationProject() != null &&  
    + dArray[i].getCodestationProject() instanceof AnthillProject) {  
    + AnthillProject project = (AnthillProject)  
    + dArray[i].getCodestationProject();  
    + String temp = project.getBuildProfile ().getProject().getName();  
    + if (temp.equals(PROJECT_NAME)){  
    + stamp = dArray[i].getLatestStampValue();  
    + }  
    + }  
       
    + }  
    + br.setProperty("Stamp_Value", stamp);  
    + uow.commit();</pre>