package org.jenkinsci.plugins.p4.changes; import com.perforce.p4java.core.IChangelistSummary; import com.perforce.p4java.core.IFix; import com.perforce.p4java.core.file.FileAction; import com.perforce.p4java.exception.P4JavaException; import com.perforce.p4java.impl.generic.core.Fix; import hudson.model.Run; import hudson.scm.ChangeLogParser; import hudson.scm.ChangeLogSet; import hudson.scm.ChangeLogSet.Entry; import hudson.scm.RepositoryBrowser; import org.jenkinsci.plugins.p4.browsers.SwarmBrowser; import org.jenkinsci.plugins.p4.client.ConnectionHelper; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.ArrayList; import java.util.List; import java.util.Stack; /** * Uses the "index.jelly" view to render the changelist details and use the * "digest.jelly" view of to render the summary page. */ public class P4ChangeParser extends ChangeLogParser { private final String credential; public P4ChangeParser(String credential) { this.credential = credential; } @SuppressWarnings("rawtypes") @Override public ChangeLogSet<? extends Entry> parse(Run run, RepositoryBrowser<?> browser, File file) throws IOException, SAXException { try { SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); ChangeLogHandler handler = new ChangeLogHandler(run, browser, credential); 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 Run<?, ?> run; private RepositoryBrowser<?> browser; private ConnectionHelper p4; public ChangeLogHandler(Run<?, ?> run, RepositoryBrowser<?> browser, String credential) throws P4JavaException { this.run = run; this.browser = browser; this.p4 = new ConnectionHelper(run, credential, null); if (browser == null) { this.browser = new SwarmBrowser(p4.getSwarm()); } } @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(run, browser, 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")) { // URL decode depot path String safePath = attributes.getValue("depot"); String depotPath = URLDecoder.decode(safePath, "UTF-8"); String a = attributes.getValue("action"); FileAction action = FileAction.fromString(a); String strRev = attributes.getValue("endRevision"); P4AffectedFile file = new P4AffectedFile(depotPath, strRev, action); entry.addAffectedFiles(file); ///entry.files.add(temp); text.setLength(0); return; } if (qName.equalsIgnoreCase("job")) { IFix temp = new Fix(); String id = attributes.getValue("id"); temp.setJobId(id); String status = attributes.getValue("status"); temp.setStatus(status); entry.addJob(temp); text.setLength(0); return; } } catch (UnsupportedEncodingException 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") || qName.equalsIgnoreCase("commit"))) { // Add changelist to entry if (qName.equalsIgnoreCase("changenumber")) { int id = Integer.parseInt(text.toString()); IChangelistSummary summary = p4.getChangeSummary(id); entry.setChange(p4, summary); } // Add label to entry if (qName.equalsIgnoreCase("label")) { String id = text.toString(); entry.setLabel(p4, id); } // Add Commit to entry if (qName.equalsIgnoreCase("commit")) { String id = text.toString(); entry.setGraphCommit(p4, id); } // disconnect from Perforce p4.disconnect(); } else { String elementText = text.toString().trim(); if (qName.equalsIgnoreCase("changeInfo")) { if (elementText.contains("@")) { entry.setId(new P4GraphRef(p4, elementText)); text.setLength(0); return; } else { int id = Integer.parseInt(elementText); entry.setId(new P4ChangeRef(id)); text.setLength(0); return; } } if (qName.equalsIgnoreCase("shelved")) { entry.setShelved(elementText.equals("true")); text.setLength(0); return; } if (qName.equalsIgnoreCase("msg")) { entry.setMsg(elementText); text.setLength(0); return; } 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 | |
---|---|---|---|---|---|
#21 | 29673 | Sandeep Kumar |
Merge pull request #188 from jenkinsci/CodeRefactoring Code Cleanup |
||
#20 | 28784 | Paul Allen |
Merge pull request #140 from jorgenpt/fix-file-limit-not-persisting Persist `fileLimit` when serializing a changeset |
||
#19 | 24938 | Paul Allen |
Prevent XML parse errors from failing the build. Jelly page is called while the changelist is being built. Log the error and return an empty list of changes. JENKINS-53030 |
||
#18 | 24937 | Paul Allen |
Merge pull request #84 from p4charu/jenkinsci-master Added help text for Include and Fixed incorrect images. JENKINS-54584 |
||
#17 | 24487 | Paul Allen | Perforce Connection Refactor. | ||
#16 | 23478 | Paul Allen |
Merge pull request #65 from PhRX/jenkins-44845 JENKINS-48845 : Backward compatibility for pre-swarm P4 releases |
||
#15 | 22970 | Paul Allen |
Merge pull request #57 from jfperusse-bhvr/fix-changelog-errors Fix changelog issues caused by NullPointerException in getSwarm JENKINS-47336 |
||
#14 | 22856 | Paul Allen |
Remove guessBrowser() and lookup browser when used. guessBrowser() gets called a lot and each lookup opens a Perforce connection. JENKINS-46810 |
||
#13 | 22128 | Paul Allen |
Helix Graph support for Jenkins. JENKINS-40354 |
||
#12 | 21794 | Paul Allen |
Merge pull request #39 from Dohbedoh/JENKINS-34825 Jenkins 34825 |
||
#11 | 19581 | Paul Allen | Minor fixes to satisfy FindBugs Analysis. | ||
#10 | 16409 | Paul Allen |
Use Fix records for Job information. 'p4 fixes' is lighter and still provides enough useful data. Includes jelly fix and extra job data in changelog.xml. |
||
#9 | 16390 | Paul Allen |
Update change/file reporting. Use `p4 changes @=1234` to get change summary and `p4 files -m50 @=1234` to get limited file list. |
||
#8 | 15750 | Paul Allen |
Use a P4Revision object and not int/String as Object. In sure that there is no ambiguity with the revision specifier. Should fix change summary when using the Workflow plugin. JENKINS-30425 |
||
#7 | 14150 | Paul Allen |
URL Encode/Decode the depot path for changes. Filenames with ampersands was causing Jelly to break when showing the change detail. JENKINS-29017 |
||
#6 | 11626 | Paul Allen |
Workflow support. - Updated the plugin to the latest LTS Jenkins release 1.580.3. - Updated P4Java to 2014.1 Tested with simple ‘static’ workspace, there may be limitations with ‘manual’ workspace. Plan to add DSL support by extending the SCMStep class. #review-11537 JENKINS-24206 |
||
#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 |