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.ICommit; 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 fileCountLimit = PerforceScm.DEFAULT_FILE_LIMIT; private P4Ref id; private User author; private Date date = new Date(); private String clientId = ""; private String msg = ""; private List<P4AffectedFile> affectedFiles; private boolean shelved; private boolean fileLimit = false; private List<IFix> jobs; public P4ChangeEntry(P4ChangeSet parent) { super(); setParent(parent); jobs = new ArrayList<IFix>(); affectedFiles = new ArrayList<P4AffectedFile>(); getFileCountLimit(); } public P4ChangeEntry() { getFileCountLimit(); } 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 List<IFileSpec> files; if (changelist.getStatus() == ChangelistStatus.PENDING) { files = p4.getShelvedFiles(changeId); shelved = true; } else { files = p4.getChangeFiles(changeId, fileCountLimit + 1); shelved = false; } if (files != null && files.size() > fileCountLimit) { fileLimit = true; files = files.subList(0, fileCountLimit); } // set list of affected paths/files affectedFiles = new ArrayList<P4AffectedFile>(); if (files != null) { for (IFileSpec item : files) { 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 List<IFileSpec> files = p4.getLabelFiles(labelId, fileCountLimit + 1); if (files.size() > fileCountLimit) { fileLimit = true; files = files.subList(0, fileCountLimit); } // set list of affected files affectedFiles = new ArrayList<P4AffectedFile>(); for (IFileSpec item : files) { affectedFiles.add(new P4AffectedFile(item)); } } public void setGraphCommit(ConnectionHelper p4, String id) throws Exception { if (id == null || id.isEmpty() || !id.contains("@")) { return; } String[] parts = id.split("@"); if (parts.length != 2) { return; } String repo = parts[0]; String sha = parts[1]; setGraphCommit(p4, repo, sha); } public void setGraphCommit(ConnectionHelper p4, String repo, String sha) throws Exception { ICommit commit = p4.getGraphCommit(sha, repo); id = new P4GraphRef(repo, commit); // set author String user = commit.getAuthor(); user = (user != null && !user.isEmpty()) ? user : "unknown"; author = User.get(user); // set date of change date = commit.getDate(); // set client id clientId = commit.getAuthorEmail(); // set display message msg = commit.getDescription(); // set list of affected paths affectedFiles = new ArrayList<>(); List<IFileSpec> graphFiles = p4.getCommitFiles(repo, sha); for (IFileSpec item : graphFiles) { String path = item.getDepotPathString(); FileAction action = item.getAction(); affectedFiles.add(new P4AffectedFile(path, sha, action)); } if (affectedFiles.size() > fileCountLimit) { fileLimit = true; affectedFiles = affectedFiles.subList(0, fileCountLimit); } } @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; } // JENKINS-31306 @Override public Collection<String> getAffectedPaths() { Collection<String> affectedPaths = new ArrayList<String>(); for (P4AffectedFile item : getAffectedFiles()) { affectedPaths.add(item.getPath()); } return affectedPaths; } @Override public Collection<P4AffectedFile> getAffectedFiles() { return affectedFiles; } public void addAffectedFiles(P4AffectedFile file) { affectedFiles.add(file); } public boolean isFileLimit() { return fileLimit; } 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 void addJob(IFix job) { jobs.add(job); } public String getJobStatus(IFix job) { String status = job.getStatus(); return status; } public int getMaxLimit() { return fileCountLimit; } // For email-ext @Exported public long getTimestamp() { return getDate().getTime(); } // For email-ext @Exported public String getCommitId() { return getChangeNumber(); } private int getFileCountLimit() { Jenkins j = Jenkins.getInstance(); if (j != null) { Descriptor dsc = j.getDescriptor(PerforceScm.class); if (dsc instanceof PerforceScm.DescriptorImpl) { PerforceScm.DescriptorImpl p4scm = (PerforceScm.DescriptorImpl) dsc; fileCountLimit = p4scm.getMaxFiles(); } } return fileCountLimit; } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#34 | 28784 | Paul Allen |
Merge pull request #140 from jorgenpt/fix-file-limit-not-persisting Persist `fileLimit` when serializing a changeset |
||
#33 | 23645 | Paul Allen |
Use DEFAULT_FILE_LIMIT if max file limit is set to 0. JENKINS-49633 |
||
#32 | 23590 | Paul Allen |
Fix file limits for change reporting. JENKINS-47602 |
||
#31 | 22816 | Paul Allen |
Merge pull request #51 from jenkinsci/limit-describe. Limit output from describe. JENKINS-46671 |
||
#30 | 22815 | Paul Allen |
Provide repo with connection.getCommitObject(). The `p4 graph cat-file commit` requires `super` level access if the repo name is not provided. JENKINS-46595 |
||
#29 | 22128 | Paul Allen |
Helix Graph support for Jenkins. JENKINS-40354 |
||
#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 |