serve mercurial repositories with hgweb cgi

This commit is contained in:
Sebastian Sdorra
2010-09-26 16:17:39 +02:00
parent 2d666f5b14
commit 4a6fcb4aef
8 changed files with 253 additions and 7 deletions

View File

@@ -15,9 +15,14 @@ import com.google.inject.Singleton;
import sonia.scm.repository.HgConfig;
import sonia.scm.repository.HgRepositoryHandler;
import sonia.scm.repository.RepositoryManager;
import sonia.scm.web.HgWebConfigWriter;
//~--- JDK imports ------------------------------------------------------------
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
@@ -79,16 +84,23 @@ public class HgConfigResource
*
*
* @param uriInfo
* @param servletContext
* @param config
*
* @return
*
* @throws IOException
*/
@POST
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response setConfig(@Context UriInfo uriInfo, HgConfig config)
public Response setConfig(@Context UriInfo uriInfo,
@Context ServletContext servletContext,
HgConfig config)
throws IOException
{
handler.setConfig(config);
handler.storeConfig();
new HgWebConfigWriter(config).write(servletContext);
return Response.created(uriInfo.getRequestUri()).build();
}

View File

@@ -29,7 +29,6 @@ public class HgConfig extends BasicRepositoryConfig
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
@@ -41,6 +40,17 @@ public class HgConfig extends BasicRepositoryConfig
return hgBinary;
}
/**
* Method description
*
*
* @return
*/
public String getPythonBinary()
{
return pythonBinary;
}
/**
* Method description
*
@@ -65,6 +75,17 @@ public class HgConfig extends BasicRepositoryConfig
this.hgBinary = hgBinary;
}
/**
* Method description
*
*
* @param pythonBinary
*/
public void setPythonBinary(String pythonBinary)
{
this.pythonBinary = pythonBinary;
}
/**
* Method description
*
@@ -78,10 +99,12 @@ public class HgConfig extends BasicRepositoryConfig
//~--- fields ---------------------------------------------------------------
/** Field description */
private String hgBinary = "hg";
/** Field description */
private String pythonBinary = "python";
/** Field description */
private File repositoryDirectory;
}

View File

@@ -0,0 +1,46 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package sonia.scm.web;
//~--- non-JDK imports --------------------------------------------------------
import com.google.inject.Scopes;
import com.google.inject.servlet.ServletModule;
import org.apache.catalina.servlets.CGIServlet;
import sonia.scm.web.filter.BasicAuthenticationFilter;
//~--- JDK imports ------------------------------------------------------------
import java.util.HashMap;
import java.util.Map;
/**
*
* @author Sebastian Sdorra
*/
public class HgServletModule extends ServletModule
{
/**
* Method description
*
*/
@Override
protected void configureServlets()
{
filter("/hg/*").through(BasicAuthenticationFilter.class);
Map<String, String> initParams = new HashMap<String, String>();
initParams.put("cgiPathPrefix", "WEB-INF/cgi/hgweb.cgi");
bind(CGIServlet.class).in(Scopes.SINGLETON);
serve("/hg/*").with(CGIServlet.class, initParams);
}
}

View File

@@ -0,0 +1,150 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package sonia.scm.web;
//~--- non-JDK imports --------------------------------------------------------
import sonia.scm.io.INIConfiguration;
import sonia.scm.io.INIConfigurationWriter;
import sonia.scm.io.INISection;
import sonia.scm.io.RegexResourceProcessor;
import sonia.scm.io.ResourceProcessor;
import sonia.scm.repository.HgConfig;
import sonia.scm.util.Util;
//~--- JDK imports ------------------------------------------------------------
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.ServletContext;
/**
*
* @author Sebastian Sdorra
*/
public class HgWebConfigWriter
{
/** Field description */
public static final String CGI_PATH = "WEB-INF/cgi/hgweb.cgi";
/** Field description */
public static final String CGI_TEMPLATE = "/sonia/scm/hgweb.cgi";
/** Field description */
public static final String CONFIG_NAME = "hgweb.config";
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
*
* @param config
*/
public HgWebConfigWriter(HgConfig config)
{
this.config = config;
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param context
*
* @throws IOException
*/
public void write(ServletContext context) throws IOException
{
File webConfigFile = new File(config.getRepositoryDirectory(), CONFIG_NAME);
writeWebConfigFile(webConfigFile);
String path = context.getRealPath(CGI_PATH);
File cgiFile = new File(path);
File cgiDirectory = cgiFile.getParentFile();
if (!cgiDirectory.exists() &&!cgiDirectory.mkdirs())
{
throw new IOException(
"could not create directory: ".concat(cgiDirectory.getPath()));
}
System.out.println( cgiFile );
writeCGIFile(cgiFile, webConfigFile);
}
/**
* Method description
*
*
* @param cgiFile
* @param webConfigFile
*
* @throws IOException
*/
private void writeCGIFile(File cgiFile, File webConfigFile) throws IOException
{
InputStream input = null;
OutputStream output = null;
try
{
input = HgWebConfigWriter.class.getResourceAsStream(CGI_TEMPLATE);
output = new FileOutputStream(cgiFile);
ResourceProcessor rp = new RegexResourceProcessor();
rp.addVariable("python", config.getPythonBinary());
rp.addVariable("config", webConfigFile.getAbsolutePath());
rp.process(input, output);
}
finally
{
Util.close(input);
Util.close(output);
}
}
/**
* Method description
*
*
* @param webConfigFile
*
* @throws IOException
*/
private void writeWebConfigFile(File webConfigFile) throws IOException
{
INIConfiguration webConfig = new INIConfiguration();
INISection pathsSection = new INISection("paths");
String path = config.getRepositoryDirectory().getAbsolutePath();
if (!path.endsWith(File.separator))
{
path = path.concat(File.separator);
}
pathsSection.setParameter("/", path.concat("*"));
webConfig.addSection(pathsSection);
new INIConfigurationWriter().write(webConfig, webConfigFile);
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private HgConfig config;
}

View File

@@ -7,10 +7,6 @@
package sonia.scm.web;
//~--- JDK imports ------------------------------------------------------------
import java.io.InputStream;
/**
*
* @author Sebastian Sdorra
@@ -46,5 +42,6 @@ public class HgWebPlugin implements ScmWebPlugin
public void contextInitialized(ScmWebPluginContext context)
{
context.addScriptResource(new ClasspathWebResource(SCRIPT));
context.addInjectModule(new HgServletModule());
}
}