| /* |
| * 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; |
| } |
| } |