blob: 1b3ed08ca8df71b092b1bc7572416c68dea2a366 [file] [log] [blame]
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.ant.taskdefs;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* A Svn interface task, because the initial solution of <exec> and
* <propertyregex> is unhappy in ant 1.6.5, and while that's old, it's not quite
* "too old" for us to care.
*/
public class SvnInfo extends Task {
// URL line from svn info output, selecting the very last term of the URL as
// the branch specifier
private static final String URL_REGEX = "\\s*URL:\\s*https?://.*/([^/]*)\\s*";
private String fileprop;
private String outprop;
private String workdir;
public SvnInfo() {
super();
}
@Override
public void execute() throws BuildException {
if (outprop == null) {
throw new BuildException(
"<svninfo> task requires an outputproperty attribute");
}
if (workdir == null) {
workdir = getProject().getProperty("basedir");
}
File workDirFile = new File(workdir);
if (!workDirFile.isDirectory()) {
throw new BuildException(workdir + " is not a directory");
}
String branch = getSvnBranch(workDirFile);
String revision = getSvnVersion(workDirFile);
getProject().setNewProperty(outprop, branch + "@" + revision);
if (fileprop != null) {
getProject().setNewProperty(fileprop,
branch + "-" + revision.replaceAll(":", "-"));
}
}
/**
* Establishes the directory used as the SVN workspace to fetch version
* information.
*
* @param srcdir workspace directory name
*/
public void setDirectory(String srcdir) {
workdir = srcdir;
}
/**
* Establishes the property containing the SVN output string, branch@rev.
*
* @param propname Name of a property
*/
public void setOutputFileProperty(String propname) {
fileprop = propname;
}
/**
* Establishes the property containing the SVN output string, branch@rev.
*
* @param propname Name of a property
*/
public void setOutputProperty(String propname) {
outprop = propname;
}
private String getSvnBranch(File workdir) {
String branchName = null;
LineNumberReader svnout = runCommand(workdir, "svn", "info");
try {
String line = svnout.readLine();
Pattern urlRegex = Pattern.compile(URL_REGEX);
while (line != null) {
Matcher m = urlRegex.matcher(line);
if (m.matches()) {
branchName = m.group(1);
if (branchName == null || "".equals(branchName)) {
throw new BuildException(
"svn info didn't get branch from URL line " + line);
}
break;
}
line = svnout.readLine();
}
} catch (IOException e) {
throw new BuildException(
"<svninfo> cannot read svn info's output stream", e);
}
return branchName;
}
private String getSvnVersion(File workdir) {
String line = null;
LineNumberReader svnout = runCommand(workdir, "svnversion", ".");
try {
line = svnout.readLine();
} catch (IOException e) {
throw new BuildException(
"<svninfo> cannot read svnversion's output stream", e);
}
if (line == null || "".equals(line)) {
throw new BuildException("svnversion didn't give any answer");
}
return line;
}
private LineNumberReader runCommand(File workdir, String... cmd) {
String cmdString = "";
for (String arg : cmd) {
cmdString = cmdString + arg + " ";
}
cmdString = cmdString.substring(0, cmdString.length() - 1);
ProcessBuilder svnPb = new ProcessBuilder(cmd);
svnPb.directory(workdir);
Process svnproc;
try {
svnproc = svnPb.start();
} catch (IOException e) {
throw new BuildException("cannot launch command " + cmdString, e);
}
LineNumberReader svnerr = new LineNumberReader(new InputStreamReader(
svnproc.getErrorStream()));
try {
String line = svnerr.readLine();
String errorText = "";
if (line != null) {
while (line != null) {
errorText = errorText + " " + line + "\n";
line = svnerr.readLine();
}
throw new BuildException(cmdString + " returned error output:\n"
+ errorText);
}
} catch (IOException e) {
throw new BuildException("cannot read error stream from " + cmdString, e);
}
LineNumberReader svnout = new LineNumberReader(new InputStreamReader(
svnproc.getInputStream()));
return svnout;
}
}