package org.jenkinsci.plugins.p4.changes; import com.perforce.p4java.core.file.FileAction; import com.perforce.p4java.core.file.IFileSpec; import com.perforce.p4java.impl.generic.core.file.FileSpec; import hudson.model.AbstractBuild; import hudson.model.AbstractProject; import hudson.model.User; import hudson.scm.ChangeLogParser; import hudson.scm.ChangeLogSet; import hudson.scm.ChangeLogSet.Entry; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Stack; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.jenkinsci.plugins.p4.PerforceScm; import org.jenkinsci.plugins.p4.client.ConnectionHelper; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class P4ChangeParser extends ChangeLogParser { /** * Uses the "index.jelly" view to render the changelist details and use the * "digest.jelly" view of to render the summary page. */ @SuppressWarnings("rawtypes") @Override public ChangeLogSet<? extends Entry> parse(AbstractBuild build, File file) throws IOException, SAXException { try { SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); ChangeLogHandler handler = new ChangeLogHandler(build); parser.parse(file, handler); P4ChangeSet changeSet = handler.getChangeLogSet(); return changeSet; } catch (Exception e) { throw new SAXException("Could not parse perforce changelog: ", e); } } public static class ChangeLogHandler extends DefaultHandler { private Stack<P4ChangeEntry> objects = new Stack<P4ChangeEntry>(); private StringBuffer text = new StringBuffer(); private List<P4ChangeEntry> changeEntries; private P4ChangeSet changeSet; private AbstractBuild<?, ?> build; public ChangeLogHandler(AbstractBuild<?, ?> build) { this.build = build; } @Override public void characters(char[] ch, int start, int length) throws SAXException { text.append(ch, start, length); } @Override public void startDocument() throws SAXException { changeEntries = new ArrayList<P4ChangeEntry>(); changeSet = new P4ChangeSet(build, changeEntries); } @Override public void endDocument() throws SAXException { } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (qName.equalsIgnoreCase("changelog")) { // this is the root, so don't do anything text.setLength(0); return; } if (qName.equalsIgnoreCase("entry")) { objects.push(new P4ChangeEntry(changeSet)); text.setLength(0); return; } if (objects.peek() instanceof P4ChangeEntry) { P4ChangeEntry entry = (P4ChangeEntry) objects.peek(); try { if (qName.equalsIgnoreCase("file")) { IFileSpec temp = new FileSpec(); temp.setDepotPath(attributes.getValue("depot")); temp.setAction(FileAction.fromString(attributes .getValue("action"))); int endRevision = new Integer( attributes.getValue("endRevision")); temp.setEndRevision(endRevision); entry.files.add(temp); text.setLength(0); return; } } catch (Exception e) { entry = null; } } text.setLength(0); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if (qName.equalsIgnoreCase("changelog")) { // this is the root, so don't do anything return; } if (qName.equalsIgnoreCase("entry")) { P4ChangeEntry entry = (P4ChangeEntry) objects.pop(); changeEntries.add(entry); return; } // if we are in the entry element if (objects.peek() instanceof P4ChangeEntry) { P4ChangeEntry entry = (P4ChangeEntry) objects.peek(); try { if (text.toString().trim().length() != 0 && (qName.equalsIgnoreCase("changenumber") || qName .equalsIgnoreCase("label"))) { // Find Credential ID and Workspace for this build AbstractProject<?, ?> project = build.getProject(); PerforceScm scm = (PerforceScm) project.getScm(); String credential = scm.getCredential(); // Log in to Perforce and find change-list ConnectionHelper p4 = new ConnectionHelper(credential, null); // Add changelist to entry if (qName.equalsIgnoreCase("changenumber")) { int id = new Integer(text.toString()); entry.setChange(p4, id); } // Add label to entry if (qName.equalsIgnoreCase("label")) { String id = text.toString(); entry.setLabel(p4, id); } // disconnect from Perforce p4.disconnect(); } else { String elementText = text.toString().trim(); if (qName.equalsIgnoreCase("changeInfo")) { int id = new Integer(elementText); entry.setId(id); text.setLength(0); return; } if (qName.equalsIgnoreCase("shelved")) { entry.setShelved(elementText.equals("true")); text.setLength(0); } if (qName.equalsIgnoreCase("msg")) { entry.setMsg(elementText); text.setLength(0); } if (qName.equalsIgnoreCase("clientId")) { entry.setClientId(elementText); text.setLength(0); return; } if (qName.equalsIgnoreCase("changeUser")) { entry.setAuthor(elementText); text.setLength(0); return; } if (qName.equalsIgnoreCase("changeTime")) { entry.setDate(elementText); text.setLength(0); return; } } text.setLength(0); return; } catch (Exception e) { entry = null; } } } public P4ChangeSet getChangeLogSet() { return changeSet; } } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 11628 | Paul Allen | Branching using p4-jenkins-R1.1 | ||
//guest/perforce_software/p4jenkins/main/src/main/java/org/jenkinsci/plugins/p4/changes/P4ChangeParser.java | |||||
#5 | 11084 | Paul Allen |
(mjoubert) Fully populate changelog.xml Replaces sparse change log which only recorded the change number. The change is now recorded in full allowing faster page load times. The number of files listed in the change is limited to 50; to view larger changes please add a repo browser such as Swarm, Fisheye, P4Web, etc… |
||
#4 | 10201 | Paul Allen | Fix page loading error with no connection to P4 | ||
#3 | 9803 | Paul Allen | Merging using p4-jenkins | ||
#2 | 9738 | Paul Allen | Merging using p4-jenkins | ||
#1 | 9690 | Paul Allen |
[Branching using p4-jenkins] Release 1.0.1 |
||
//guest/paul_allen/dev/p4-jenkins/p4-client/src/main/java/org/jenkinsci/plugins/p4/changes/P4ChangeParser.java | |||||
#1 | 9672 | Paul Allen | Refactor name from 'p4_client' to 'p4'. | ||
//guest/paul_allen/dev/p4-jenkins/p4-client/src/main/java/org/jenkinsci/plugins/p4_client/changes/P4ChangeParser.java | |||||
#3 | 9055 | Paul Allen |
Label support. Build at a label using the pram 'label'. This includes adding the label to the ChangeEntry, building the change reports and Browser links to Swarm. (TPI-102) |
||
#2 | 8940 | Paul Allen |
Major refactor for the ConnectionHelper class to simplify serialisation. Fixed remote Jenkins JNLP slave connection issue. ClientHelper now extends ConnectionHelper and takes on all methods that require a client workspace. P4StandardCredentials is sent to the remote node instead of Credentials ID due to an issue accessing the Credentials store over a remote connection. For simplicity Client ID (workspace name) is serialised instead of the Workspace object. |
||
#1 | 8915 | Paul Allen |
Support for ChangeLog and RepoBrowser. - Added RepoBrowser for Swarm (porting the others should be easy) - ChangeLog XML file now only stores the changelist number all other information is fetched from Perforce |