-
-
Notifications
You must be signed in to change notification settings - Fork 273
Expand file tree
/
Copy pathCompareAgainstBaselineCallable.java
More file actions
137 lines (122 loc) · 5.83 KB
/
Copy pathCompareAgainstBaselineCallable.java
File metadata and controls
137 lines (122 loc) · 5.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package hudson.scm;
import hudson.model.TaskListener;
import hudson.remoting.DelegatingCallable;
import hudson.scm.PollingResult.Change;
import hudson.scm.SubversionSCM.SVNLogHandler;
import hudson.scm.SubversionSCM.SvnInfo;
import hudson.scm.subversion.Messages;
import java.io.IOException;
import java.text.DateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import jenkins.model.Jenkins;
import jenkins.security.MasterToSlaveCallable;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationProvider;
/**
* Callable which compares the given baseline against the current state of the svn repository and returns the
* appropriate {@link PollingResult} as answer.
*
* @author kutzi
*/
final class CompareAgainstBaselineCallable extends MasterToSlaveCallable<PollingResult,IOException> implements DelegatingCallable<PollingResult, IOException> {
private final SVNLogHandler logHandler;
private final String projectName;
private final SVNRevisionState baseline;
private final TaskListener listener;
private final ISVNAuthenticationProvider defaultAuthProvider;
private final Map<String, ISVNAuthenticationProvider> authProviders;
private final String nodeName;
private static final long serialVersionUID = 8200959096894789583L;
CompareAgainstBaselineCallable(SVNRevisionState baseline, SVNLogHandler logHandler, String projectName,
TaskListener listener, ISVNAuthenticationProvider defaultAuthProvider,
Map<String, ISVNAuthenticationProvider> authProviders, String nodeName) {
this.logHandler = logHandler;
this.projectName = projectName;
this.baseline = baseline;
this.listener = listener;
this.defaultAuthProvider = defaultAuthProvider;
this.authProviders = authProviders;
this.nodeName = nodeName;
}
public ClassLoader getClassLoader() {
return Jenkins.get().getPluginManager().uberClassLoader;
}
/**
* Computes {@link PollingResult}. Note that we allow changes that match the certain paths to be excluded,
* so
*/
public PollingResult call() {
listener.getLogger().println("Received SCM poll call on " + nodeName + " for " + projectName + " on " + DateFormat.getDateTimeInstance().format(new Date()) );
final Map<String,Long> revs = new HashMap<>();
boolean changes = false;
boolean significantChanges = false;
for (Map.Entry<String,Long> baselineInfo : baseline.revisions.entrySet()) {
String url = baselineInfo.getKey();
long baseRev = baselineInfo.getValue();
/*
If we fail to check the remote revision, assume there's no change.
In this way, a temporary SVN server problem won't result in bogus builds,
which will fail anyway. So our policy in the error handling in the polling
is not to fire off builds. see HUDSON-6136.
*/
revs.put(url, baseRev);
try {
ISVNAuthenticationProvider authProvider = authProviders.get(url);
if (authProvider == null) {
authProvider = defaultAuthProvider;
}
ChangeState revChanges = checkInternal(url,authProvider,baseRev,revs);
changes |= revChanges.changes;
significantChanges |= revChanges.significantChanges;
} catch (SVNException e) {
boolean success = false;
// normal auth provider handling is not working
// we don't know which external revision belongs to which module -> we try all authproviders provided
for(ISVNAuthenticationProvider authProvider : authProviders.values()){
try{
ChangeState revChanges = checkInternal(url,authProvider,baseRev,revs);
changes |= revChanges.changes;
significantChanges |= revChanges.significantChanges;
success = true;
break;
}catch(SVNException ignored){}
}
if(!success){
e.printStackTrace(listener.error(Messages.SubversionSCM_pollChanges_exception(url)));
}
}
}
assert revs.size()== baseline.revisions.size();
return new PollingResult(baseline,new SVNRevisionState(revs),
significantChanges ? Change.SIGNIFICANT : changes ? Change.INSIGNIFICANT : Change.NONE);
}
static class ChangeState{
boolean changes = false;
boolean significantChanges = false;
}
private ChangeState checkInternal(String url,ISVNAuthenticationProvider authProvider, long baseRev, Map<String,Long> revs) throws SVNException {
ChangeState changes = new ChangeState();
final SVNURL svnurl = SVNURL.parseURIDecoded(url);
long nowRev = new SvnInfo(SubversionSCM.parseSvnInfo(svnurl, authProvider)).revision;
changes.changes |= (nowRev>baseRev);
listener.getLogger().println(Messages.SubversionSCM_pollChanges_remoteRevisionAt(url, nowRev));
if(revs.containsKey(url)){
long containingRevision = revs.get(url);
// take maximum revision
if(nowRev > containingRevision){
revs.put(url, nowRev);
}
}else {
revs.put(url, nowRev);
}
// make sure there's a change and it isn't excluded
if (logHandler.findNonExcludedChanges(svnurl, baseRev+1, nowRev, authProvider)) {
listener.getLogger().println(Messages.SubversionSCM_pollChanges_changedFrom(baseRev));
changes.significantChanges = true;
}
return changes;
}
}