[Anthill-dev] Subversion backend - make sure correct revision is
labelled
Jim Hague
jim.hague at acm.org
Mon Nov 8 08:02:43 CST 2004
When Anthill Subversion backend labels the repository after a successful build,
it does the label directly on the repository. It will therefore label the
current head revision. If a checking has occurred during the build, this
behaviour is badly wrong.
This patch amends the Subversion backend such that it records the revision
number of the source that is checked out for build, and labels that revision on
a successful build.
--
Jim Hague - jim.hague at acm.org Never trust a computer you can't lift.
-------------- next part --------------
Index: build/build.xml
===================================================================
--- build/build.xml (revision 605)
+++ build/build.xml (revision 607)
@@ -149,6 +149,7 @@
<fixcrlf srcdir="${conf.profile.dir}/Unix/unix_cvs" />
<fixcrlf srcdir="${conf.profile.dir}/Unix/unix_perforce" />
<fixcrlf srcdir="${conf.profile.dir}/Unix/unix_pvcs" />
+ <fixcrlf srcdir="${conf.profile.dir}/Unix/unix_subversion" />
<fixcrlf srcdir="${conf.profile.dir}/Unix/unix_vss" />
<fixcrlf srcdir="${build.dir}" excludes="**/CVS **/*.class" />
</target>
Index: source/main/java/com/urbancode/anthill/adapter/SubversionRepositoryAdapte
r.java
===================================================================
--- source/main/java/com/urbancode/anthill/adapter/SubversionRepositoryAdapter.j
ava (revision 605)
+++ source/main/java/com/urbancode/anthill/adapter/SubversionRepositoryAdapter.j
ava (revision 607)
@@ -90,12 +90,13 @@
private static final String REV_DELIM_TOKEN = "----------------------------
--------------------------------------------";
private static final String NEW_LINE = System.getProperty("line.separator")
;
-
-
- //*************************************************************************
- // Instance
- //*************************************************************************
-
+
+ //*************************************************************************
// Instance
+ //*************************************************************************
+
+ // The revision we are building.
+ protected String buildRevision;
+
/**
* Create a new SubversionRepositoryAdapter
*/
@@ -114,6 +115,99 @@
}
/**
+ * checks out entire project and notes the revision the local
+ * copy is at for when it is time to tag later on.
+ */
+ public void getWorkingProjectCopy(BuildDefinition def)
+ throws RepositoryException {
+ super.getWorkingProjectCopy(def);
+
+ log.debug("Getting working copy of project: " + project.getProjectName(
));
+ Process p = null;
+ StreamPumper errorPumper = null;
+ int exitcode = 0;
+ try {
+ Map tempMap = new HashMap();
+ tempMap.put("Adapter", this);
+ tempMap.put("Properties", project.getProperties());
+ if (def.getVersionedBuildFlag()){
+ log.info("Retrieving project version " + def.getVersion());
+ tempMap.put("Version", def.getVersion().trim());
+ }
+
+ Pagelet pagelet = getPageletFactory().getPagelet(makeProfilePagelet
Name(WORKING_PROJECT_PAGELET));
+ if (pagelet != null) {
+ log.debug("Have checkout pagelet.");
+ }
+ else {
+ log.debug("Pagelet is null in checkout!");
+ }
+ String commandString = pagelet.service(tempMap);
+ log.debug("Checkout Command: " + commandString);
+ p = Runtime.getRuntime().exec(toArray(commandString));
+
+ // pump the error stream.
+ errorPumper = new StreamPumper(p.getErrorStream(), "getRevisions",
+ System.err, true);
+ errorPumper.start();
+
+ // get and parse the input stream
+ parseCheckoutCommandResult(p.getInputStream());
+
+ exitcode = p.waitFor();
+ }
+ catch (RepositoryException e) {
+ throw e;
+ }
+ catch (Exception e) {
+ throw new RepositoryException(
+ "Checkout failed: " + e.getMessage(),
+ e);
+ }
+ finally {
+ if (errorPumper != null) {
+ try {
+ errorPumper.join();
+ } catch (InterruptedException e) {
+ throw new RepositoryException(e);
+ }
+ }
+ }
+ // handle errors
+ if (exitcode != 0)
+ throw (new RepositoryException("svn checkout failed. Exit code: "
+ exitcode));
+ }
+
+ protected void parseCheckoutCommandResult(InputStream in)
+ throws IOException, RepositoryException {
+ BufferedReader br = new BufferedReader(new InputStreamReader(in));
+ RE checkedOutRE = null;
+
+ // The last line says "Checked out revision nnn."
+ // Start by collecting the last line.
+ String lastLine = null;
+ for ( String line = br.readLine(); line != null; line = br.readLine() )
+ lastLine = line;
+
+ try
+ {
+ checkedOutRE = new RE("(\\d+)");
+ }
+ catch (RESyntaxException rse)
+ {
+ log.error(rse);
+ throw new RepositoryException(rse);
+ }
+
+ if ( !checkedOutRE.match(lastLine) )
+ {
+ log.error("No revision number in last line of checkout" + lastLine);
+ throw new RepositoryException("No revision number in " + lastLine);
+ }
+ buildRevision = checkedOutRE.getParen(1);
+ }
+
+ /**
* Returns a List of Revision objects detailing the changes that have
* been made since the specified date.
* <p>
@@ -138,7 +232,7 @@
tempMap.put("Date", date);
Pagelet pagelet = getPageletFactory().getPagelet(makeProfilePagelet
Name(GET_REVISIONS_SINCE_PAGELET));
String commandString = pagelet.service(tempMap);
- log.info("Get revisions since command: " + commandString);
+ log.debug("Get revisions since command: " + commandString);
p = Runtime.getRuntime().exec(toArray(commandString));
// pump the error stream.
@@ -222,6 +316,11 @@
log.debug("RevID: " + revId);
log.debug("User: " + user);
log.debug("Date: " + rev.date);
+
+ // We need buildRevision to end up the latest revision
+ // in our working directory, i.e. the revision
+ // which we're actually building.
+ buildRevision = revId;
}
catch (ParseException pe)
{
@@ -304,5 +403,41 @@
* @param file file to prepare for editing
*/
public void prepareFileForEdit(String file) throws RepositoryException {
- }
+ }
+
+ /**
+ * Labels all relevant project files with the provided tag.
+ * A Subversion label/tag operation is simply a server-side copy of
+ * the project, but that means we must make sure we copy the project
+ * at the revision at which we built it. So we pass
+ * <code>buildRevision</code> down to the labelling code.
+ *
+ * @param tag The label to tag the files with
+ */
+ public void label(String tag) throws RepositoryException {
+ if (tag == null || tag.length() == 0) {
+ throw (new RepositoryException("No label specified"));
+ }
+
+ tag = tag.replace('$', '_').replace(',', '_').replace('.', '_')
+ .replace(':', '_').replace(';', '_').replace('@', '_');
+
+ log.info("Tagging entire project with label: " + tag);
+
+ try {
+ Map tempMap = new HashMap();
+ tempMap.put("Properties", project.getProperties());
+ tempMap.put("Adapter", this);
+ tempMap.put("Tag", tag);
+ tempMap.put("BuildRevision", buildRevision);
+ Pagelet pagelet = getPageletFactory().getPagelet(makeProfilePagelet
Name(LABEL_PAGELET));
+ executeCommand(pagelet.service(tempMap), "Label");
+ }
+ catch (RepositoryException e) {
+ throw e;
+ }
+ catch (Exception e) {
+ throw new RepositoryException("Label failed: " + e.getMessage(), e)
;
+ }
+ }
}
Index: source/main/profiles/Win32/win_subversion/label.pgl
===================================================================
--- source/main/profiles/Win32/win_subversion/label.pgl (revision 605)
+++ source/main/profiles/Win32/win_subversion/label.pgl (revision 607)
@@ -7,6 +7,7 @@
ProfileRepositoryAdapter ra = (ProfileRepositoryAdapter)context.get("Adapter");
ProjectProperties pp = (ProjectProperties)context.get("Properties");
String tag = (String)context.get("Tag");
+String buildRevision = (String)context.get("BuildRevision");
String url = pp.getProperty(SubversionRepositoryAdapter.URL_KEY);
String tagUrl = pp.getProperty(SubversionRepositoryAdapter.TAGS_URL_KEY);
String user = pp.getProperty(SubversionRepositoryAdapter.USER_KEY).trim();
@@ -25,4 +26,4 @@
%>
-svn copy --non-interactive -m "Copied by Anthill" <%=authArgs%> <%=url%> <%=tag
Url%>
+svn copy --non-interactive -m "Copied by Anthill" <%=authArgs%> -r <%=buildRevi
sion%> <%=url%> <%=tagUrl%>
Index: source/main/profiles/Unix/unix_subversion/label.pgl
===================================================================
--- source/main/profiles/Unix/unix_subversion/label.pgl (revision 605)
+++ source/main/profiles/Unix/unix_subversion/label.pgl (revision 607)
@@ -7,6 +7,7 @@
ProfileRepositoryAdapter ra = (ProfileRepositoryAdapter)context.get("Adapter");
ProjectProperties pp = (ProjectProperties)context.get("Properties");
String tag = (String)context.get("Tag");
+String buildRevision = (String)context.get("BuildRevision");
String url = pp.getProperty(SubversionRepositoryAdapter.URL_KEY);
String tagUrl = pp.getProperty(SubversionRepositoryAdapter.TAGS_URL_KEY);
String user = pp.getProperty(SubversionRepositoryAdapter.USER_KEY).trim();
@@ -29,4 +30,4 @@
%>
-sh <%=pageletDir%>label.sh <%=authArgs%> <%=url%> <%=tagUrl%>
+sh <%=pageletDir%>label.sh <%=authArgs%> -r <%=buildRevision%> <%=url%> <%=tagU
rl%>
More information about the Anthill-dev
mailing list