CFB_ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
INSTR_DIR="${CFB_ROOT}/../instr"
+. ${CFB_ROOT}/setcp.sh
+
#####################
echo Compiling...
find "${CFB_ROOT}/prod" -name "*.java" | xargs javac -g -Xlint:deprecation
#!/bin/bash
CFB_ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+. ${CFB_ROOT}/setcp.sh
+
echo Compiling...
find "${CFB_ROOT}/prod" -name "*.java" | xargs javac -g -classpath ${CFB_ROOT}/prod:${CLASSPATH} -Xlint:deprecation
cp -r ${CFB_ROOT}/prod/* ${CFB_ROOT}/bin/
find "${CFB_ROOT}/prod" -name '*.class' -exec rm {} \;
+
echo Launching...
+echo java -ea -Djsse.enableSNIExtension=false net.jaekl.cfb.CFB $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15} ${16} ${17} ${18} ${19} ${20}
java -ea -Djsse.enableSNIExtension=false net.jaekl.cfb.CFB $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15} ${16} ${17} ${18} ${19} ${20}
analyzed.at=Analyzed at {0}
bug.category.unknown=Internal error: The bug category {0} is unknown. Perhaps the Findbugs versions used to generate the report, and the FindBugs messages.xml, do not match?
bug.type.unknown=Internal error: The bug pattern type {0} is unknown. Perhaps the Findbugs versions used to generate the report, and eth FindBugs messages.xml, do not match?
-cannot.connect.to.db=Unable to connect to, or to initialize, database {2} on {0}:{1} as user {3}.
+cannot.connect.to.db=Unable to connect to, or to initialize, database {2} on {0}:{1} as user "{3}".
cannot.exec=Got result code {1} when attempting to execute command-line: {0}
+cannot.load.fbmsg.file=Unable to load the FindBugs messages file (messages.xml).
cannot.send.mail=Attempt to send email to {0} failed: {1}
cfb=Comparative FindBugs
cfb.mail.subject=CFB: {0} vs. {1}
cfb.report=Comparative FindBugs Report
+findbugs.home.is.not.set=The environment variable FINDBUGS_HOME is not set. Please set it to the path where FindBugs is installed.
+findbugs.home.is.set.to=The environment variable FINDBUGS_HOME is set to {0}. Please ensure that it points to the path where FindBugs is installed.
fixed.bugs=Fixed Bugs
new.bugs=New Bugs
new.version=New Version
import net.jaekl.cfb.analyze.Analysis;
import net.jaekl.cfb.analyze.Analyzer;
import net.jaekl.cfb.analyze.Delta;
+import net.jaekl.cfb.analyze.FBMsgFileNotFoundException;
import net.jaekl.cfb.analyze.HtmlReport;
import net.jaekl.cfb.analyze.MessageMap;
import net.jaekl.cfb.analyze.Notifier;
import net.jaekl.cfb.db.driver.PostgresqlDriver;
import net.jaekl.cfb.store.DbStore;
import net.jaekl.cfb.store.StoreException;
+import net.jaekl.cfb.util.Env;
import net.jaekl.qd.xml.XmlParseException;
import org.apache.commons.cli.CommandLine;
import org.xml.sax.SAXException;
public class CFB {
+ public static final String FINDBUGS_HOME = "FINDBUGS_HOME"; // name of the FINDBUGS_HOME environment variable
+
DbDriver m_driver;
CfbSchema m_schema;
volatile static CfbBundle m_bundle = null;
help.printHelp(pw, 80, getClass().getName(), "", opt, 0, 0, "", true);
}
- String trans(String key) {
- return getBundle(m_locale).get(key);
+ String trans(String key, Object... params) {
+ return getBundle(m_locale).get(key, params);
}
String getenv(String varName) {
File findBugsDir = getFindBugsDir();
File workDir = new File(".");
MessageMap messageMap = new MessageMap();
- messageMap.load(findBugsDir, Locale.getDefault(Category.DISPLAY));
+ try {
+ messageMap.load(findBugsDir, Locale.getDefault(Category.DISPLAY));
+ }
+ catch (FBMsgFileNotFoundException exc) {
+ reportException(pw, exc);
+ return;
+ }
if (!ensureDbInitialized(pw, messageMap)) {
return;
reportUnableToConnect(pw, exc);
}
}
+
+ void reportException(PrintWriter pw, FBMsgFileNotFoundException exc) {
+ exc.printStackTrace(pw);
+
+ pw.println(trans(CfbBundle.CANNOT_LOAD_FBMSG_FILE, exc.getFilename()));
+
+ String fbHome = Env.get(FINDBUGS_HOME);
+ if (null == fbHome) {
+ pw.println(trans(CfbBundle.FINDBUGS_HOME_IS_NOT_SET, FINDBUGS_HOME));
+ }
+ else {
+ pw.println(trans(CfbBundle.FINDBUGS_HOME_IS_SET_TO, FINDBUGS_HOME, fbHome));
+ }
+
+ }
private void reportUnableToConnect(PrintWriter pw, SQLException exc) {
String cannotConnectFormat = trans(CfbBundle.CANNOT_CONNECT);
public static final String BUG_TYPE_UNKNOWN = "bug.type.unknown";
public static final String CANNOT_CONNECT = "cannot.connect.to.db";
public static final String CANNOT_EXEC = "cannot.exec";
+ public static final String CANNOT_LOAD_FBMSG_FILE = "cannot.load.fbmsg.file";
public static final String CANNOT_SEND_MAIL = "cannot.send.mail";
public static final String CFB = "cfb";
public static final String CFB_MAIL_SUBJECT = "cfb.mail.subject";
public static final String CFB_REPORT = "cfb.report";
public static final String COMPARING_RUNS = "comparing.runs";
public static final String COMPARING_VERSIONS = "comparing.versions";
+ public static final String FINDBUGS_HOME_IS_NOT_SET = "findbugs.home.is.not.set";
+ public static final String FINDBUGS_HOME_IS_SET_TO = "findbugs.home.is.set.to";
public static final String FIXED_BUGS = "fixed.bugs";
public static final String NEW_BUGS = "new.bugs";
public static final String NEW_VERSION = "new.version";
--- /dev/null
+package net.jaekl.cfb.analyze;
+
+import net.jaekl.cfb.CfbException;
+
+public class FBMsgFileNotFoundException extends CfbException {
+ private static final long serialVersionUID = 1L;
+
+ private String m_filename;
+
+ public FBMsgFileNotFoundException(String filename) {
+ super(filename);
+ m_filename = filename;
+ }
+
+ public String getFilename() { return m_filename; }
+}
}
}
- pw.write(" <TR>");
- pw.write(" <TD COLSPAN=\"2\" CLASS=\"Loc\">" + sb.toString() + "</TD>");
- pw.write(" </TR>");
+ pw.println(" <TR><TD COLSPAN=\"2\" CLASS=\"Loc\">" + sb.toString() + "</TD></TR>");
}
}
for (BugInstance bug : bugs) {
BugPattern pattern = m_msgColl.getPattern(bug.getType());
- pw.write(" <P>");
- pw.write(" <TABLE CLASS=\"bug\">");
- pw.write(" <TR>");
- pw.write(" <TD WIDTH=\"20%\">" + bug.getCategory() + "</TD>");
- pw.write(" <TD>" + bug.getType() + "</TD>");
- pw.write(" </TR>");
+ pw.println(" <P>");
+ pw.println(" <TABLE CLASS=\"Bug\">");
+ pw.println(" <TR>");
+ pw.println(" <TD WIDTH=\"20%\">" + bug.getCategory() + "</TD>");
+ pw.println(" <TD>" + bug.getType() + "</TD>");
+ pw.println(" </TR>");
writeBugLocations(pw, bug);
- pw.write(" <TR>");
- pw.write(" <TD COLSPAN=\"2\">" + pattern.getShort() + "</TD>");
- pw.write(" </TR>");
- pw.write(" <TR>");
- pw.write(" <TD COLSPAN=\"2\">" + pattern.getDetails() + "</TD>");
- pw.write(" </TR>");
- pw.write(" </TABLE>");
- pw.write(" </P>");
+ pw.println(" <TR><TD COLSPAN=\"2\"><B>" + pattern.getShort() + "</B></TD></TR>");
+ pw.println(" <TR>");
+ pw.println(" <TD COLSPAN=\"2\">" + pattern.getDetails() + "</TD>");
+ pw.println(" </TR>");
+ pw.println(" </TABLE>");
+ pw.println(" </P>");
+ pw.println(" <HR/>");
}
}
}
// Load the list of bug patterns and categories from the FindBugs messages.xml file.
- public void load(File findBugsDir, Locale locale) throws FileNotFoundException, IOException, SAXException
+ public void load(File findBugsDir, Locale locale) throws FBMsgFileNotFoundException, IOException, SAXException
{
m_findBugsDir = findBugsDir;
}
if (! msgXml.canRead()) {
- throw new FileNotFoundException(msgXml.getAbsolutePath());
+ throw new FBMsgFileNotFoundException(msgXml.getAbsolutePath());
}
parse(new InputSource(new FileInputStream(msgXml)));
return false;
}
+ assert (null != analysis.getProjectName());
+ assert (null != analysis.getBuildNumber());
+
// ----------------------------------
// Add a run record for this analysis
--- /dev/null
+package net.jaekl.cfb.util;
+
+public class Env {
+ static volatile Env m_inst = null;
+
+ Env() {}
+
+ private static Env getInstance()
+ {
+ Env inst = m_inst;
+ if (null == inst) {
+ synchronized(Env.class) {
+ if (null == m_inst) {
+ m_inst = new Env();
+ }
+ inst = m_inst;
+ }
+ }
+ return inst;
+ }
+
+ String getEnv(String variableName) { return System.getenv(variableName); }
+
+ public static String get(String variableName) {
+ return getInstance().getEnv(variableName);
+ }
+}
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
+import java.io.StringWriter;
import java.nio.charset.Charset;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Locale;
import net.jaekl.cfb.analyze.Analysis;
+import net.jaekl.cfb.analyze.FBMsgFileNotFoundException;
import net.jaekl.cfb.analyze.MessageMap;
import net.jaekl.cfb.db.CfbSchema;
import net.jaekl.cfb.db.Column;
import net.jaekl.cfb.db.TypeMismatchException;
import net.jaekl.cfb.db.driver.DbDriverMock;
import net.jaekl.cfb.util.Command;
+import net.jaekl.cfb.util.EnvMock;
import net.jaekl.cfb.xml.MessagesXmlData;
import org.junit.Before;
assertEquals(PROJECT_NAME, row.getValue(1));
assertEquals(VERSION, row.getValue(2));
}
+
+ @Test
+ public void testTrans()
+ {
+ Object[][] data = {
+ { "hello", new Object[] {}, "[hello]" },
+ { "hello", new Object[] {"world"}, "[hello][world]"}
+ };
+
+ for (Object[] datum : data) {
+ String key = (String)datum[0];
+ Object[] params = (Object[])datum[1];
+ String expected = (String)datum[2];
+ String actual = m_cfb.trans(key, params);
+ assertEquals(expected, actual);
+ }
+ }
+
+ @Test
+ public void testReportException_FBMsgFileNotFoundException() throws IOException
+ {
+ String[][] data = {
+ {
+ "/home/fred/findbugs3.0.1", "messages.xml",
+ "[cannot.load.fbmsg.file][messages.xml]\n[findbugs.home.is.set.to][FINDBUGS_HOME][/home/fred/findbugs3.0.1]\n"
+ },
+ {
+ null, "messages.xml",
+ "[cannot.load.fbmsg.file][messages.xml]\n[findbugs.home.is.not.set][FINDBUGS_HOME]\n"
+ },
+ {
+ null, null, "[cannot.load.fbmsg.file][null]\n[findbugs.home.is.not.set][FINDBUGS_HOME]\n"
+ }
+ };
+ EnvMock envMock = EnvMock.mock_putInstance();
+
+ for (String[] datum : data)
+ {
+ String fbHome = datum[0];
+ String filename = datum[1];
+ String expected = datum[2];
+
+ try (
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ )
+ {
+ envMock.mock_putEnv(CFB.FINDBUGS_HOME, fbHome);
+ FBMsgFileNotFoundException exc = new FBMsgFileNotFoundException(filename);
+ m_cfb.reportException(pw, exc);
+
+ pw.close();
+ sw.close();
+
+ String actual = sw.toString();
+ boolean pass = actual.endsWith(expected);
+ if (!pass) {
+ System.out.println("Expected:\n" + expected + "\nActual:\n" + actual);
+ }
+ assertTrue(pass);
+ }
+ }
+ }
}
--- /dev/null
+package net.jaekl.cfb;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+public class CfbBundleTest {
+
+ @Test
+ public void testFallbackGet() {
+ Object[][] data = {
+ { "hello", new Object[] {}, "[hello]" },
+ { "hello", new Object[] {"world"}, "[hello][world]"},
+ { null, new Object[] {}, "[null]" },
+ {
+ "the.quick.brown.fox",
+ new Object[] {"jumps.over", Integer.valueOf(1), "lazy", "dog"},
+ "[the.quick.brown.fox][jumps.over][1][lazy][dog]"
+ }
+ };
+
+ CfbBundleMock bundle = new CfbBundleMock();
+
+ for (Object[] datum : data) {
+ String key = (String)datum[0];
+ Object[] params = (Object[])datum[1];
+ String expected = (String)datum[2];
+ String actual = bundle.fallbackGet(key, params);
+ assertEquals(expected, actual);
+ }
+ }
+
+}
--- /dev/null
+package net.jaekl.cfb.util;
+
+import java.util.HashMap;
+
+public class EnvMock extends Env {
+ private HashMap<String, String> m_map;
+
+ EnvMock() {
+ m_map = new HashMap<String, String>();
+ }
+
+ @Override
+ String getEnv(String variableName) {
+ if (m_map.containsKey(variableName)) {
+ return m_map.get(variableName);
+ }
+ return super.getEnv(variableName);
+ }
+
+ public static EnvMock mock_putInstance() {
+ EnvMock mock = new EnvMock();
+ m_inst = mock;
+ return mock;
+ }
+
+ public void mock_putEnv(String variableName, String value) {
+ m_map.put(variableName, value);
+ }
+}