提交 679ffdee 编写于 作者: K kohsuke

Implemented more intelligent polling assisted by <tt>commit-hook</tt> from SVN repository.

git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@18915 71c3de6d-444a-0410-be80-ed276b4c234a
上级 7b7d1269
......@@ -2063,6 +2063,9 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
// Initialize the filter with the crumb issuer
setCrumbIssuer(crumbIssuer);
// auto register root actions
actions.addAll(getExtensionList(RootAction.class));
LOGGER.info(String.format("Took %s ms to load",System.currentTimeMillis()-startTime));
if(KILL_AFTER_LOAD)
......
package hudson.model;
import hudson.ExtensionPoint;
import hudson.Extension;
/**
* Marker interface for actions that are added to {@link Hudson}.
*
* <p>
* Extend from this interface and put {@link Extension} on your subtype
* to have them auto-registered to {@link Hudson}.
*
* @author Kohsuke Kawaguchi
* @since 1.311
*/
public interface RootAction extends Action, ExtensionPoint {
}
package hudson.scm;
import hudson.model.AbstractModelObject;
import hudson.model.AbstractProject;
import hudson.model.Hudson;
import hudson.scm.SubversionSCM.ModuleLocation;
import hudson.triggers.SCMTrigger;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.tmatesoft.svn.core.SVNException;
import javax.servlet.ServletException;
import static javax.servlet.http.HttpServletResponse.SC_OK;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.WARNING;
import java.util.logging.Logger;
/**
* Per repository status.
*
* @author Kohsuke Kawaguchi
* @see SubversionStatus
*/
public class SubversionRepositoryStatus extends AbstractModelObject {
public final UUID uuid;
public SubversionRepositoryStatus(UUID uuid) {
this.uuid = uuid;
}
public String getDisplayName() {
return uuid.toString();
}
public String getSearchUrl() {
return uuid.toString();
}
/**
* Notify the commit to this repository.
*
* <p>
* Because this URL is not guarded, we can't really trust the data that's sent to us. But we intentionally
* don't protect this URL to simplify <tt>post-commit</tt> script set up.
*/
public void doNotifyCommit(StaplerRequest req, StaplerResponse rsp) throws ServletException, IOException {
requirePOST();
// compute the affected paths
Set<String> affectedPath = new HashSet<String>();
String line;
while((line=new BufferedReader(req.getReader()).readLine())!=null)
affectedPath.add(line.substring(4));
if(LOGGER.isLoggable(FINE))
LOGGER.fine("Change reported to Subversion repository "+uuid+" on "+affectedPath);
OUTER:
for (AbstractProject<?,?> p : Hudson.getInstance().getItems(AbstractProject.class)) {
try {
SCM scm = p.getScm();
if (!(scm instanceof SubversionSCM)) continue;
SCMTrigger trigger = p.getTrigger(SCMTrigger.class);
if(trigger==null) continue;
SubversionSCM sscm = (SubversionSCM) scm;
for (ModuleLocation loc : sscm.getLocations()) {
if(!loc.getUUID().equals(uuid)) continue; // different repository
String m = loc.getSVNURL().getPath();
String n = loc.getRepositoryRoot().getPath();
if(!m.startsWith(n)) continue; // repository root should be a subpath of the module path, but be defensive
String remaining = m.substring(n.length());
if(remaining.startsWith("/")) remaining=remaining.substring(1);
String remainingSlash = remaining + '/';
for (String path : affectedPath) {
if(path.equals(remaining) /*for files*/ || path.startsWith(remainingSlash) /*for dirs*/) {
// this project is possibly changed. poll now.
// if any of the data we used was bogus, the trigger will not detect a chaange
LOGGER.fine("Scheduling the immediate polling of "+p);
trigger.run();
continue OUTER;
}
}
}
} catch (SVNException e) {
LOGGER.log(WARNING,"Failed to handle Subversion commit notification",e);
}
}
rsp.setStatus(SC_OK);
}
private static final Logger LOGGER = Logger.getLogger(SubversionRepositoryStatus.class.getName());
}
......@@ -122,6 +122,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.StringTokenizer;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
......@@ -1674,6 +1675,12 @@ public class SubversionSCM extends SCM implements Serializable {
*/
public final String local;
/**
* Cache of the repository UUID.
*/
private transient volatile UUID repositoryUUID;
private transient volatile SVNURL repositoryRoot;
public ModuleLocation(String remote, String local) {
if(local==null)
local = getLastPathComponent(remote);
......@@ -1707,6 +1714,30 @@ public class SubversionSCM extends SCM implements Serializable {
return SVNURL.parseURIEncoded(getURL());
}
/**
* Repository UUID. Lazy computed and cached.
*/
public UUID getUUID() throws SVNException {
if(repositoryUUID==null || repositoryRoot==null) {
synchronized (this) {
SVNRepository r = openRepository();
r.testConnection(); // make sure values are fetched
repositoryUUID = UUID.fromString(r.getRepositoryUUID(false));
repositoryRoot = r.getRepositoryRoot(false);
}
}
return repositoryUUID;
}
public SVNRepository openRepository() throws SVNException {
return Hudson.getInstance().getDescriptorByType(DescriptorImpl.class).getRepository(getSVNURL());
}
public SVNURL getRepositoryRoot() throws SVNException {
getUUID();
return repositoryRoot;
}
/**
* Figures out which revision to check out.
*
......
/*
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.scm;
import hudson.model.AbstractModelObject;
import hudson.model.Action;
import hudson.model.RootAction;
import hudson.Extension;
import java.util.regex.Pattern;
import java.util.UUID;
/**
* Information screen for the use of Subversion in Hudson.
*
* @author Kohsuke Kawaguchi
*/
@Extension
public class SubversionStatus extends AbstractModelObject implements RootAction {
public String getDisplayName() {
return "Subversion";
}
public String getSearchUrl() {
return getUrlName();
}
public String getIconFileName() {
// TODO
return null;
}
public String getUrlName() {
return "subversion";
}
public SubversionRepositoryStatus getDynamic(String uuid) {
if(UUID_PATTERN.matcher(uuid).matches())
return new SubversionRepositoryStatus(UUID.fromString(uuid));
return null;
}
private static final Pattern UUID_PATTERN = Pattern.compile("\\p{XDigit}{8}-\\p{XDigit}{4}-\\p{XDigit}{4}-\\p{XDigit}{4}-\\p{XDigit}{12}");
}
<div>
Checks out the source code from Subversion repositories. See
<a href="http://wiki.hudson-ci.org/display/HUDSON/Subversion+post-commit+hook">post-commit</a> hook set up
for improved turn-around time and performance in polling.
</div>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册