/*******************************************************************************
*
* Copyright 2011-2014 Spiffy UI Team
*
* 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 org.spiffyui.build;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* <p>
* The RevisionInfoTask gets information about the current revision being built
* and makes it available to the project. This task supports Subversion and GIT.
* Both clients must be available on the current path. It exports two properties:
* revision.number and revision.date into the project.
* </p>
*/
public class RevisionInfoUtil
{
/**
* Get the revision information for the specified root directory
*
* @param rootDir the root to get revision information from
*
* @return the revision info bean with revision information about this directory.
*
* @throws InterruptedException if there is an error waiting for the output of the version control commands
*/
public static RevisionInfoBean getRevisionInfo(final File rootDir)
throws InterruptedException
{
try {
RevisionInfoBean revInfo = getSubversionRev(rootDir);
if (revInfo == null) {
revInfo = getGitRev(rootDir);
}
if (revInfo == null) {
return new RevisionInfoBean("-1", "-1");
} else {
return revInfo;
}
} catch (IOException ioe) {
/*
This means that we had an error calling one of the
tools to get the revision information. In this case
we just return an empty bean
*/
return new RevisionInfoBean("-1", "-1");
}
}
/**
* This process watcher let's is know when the external processes we are executing complete.
*/
private static class ProcessWatcher implements Runnable
{
private Process m_p;
private boolean m_finished = false;
public ProcessWatcher(Process p)
{
m_p = p;
new Thread(this).start();
}
public boolean isFinished()
{
return m_finished;
}
public void run()
{
try {
m_p.waitFor();
} catch (Exception e) {
/*
* This shouldn't happen
*/
e.printStackTrace();
}
m_finished = true;
}
}
private static RevisionInfoBean getSubversionRev(final File rootDir) throws InterruptedException, IOException
{
Process proc = Runtime.getRuntime().exec("svn info " + rootDir.getAbsolutePath());
InputStream is = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
ProcessWatcher pw = new ProcessWatcher(proc);
while (!pw.isFinished()) {
String line;
int exit = -1;
while ((line = br.readLine()) != null) {
if (line.startsWith("Revision: ")) {
return new RevisionInfoBean(line.substring(10, line.length()), "-1");
}
try {
exit = proc.exitValue();
if (exit == 0) {
// Process finished
}
} catch (IllegalThreadStateException t) {
/*
* If the process isn't finished we just want to repeat the loop
*/
}
}
Thread.sleep(100);
}
return null;
}
private static RevisionInfoBean getGitRev(final File rootDir) throws InterruptedException, IOException
{
String args[] = new String[6];
args[0] = "git";
args[1] = "log";
args[2] = "--pretty=Revision: %h:%ct0000";
args[3] = "-n1";
args[4] = "HEAD";
args[5] = rootDir.getAbsolutePath();
Process proc = Runtime.getRuntime().exec(args);
InputStream is = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
ProcessWatcher pw = new ProcessWatcher(proc);
while (!pw.isFinished()) {
String line;
int exit = -1;
while ((line = br.readLine()) != null) {
if (line.startsWith("Revision: ")) {
int colIndex = line.indexOf(':', 11);
return new RevisionInfoBean(line.substring(10, colIndex), line.substring(colIndex + 1, line.length() - 1));
}
try {
exit = proc.exitValue();
if (exit == 0) {
// Process finished
}
} catch (IllegalThreadStateException t) {
/*
* If the process isn't finished we just want to repeat the loop
*/
}
}
Thread.sleep(100);
}
return null;
}
}