package org.jenkinsci.plugins.p4.changes; import com.perforce.p4java.core.ChangelistStatus; import com.perforce.p4java.core.IChangelistSummary; import com.perforce.p4java.core.IFix; import com.perforce.p4java.core.file.FileAction; import com.perforce.p4java.core.file.IFileSpec; import com.perforce.p4java.graph.IGraphCommitLog; import com.perforce.p4java.impl.generic.core.Label; import hudson.model.Descriptor; import hudson.model.User; import hudson.scm.ChangeLogSet; import hudson.tasks.Mailer.UserProperty; import jenkins.model.Jenkins; import org.jenkinsci.plugins.p4.PerforceScm; import org.jenkinsci.plugins.p4.client.ConnectionHelper; import org.jenkinsci.plugins.p4.email.P4UserProperty; import org.kohsuke.stapler.export.Exported; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.logging.Logger; public class P4ChangeEntry extends ChangeLogSet.Entry { private static Logger logger = Logger.getLogger(P4ChangeEntry.class.getName()); private int FILE_COUNT_LIMIT = 50; private P4Ref id; private User author; private Date date = new Date(); private String clientId = ""; private String msg = ""; private Collection<String> affectedPaths; private Collection<P4AffectedFile> affectedFiles; private boolean shelved; private boolean fileLimit = false; public List<IFileSpec> files; public List<IFix> jobs; public P4ChangeEntry(P4ChangeSet parent) { super(); setParent(parent); files = new ArrayList<IFileSpec>(); jobs = new ArrayList<IFix>(); affectedPaths = new ArrayList<String>(); affectedFiles = new ArrayList<P4AffectedFile>(); Jenkins j = Jenkins.getInstance(); if (j != null) { Descriptor dsc = j.getDescriptor(PerforceScm.class); if (dsc instanceof PerforceScm.DescriptorImpl) { PerforceScm.DescriptorImpl p4scm = (PerforceScm.DescriptorImpl) dsc; FILE_COUNT_LIMIT = p4scm.getMaxFiles(); } } } public P4ChangeEntry() { } public void setChange(ConnectionHelper p4, IChangelistSummary changelist) throws Exception { // set id int changeId = changelist.getId(); id = new P4ChangeRef(changeId); // set author String user = changelist.getUsername(); author = User.get(user); // set email property on user String email = p4.getEmail(user); if (email != null && !email.isEmpty()) { P4UserProperty p4prop = new P4UserProperty(email); author.addProperty(p4prop); logger.fine("Setting email for user: " + user + ":" + email); // Set default email for Jenkins user if not defined UserProperty prop = author.getProperty(UserProperty.class); if (prop == null || prop.getAddress() == null || prop.getAddress().isEmpty()) { prop = new UserProperty(email); author.addProperty(prop); logger.fine("Setting default user: " + user + ":" + email); } } // set date of change date = changelist.getDate(); // set client id clientId = changelist.getClientId(); // set display message msg = changelist.getDescription(); // set list of file revisions in change if (changelist.getStatus() == ChangelistStatus.PENDING) { files = p4.getShelvedFiles(changeId); shelved = true; } else { files = p4.getChangeFiles(changeId); shelved = false; } if (files.size() > FILE_COUNT_LIMIT) { fileLimit = true; files = files.subList(0, FILE_COUNT_LIMIT); } // set list of affected paths/files affectedPaths = new ArrayList<String>(); affectedFiles = new ArrayList<P4AffectedFile>(); for (IFileSpec item : files) { affectedPaths.add(item.getDepotPathString()); affectedFiles.add(new P4AffectedFile(item)); } // set list of jobs in change this.jobs = p4.getJobs(changeId); } public void setLabel(ConnectionHelper p4, String labelId) throws Exception { Label label = (Label) p4.getLabel(labelId); // set id id = new P4LabelRef(labelId); // set author String user = label.getOwnerName(); user = (user != null && !user.isEmpty()) ? user : "unknown"; author = User.get(user); // set date of change date = label.getLastAccess(); // set client id clientId = labelId; // set display message msg = label.getDescription(); // set list of file revisions in change files = p4.getLabelFiles(labelId, FILE_COUNT_LIMIT + 1); if (files.size() > FILE_COUNT_LIMIT) { fileLimit = true; files = files.subList(0, FILE_COUNT_LIMIT); } // set list of affected paths affectedPaths = new ArrayList<String>(); for (IFileSpec item : files) { affectedPaths.add(item.getDepotPathString()); } } public void setGraphCommit(ConnectionHelper p4, String id) throws Exception { if (id == null || id.isEmpty() || !id.contains("@")) { return; } String[] parts = id.split("@"); if (parts.length != 3) { return; } String repo = parts[0]; String branch = parts[1]; String sha = parts[2]; IGraphCommitLog commit = p4.getGraphCommit(repo, sha); setGraphCommit(p4, repo, branch, commit); } public void setGraphCommit(ConnectionHelper p4, String repo, String branch, IGraphCommitLog commitLog) throws Exception { id = new P4GraphRef(repo, branch, commitLog); // set author String user = commitLog.getAuthor(); user = (user != null && !user.isEmpty()) ? user : "unknown"; author = User.get(user); // set date of change date = commitLog.getDate(); // set client id clientId = "graph"; // set display message msg = commitLog.getDescription(); // set list of affected paths affectedPaths = new ArrayList<String>(); String sha = commitLog.getCommit(); p4.getConnection().getGraphListTree(sha); // TODO } @Exported public String getChangeNumber() { return id.toString(); } @Exported public String getChangeTime() { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return sdf.format(date); } public P4Ref getId() { return id; } public void setId(P4Ref value) { id = value; } @Override public User getAuthor() { // JENKINS-31169 if (author == null) { return User.getUnknown(); } return author; } public void setAuthor(String value) { author = User.get(value); } public Date getDate() { return (Date) date.clone(); } public void setDate(String value) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { date = sdf.parse(value); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void setClientId(String value) { clientId = value; } public String getClientId() { return clientId; } @Override public String getMsg() { return msg; } public int getRows() { String[] lines = msg.split("\r\n|\r|\n"); int rows = lines.length; rows = (rows > 10) ? 10 : rows; return rows; } public void setMsg(String value) { msg = value; } @Override public Collection<String> getAffectedPaths() { // JENKINS-31306 if (affectedPaths.size() < 1 && files != null && files.size() > 0) { for (IFileSpec item : files) { affectedPaths.add(item.getDepotPathString()); } } return affectedPaths; } @Override public Collection<P4AffectedFile> getAffectedFiles() { if (affectedFiles.size() < 1 && files != null && files.size() > 0) { for (IFileSpec item : files) { affectedFiles.add(new P4AffectedFile(item)); } } return affectedFiles; } public boolean isFileLimit() { return fileLimit; } public List<IFileSpec> getFiles() { return files; } public String getAction(IFileSpec file) { FileAction action = file.getAction(); String s = action.name(); return s.replace("/", "_"); } public void setShelved(boolean value) { shelved = value; } public boolean isShelved() { return shelved; } public boolean isLabel() { return id.isLabel(); } public List<IFix> getJobs() { return jobs; } public String getJobStatus(IFix job) { String status = job.getStatus(); return status; } public int getMaxLimit() { return FILE_COUNT_LIMIT; } // For email-ext @Exported public long getTimestamp() { return getDate().getTime(); } // For email-ext @Exported public String getCommitId() { return getChangeNumber(); } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#8 | 22326 | Paul Allen | Merging down using p4-jenkins | ||
#7 | 22114 | Paul Allen |
Set max change limit for Graph commit. Increased default change limit to 20. |
||
#6 | 22013 | Paul Allen |
Add Graph Populate type. - Not able to use sync -p with graph - Don't store IClient; store SHA, repo and date |
||
#5 | 22000 | Paul Allen |
Use graph p4 describe to fetch committed files. Update P4Ds |
||
#4 | 21990 | Paul Allen |
Reporting Graph changes. Update Browser and Jelly code to use String and not URL for url in Data Binding to Jelly. Use P4AffectedFile object for XML storage and not IFileSpec to allow Graph use. |
||
#3 | 21978 | Paul Allen | Reporting Graph | ||
#2 | 21946 | Paul Allen |
Refactor P4Revision into interface (P4Ref). Implementing P4ChangeRef and P4LabelRev to split behaviour. |
||
#1 | 21940 | Paul Allen | Branching using p4-jenkins | ||
//guest/perforce_software/p4jenkins/main/src/main/java/org/jenkinsci/plugins/p4/changes/P4ChangeEntry.java | |||||
#28 | 21042 | Paul Allen |
Use `textarea` for change description (CSS: 10 rows max) JENKINS-39257 |
||
#27 | 20820 | Paul Allen | Find bug fix for null checking on Jenkins.getInstance() | ||
#26 | 20818 | Paul Allen |
Global limits for changes and files. Max number of change lists to show for a build (default 10) Max number of files to list in a change (default 50) |
||
#25 | 20207 | Paul Allen |
Added implementation for getAffectedFiles() #review-20131 |
||
#24 | 19878 | Paul Allen |
Export getTimestamp() and getCommitId() for email-ext. JENKINS-36409 |
||
#23 | 19581 | Paul Allen | Minor fixes to satisfy FindBugs Analysis. | ||
#22 | 18809 | Paul Allen |
Use p4 describe -s for listing files in a change. Previously used p4 files @=<change>, but without a client to limit view. |
||
#21 | 18550 | Paul Allen |
Add Perforce email address if Jenkins User is undefined. Other email plugins use P4UserProperty, but for if UserProperty is undefined update this one too. JENKINS-32879 |
||
#20 | 16516 | Paul Allen |
Use empty email "" for deleted users. JENKINS-31169 |
||
#19 | 16503 | Paul Allen |
If author is not set use unknown. JENKINS-31169 |
||
#18 | 16497 | Paul Allen |
Fix rest api for affectedPaths. JENKINS-31306 |
||
#17 | 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. |
||
#16 | 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. |
||
#15 | 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 |
||
#14 | 15746 | mjoubert |
JENKINS-30387 : Fix problem with saving hours in 12 hour format. #review @pallen |
||
#13 | 15503 | Paul Allen |
Created P4UserProperty to store Email address. P4UserProperty extends UserProperty to store the Perforce User’s email. Then retrieves it with P4AddressResolver by extending MailAddressResolver. JENKINS-28421 |
||
#12 | 15495 | Paul Allen |
Only set email if User's address in null or empty. JENKINS-28421 |
||
#11 | 15431 | Paul Allen |
Add Perforce User's email to Jenkins User property. JENKINS-28421 |
||
#10 | 15249 | Paul Allen |
Null protection if Label Owner is not set. Fall back to “unknown” for user. |
||
#9 | 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… |
||
#8 | 10939 | Paul Allen |
Tidy up changes. - Moved duration timings to ClientHelper and measure each task individually. - White space/formatting on P4ChangeEntry. - Temporarily backed-out p4-plugin.properties file (could damage builds - need to understand requirements) |
||
#7 | 10936 | Paul Allen |
(mjoubert) Pull request Add simple REST tags to match other plugin |
||
#6 | 10757 | Paul Allen |
More efficient listing of files. Listing files for the Change reporting used `p4 files //…@=<id>`, this now uses `p4 describe -s <id>` for changes and `p4 files //…@<id>` for labels. The `\\…@label` should be much more efficient as it only looks as the db.label table not db.rev. I can’t limit the scope to a workspace. Often the client name uses ${var}, which are not present at this point in the code. JENKINS-25303 |
||
#5 | 10668 | Matt Attaway | Adding a file to redirect JSAPI users to the new examples location | ||
#4 | 10201 | Paul Allen | Fix page loading error with no connection to P4 | ||
#3 | 9803 | Paul Allen | Merging using p4-jenkins | ||
#2 | 9769 | Paul Allen | Copying 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/P4ChangeEntry.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/P4ChangeEntry.java | |||||
#5 | 9127 | Paul Allen |
Added Browser support for P4Web. - Includes fix for move/add and move/delete icons when browsing change lists. |
||
#4 | 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) |
||
#3 | 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. |
||
#2 | 8916 | Paul Allen | Unit tests for ChangeLog feature and minor fix when listing files if the change is Submitted or Shelved. | ||
#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 |