Skip to content
Permalink
Browse files
Merge pull request #27 from batkinson/JENKINS-10449
Filter changelog based on the same inclusion/exclusion filters used to detect changes. [FIXED JENKINS-10449]
  • Loading branch information
kutzi committed Dec 29, 2012
2 parents ed8a1f8 + 515250d commit 72be6320a61f79ec329e0f42b496dbac8fff1644
@@ -0,0 +1,171 @@
package hudson.scm;

import hudson.Util;

import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

import org.tmatesoft.svn.core.SVNLogEntry;
import org.tmatesoft.svn.core.SVNLogEntryPath;
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.SVNProperties;

/**
* Determines whether a log entry contains changes within the included paths for a project.
*/
public class DefaultSVNLogFilter implements SVNLogFilter {

private PrintStream log;

private Pattern[] excludedPatterns;
private Pattern[] includedPatterns;
private Set<String> excludedUsers;
private String excludedRevprop;
private Pattern[] excludedCommitMessages;
private boolean ignoreDirPropChanges;

public DefaultSVNLogFilter(Pattern[] excludedPatterns, Pattern[] includedPatterns, Set<String> excludedUsers, String excludedRevProp, Pattern[] excludedCommitMessages, boolean ignoreDirPropChanges) {
this.excludedPatterns = excludedPatterns;
this.includedPatterns = includedPatterns;
this.excludedUsers = excludedUsers;
this.excludedRevprop = excludedRevProp;
this.excludedCommitMessages = excludedCommitMessages;
this.ignoreDirPropChanges = ignoreDirPropChanges;
}

/* (non-Javadoc)
* @see hudson.scm.SVNLogFilter#setLog(java.io.PrintStream)
*/
public void setLog(PrintStream log) {
this.log = log;
}

/* (non-Javadoc)
* @see hudson.scm.SVNLogFilter#hasExclusionRule()
*/
public boolean hasExclusionRule() {
return excludedPatterns.length > 0 || !excludedUsers.isEmpty() || excludedRevprop != null || excludedCommitMessages.length > 0 || includedPatterns.length > 0 || ignoreDirPropChanges;
}

/* (non-Javadoc)
* @see hudson.scm.SVNLogFilter#isIncluded(org.tmatesoft.svn.core.SVNLogEntry)
*/
public boolean isIncluded(SVNLogEntry logEntry) {
if (excludedRevprop != null) {
// If the entry includes the exclusion revprop, don't count it as a change
SVNProperties revprops = logEntry.getRevisionProperties();
if (revprops != null && revprops.containsName(excludedRevprop)) {
if (log != null) {
log.println(hudson.scm.subversion.Messages.SubversionSCM_pollChanges_ignoredRevision(
logEntry.getRevision(),
hudson.scm.subversion.Messages.SubversionSCM_pollChanges_ignoredRevision_revprop(excludedRevprop)));
}
return false;
}
}

String author = logEntry.getAuthor();
if (excludedUsers.contains(author)) {
// If the author is an excluded user, don't count this entry as a change
if (log != null) {
log.println(hudson.scm.subversion.Messages.SubversionSCM_pollChanges_ignoredRevision(
logEntry.getRevision(),
hudson.scm.subversion.Messages.SubversionSCM_pollChanges_ignoredRevision_author(author)));
}
return false;
}

if (excludedCommitMessages != null) {
// If the commit message contains one of the excluded messages, don't count it as a change
String commitMessage = logEntry.getMessage();
for (Pattern pattern : excludedCommitMessages) {
if (pattern.matcher(commitMessage).find()) {
return false;
}
}
}

// If there were no changes, don't count this entry as a change
Map<String, SVNLogEntryPath> changedPaths = logEntry.getChangedPaths();
if (changedPaths.isEmpty()) {
return false;
}

// dirPropChanges are changes that modifiy ('M') a directory, i.e. only
// exclude if there are NO changes on files or Adds/Removals
if (ignoreDirPropChanges) {
boolean contentChanged = false;
for (SVNLogEntryPath path : changedPaths.values()) {
if (path.getType() != 'M' || path.getKind() != SVNNodeKind.DIR) {
contentChanged = true;
break;
}
}
if (!contentChanged) {
if (log != null) {
log.println(hudson.scm.subversion.Messages.SubversionSCM_pollChanges_ignoredRevision(
logEntry.getRevision(),
hudson.scm.subversion.Messages.SubversionSCM_pollChanges_ignoredRevision_onlydirprops()));
}
return false;
}
}

// If there are included patterns, see which paths are included
List<String> includedPaths = new ArrayList<String>();
if (includedPatterns.length > 0) {
for (String path : changedPaths.keySet()) {
for (Pattern pattern : includedPatterns) {
if (pattern.matcher(path).matches()) {
includedPaths.add(path);
break;
}
}
}
} else {
includedPaths = new ArrayList<String>(changedPaths.keySet());
}

// If no paths are included don't count this entry as a change
if (includedPaths.isEmpty()) {
if (log != null) {
log.println(hudson.scm.subversion.Messages.SubversionSCM_pollChanges_ignoredRevision(
logEntry.getRevision(),
hudson.scm.subversion.Messages.SubversionSCM_pollChanges_ignoredRevision_noincpath()));
}
return false;
}

// Else, check each changed path
List<String> excludedPaths = new ArrayList<String>();
if (excludedPatterns.length > 0) {
for (String path : includedPaths) {
for (Pattern pattern : excludedPatterns) {
if (pattern.matcher(path).matches()) {
excludedPaths.add(path);
break;
}
}
}
}

// If all included paths are in an excluded region, don't count this entry as a change
if (includedPaths.size() == excludedPaths.size()) {
if (log != null) {
log.println(hudson.scm.subversion.Messages.SubversionSCM_pollChanges_ignoredRevision(
logEntry.getRevision(),
hudson.scm.subversion.Messages.SubversionSCM_pollChanges_ignoredRevision_path(Util.join(excludedPaths, ", "))));
}
return false;
}

// Otherwise, a change is a change
return true;
}

private static final long serialVersionUID = 1L;
}
@@ -41,7 +41,14 @@ public class DirAwareSVNXMLLogHandler extends SVNXMLLogHandler implements ISVNLo
private boolean myIsOmitLogMessage;

private LinkedList<MergeFrame> myMergeStack;


private SVNLogFilter filter = new NullSVNLogFilter();

public DirAwareSVNXMLLogHandler(ContentHandler contentHandler, SVNLogFilter filter) {
super(contentHandler);
this.filter = filter;
}

public DirAwareSVNXMLLogHandler(ContentHandler contentHandler, ISVNDebugLog log) {
super(contentHandler, log);
}
@@ -68,7 +75,9 @@ public void setOmitLogMessage(boolean omitLogMessage) {
*/
public void handleLogEntry(SVNLogEntry logEntry) throws SVNException {
try {
sendToHandler(logEntry);
if (filter == null || !filter.hasExclusionRule() || filter.isIncluded(logEntry)) {
sendToHandler(logEntry);
}
} catch (SAXException e) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.XML_MALFORMED, e.getLocalizedMessage());
SVNErrorManager.error(err, e, SVNLogType.DEFAULT);
@@ -0,0 +1,23 @@
package hudson.scm;

import java.io.PrintStream;

import org.tmatesoft.svn.core.SVNLogEntry;

/**
* An implementation of {@link SVNLogFilter} that never filters a {@link SVNLogEntry}.
*/
public class NullSVNLogFilter implements SVNLogFilter {

public void setLog(PrintStream log) {
}

public boolean hasExclusionRule() {
return false;
}

public boolean isIncluded(SVNLogEntry logEntry) {
return true;
}

}
@@ -0,0 +1,25 @@
package hudson.scm;

import java.io.PrintStream;

import org.tmatesoft.svn.core.SVNLogEntry;

public interface SVNLogFilter {

public abstract void setLog(PrintStream log);

/**
* Is there any exclusion rule?
* @return true if the filter could possibly filter anything.
*/
public abstract boolean hasExclusionRule();

/**
* Checks if the given log entry should be considered for the purposes
* of SCM polling.
*
* @return <code>true</code> if the should trigger polling, <code>false</code> otherwise
*/
public abstract boolean isIncluded(SVNLogEntry logEntry);

}
@@ -103,7 +103,8 @@ public boolean run(Collection<SubversionSCM.External> externals, Result changeLo
SVNLogClient svnlc = manager.getLogClient();
TransformerHandler th = createTransformerHandler();
th.setResult(changeLog);
SVNXMLLogHandler logHandler = new DirAwareSVNXMLLogHandler(th);
SVNLogFilter logFilter = scm.isFilterChangelog()? scm.createSVNLogFilter() : new NullSVNLogFilter();
SVNXMLLogHandler logHandler = new DirAwareSVNXMLLogHandler(th, logFilter);
// work around for http://svnkit.com/tracker/view.php?id=175
th.setDocumentLocator(DUMMY_LOCATOR);
logHandler.startDocument();

0 comments on commit 72be632

Please sign in to comment.