Add checkstyle to find missing docs, fix missing docs

This commit is contained in:
Havoc Pennington 2015-03-06 20:17:39 -05:00
parent 7914406ebf
commit 59a7c00725
7 changed files with 372 additions and 6 deletions

View File

@ -4,6 +4,7 @@ import de.johoop.jacoco4sbt.JacocoPlugin.jacoco
import com.typesafe.sbt.SbtScalariform
import com.typesafe.sbt.SbtScalariform.ScalariformKeys
import scalariform.formatter.preferences._
import com.etsy.sbt.Checkstyle._
SbtScalariform.scalariformSettings
@ -25,6 +26,46 @@ libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test"
externalResolvers += "Scala Tools Snapshots" at "http://scala-tools.org/repo-snapshots/"
checkstyleSettings
CheckstyleTasks.checkstyleConfig := baseDirectory.value / "checkstyle-config.xml"
CheckstyleTasks.checkstyle in Compile := {
val log = streams.value.log
(CheckstyleTasks.checkstyle in Compile).value
val resultFile = (target in Compile).value / "checkstyle-report.xml"
val results = scala.xml.XML.loadFile(resultFile)
val errorFiles = results \\ "checkstyle" \\ "file"
def errorFromXml(node: scala.xml.NodeSeq): (String, String, String) = {
val line: String = (node \ "@line" text)
val msg: String = (node \ "@message" text)
val source: String = (node \ "@source" text)
(line, msg, source)
}
def errorsFromXml(fileNode: scala.xml.NodeSeq): Seq[(String, String, String, String)] = {
val name: String = (fileNode \ "@name" text)
val errors = (fileNode \\ "error") map { e => errorFromXml(e) }
errors map { case (line, error, source) => (name, line, error, source) }
}
val errors = errorFiles flatMap { f => errorsFromXml(f) }
if (errors.nonEmpty) {
for (e <- errors) {
log.error(s"${e._1}:${e._2}: ${e._3} (from ${e._4})")
}
throw new RuntimeException(s"Checkstyle failed with ${errors.size} errors")
}
log.info("No errors from checkstyle")
}
// add checkstyle as a dependency of doc
doc in Compile := {
(CheckstyleTasks.checkstyle in Compile).value
(doc in Compile).value
}
findbugsSettings
findbugsReportType := Some(ReportType.Html)
findbugsReportName := Some("findbugs.html")

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<module name="Checker">
<module name="SuppressionFilter">
<property name="file" value="config/checkstyle-suppressions.xml"/>
</module>
<module name="TreeWalker">
<module name="JavadocType">
<property name="scope" value="public"/>
</module>
<module name="JavadocMethod">
<property name="scope" value="public"/>
</module>
<module name="JavadocStyle">
<property name="scope" value="public"/>
</module>
</module>
</module>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suppressions PUBLIC "-//Puppy Crawl//DTD Suppressions 1.1//EN"
"http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
<suppressions>
<!-- don't care about javadoc coverage of methods in impl -->
<suppress checks="JavadocMethod"
files="com[\\/]typesafe[\\/]config[\\/]impl[\\/]"/>
<!-- ConfigException has a bunch of constructors that are
self-evident and would clutter the heck out of the file
to document -->
<suppress checks="JavadocMethod"
files="com[\\/]typesafe[\\/]config[\\/]ConfigException.java"/>
</suppressions>

View File

@ -723,24 +723,154 @@ public interface Config extends ConfigMergeable {
*/
ConfigList getList(String path);
/**
* Gets a list value with boolean elements. Throws if the
* path is unset or null or not a list or contains values not
* convertible to boolean.
*
* @param path
* the path to the list value.
* @return the list at the path
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType
* if value is not convertible to a list of booleans
*/
List<Boolean> getBooleanList(String path);
/**
* Gets a list value with number elements. Throws if the
* path is unset or null or not a list or contains values not
* convertible to number.
*
* @param path
* the path to the list value.
* @return the list at the path
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType
* if value is not convertible to a list of numbers
*/
List<Number> getNumberList(String path);
/**
* Gets a list value with int elements. Throws if the
* path is unset or null or not a list or contains values not
* convertible to int.
*
* @param path
* the path to the list value.
* @return the list at the path
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType
* if value is not convertible to a list of ints
*/
List<Integer> getIntList(String path);
/**
* Gets a list value with long elements. Throws if the
* path is unset or null or not a list or contains values not
* convertible to long.
*
* @param path
* the path to the list value.
* @return the list at the path
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType
* if value is not convertible to a list of longs
*/
List<Long> getLongList(String path);
/**
* Gets a list value with double elements. Throws if the
* path is unset or null or not a list or contains values not
* convertible to double.
*
* @param path
* the path to the list value.
* @return the list at the path
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType
* if value is not convertible to a list of doubles
*/
List<Double> getDoubleList(String path);
/**
* Gets a list value with string elements. Throws if the
* path is unset or null or not a list or contains values not
* convertible to string.
*
* @param path
* the path to the list value.
* @return the list at the path
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType
* if value is not convertible to a list of strings
*/
List<String> getStringList(String path);
/**
* Gets a list value with object elements. Throws if the
* path is unset or null or not a list or contains values not
* convertible to <code>ConfigObject</code>.
*
* @param path
* the path to the list value.
* @return the list at the path
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType
* if value is not convertible to a list of objects
*/
List<? extends ConfigObject> getObjectList(String path);
/**
* Gets a list value with <code>Config</code> elements.
* Throws if the path is unset or null or not a list or
* contains values not convertible to <code>Config</code>.
*
* @param path
* the path to the list value.
* @return the list at the path
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType
* if value is not convertible to a list of configs
*/
List<? extends Config> getConfigList(String path);
/**
* Gets a list value with any kind of elements. Throws if the
* path is unset or null or not a list. Each element is
* "unwrapped" (see {@link ConfigValue#unwrapped()}).
*
* @param path
* the path to the list value.
* @return the list at the path
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType
* if value is not convertible to a list
*/
List<? extends Object> getAnyRefList(String path);
/**
* Gets a list value with elements representing a size in
* bytes. Throws if the path is unset or null or not a list
* or contains values not convertible to memory sizes.
*
* @param path
* the path to the list value.
* @return the list at the path
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType
* if value is not convertible to a list of memory sizes
*/
List<Long> getBytesList(String path);
/**
@ -751,6 +881,10 @@ public interface Config extends ConfigMergeable {
* @param path
* a path expression
* @return list of memory sizes
* @throws ConfigException.Missing
* if value is absent or null
* @throws ConfigException.WrongType
* if value is not convertible to a list of memory sizes
*/
List<ConfigMemorySize> getMemorySizeList(String path);

View File

@ -167,6 +167,16 @@ public final class ConfigFactory {
return load(checkedContextClassLoader("load"), config);
}
/**
* Like {@link #load(Config)} but allows you to specify
* the class loader for looking up resources.
*
* @param loader
* the class loader to use to find resources
* @param config
* the application's portion of the configuration
* @return resolved configuration with overrides and fallbacks added
*/
public static Config load(ClassLoader loader, Config config) {
return load(loader, config, ConfigResolveOptions.defaults());
}
@ -269,7 +279,7 @@ public final class ConfigFactory {
}
/**
* Like {@link #load()} but allows specifying parse options
* Like {@link #load()} but allows specifying parse options.
*
* @param parseOptions
* Options for parsing resources
@ -299,7 +309,7 @@ public final class ConfigFactory {
/**
* Like {@link #load()} but allows specifying a class loader other than the
* thread's current context class loader, and parse options
* thread's current context class loader and also specify parse options.
*
* @param loader
* class loader for finding resources (overrides any loader in parseOptions)
@ -313,7 +323,7 @@ public final class ConfigFactory {
/**
* Like {@link #load()} but allows specifying a class loader other than the
* thread's current context class loader, and resolve options
* thread's current context class loader and also specify resolve options.
*
* @param loader
* class loader for finding resources
@ -328,7 +338,7 @@ public final class ConfigFactory {
/**
* Like {@link #load()} but allows specifying a class loader other than the
* thread's current context class loader, parse options, and resolve options
* thread's current context class loader, parse options, and resolve options.
*
* @param loader
* class loader for finding resources (overrides any loader in parseOptions)
@ -628,22 +638,79 @@ public final class ConfigFactory {
return Parseable.newProperties(properties, options).parse().toConfig();
}
/**
* Like {@link parseProperties(Properties, ConfigParseOptions)} but uses default
* parse options.
* @param properties
* a Java Properties object
* @return the parsed configuration
*/
public static Config parseProperties(Properties properties) {
return parseProperties(properties, ConfigParseOptions.defaults());
}
/**
* Parses a Reader into a Config instance. Does not call
* {@link Config#resolve} or merge the parsed stream with any
* other configuration; this method parses a single stream and
* does nothing else. It does process "include" statements in
* the parsed stream, and may end up doing other IO due to those
* statements.
*
* @param reader
* the reader to parse
* @param options
* parse options to control how the reader is interpreted
* @return the parsed configuration
* @throws ConfigException on IO or parse errors
*/
public static Config parseReader(Reader reader, ConfigParseOptions options) {
return Parseable.newReader(reader, options).parse().toConfig();
}
/**
* Parses a reader into a Config instance as with
* {@link #parseReader(Reader,ConfigParseOptions)} but always uses the
* default parse options.
*
* @param reader
* the reader to parse
* @return the parsed configuration
* @throws ConfigException on IO or parse errors
*/
public static Config parseReader(Reader reader) {
return parseReader(reader, ConfigParseOptions.defaults());
}
/**
* Parses a URL into a Config instance. Does not call
* {@link Config#resolve} or merge the parsed stream with any
* other configuration; this method parses a single stream and
* does nothing else. It does process "include" statements in
* the parsed stream, and may end up doing other IO due to those
* statements.
*
* @param url
* the url to parse
* @param options
* parse options to control how the url is interpreted
* @return the parsed configuration
* @throws ConfigException on IO or parse errors
*/
public static Config parseURL(URL url, ConfigParseOptions options) {
return Parseable.newURL(url, options).parse().toConfig();
}
/**
* Parses a url into a Config instance as with
* {@link #parseURL(URL,ConfigParseOptions)} but always uses the
* default parse options.
*
* @param url
* the url to parse
* @return the parsed configuration
* @throws ConfigException on IO or parse errors
*/
public static Config parseURL(URL url) {
return parseURL(url, ConfigParseOptions.defaults());
}
@ -766,6 +833,19 @@ public final class ConfigFactory {
.toConfig();
}
/**
* Like {@link #parseResources(Class,String,ConfigParseOptions)} but always uses
* default parse options.
*
* @param klass
* <code>klass.getClassLoader()</code> will be used to load
* resources, and non-absolute resource names will have this
* class's package added
* @param resource
* resource to look up, relative to <code>klass</code>'s package
* or absolute starting with a "/"
* @return the parsed configuration
*/
public static Config parseResources(Class<?> klass, String resource) {
return parseResources(klass, resource, ConfigParseOptions.defaults());
}
@ -806,6 +886,19 @@ public final class ConfigFactory {
options).toConfig();
}
/**
* Like {@link #parseResourcesAnySyntax(Class,String,ConfigParseOptions)}
* but always uses default parse options.
*
* @param klass
* <code>klass.getClassLoader()</code> will be used to load
* resources, and non-absolute resource names will have this
* class's package added
* @param resourceBasename
* a resource name as in {@link java.lang.Class#getResource},
* with or without extension
* @return the parsed configuration
*/
public static Config parseResourcesAnySyntax(Class<?> klass, String resourceBasename) {
return parseResourcesAnySyntax(klass, resourceBasename, ConfigParseOptions.defaults());
}
@ -837,6 +930,16 @@ public final class ConfigFactory {
return parseResources(resource, options.setClassLoader(loader));
}
/**
* Like {@link #parseResources(ClassLoader,String,ConfigParseOptions)} but always uses
* default parse options.
*
* @param loader
* will be used to load resources
* @param resource
* resource to look up in the loader
* @return the parsed configuration
*/
public static Config parseResources(ClassLoader loader, String resource) {
return parseResources(loader, resource, ConfigParseOptions.defaults());
}
@ -870,6 +973,18 @@ public final class ConfigFactory {
.toConfig();
}
/**
* Like {@link #parseResourcesAnySyntax(ClassLoader,String,ConfigParseOptions)} but always uses
* default parse options.
*
* @param loader
* will be used to load resources
* @param resourceBasename
* a resource name as in
* {@link java.lang.ClassLoader#getResource}, with or without
* extension
* @return the parsed configuration
*/
public static Config parseResourcesAnySyntax(ClassLoader loader, String resourceBasename) {
return parseResourcesAnySyntax(loader, resourceBasename, ConfigParseOptions.defaults());
}

View File

@ -36,6 +36,12 @@ public final class ConfigParseOptions {
this.classLoader = classLoader;
}
/**
* Gets an instance of <code>ConfigParseOptions</code> with all fields
* set to the default values. Start with this instance and make any
* changes you need.
* @return the default parse options
*/
public static ConfigParseOptions defaults() {
return new ConfigParseOptions(null, null, true, null, null);
}
@ -56,6 +62,10 @@ public final class ConfigParseOptions {
this.includer, this.classLoader);
}
/**
* Gets the current syntax option, which may be null for "any".
* @return the current syntax or null
*/
public ConfigSyntax getSyntax() {
return syntax;
}
@ -82,6 +92,10 @@ public final class ConfigParseOptions {
this.includer, this.classLoader);
}
/**
* Gets the current origin description, which may be null for "automatic".
* @return the current origin description or null
*/
public String getOriginDescription() {
return originDescription;
}
@ -110,12 +124,17 @@ public final class ConfigParseOptions {
this.includer, this.classLoader);
}
/**
* Gets the current "allow missing" flag.
* @return whether we allow missing files
*/
public boolean getAllowMissing() {
return allowMissing;
}
/**
* Set a ConfigIncluder which customizes how includes are handled.
* Set a {@link ConfigIncluder} which customizes how includes are handled.
* null means to use the default includer.
*
* @param includer the includer to use or null for default
* @return new version of the parse options with different includer
@ -128,6 +147,15 @@ public final class ConfigParseOptions {
includer, this.classLoader);
}
/**
* Prepends a {@link ConfigIncluder} which customizes how
* includes are handled. To prepend your includer, the
* library calls {@link ConfigIncluder#withFallback} on your
* includer to append the existing includer to it.
*
* @param includer the includer to prepend (may not be null)
* @return new version of the parse options with different includer
*/
public ConfigParseOptions prependIncluder(ConfigIncluder includer) {
if (includer == null)
throw new NullPointerException("null includer passed to prependIncluder");
@ -139,6 +167,14 @@ public final class ConfigParseOptions {
return setIncluder(includer);
}
/**
* Appends a {@link ConfigIncluder} which customizes how
* includes are handled. To append, the library calls {@link
* ConfigIncluder#withFallback} on the existing includer.
*
* @param includer the includer to append (may not be null)
* @return new version of the parse options with different includer
*/
public ConfigParseOptions appendIncluder(ConfigIncluder includer) {
if (includer == null)
throw new NullPointerException("null includer passed to appendIncluder");
@ -150,6 +186,10 @@ public final class ConfigParseOptions {
return setIncluder(includer);
}
/**
* Gets the current includer (will be null for the default includer).
* @return current includer or null
*/
public ConfigIncluder getIncluder() {
return includer;
}

View File

@ -4,6 +4,8 @@ addSbtPlugin("com.typesafe.sbt" % "sbt-pgp" % "0.8.1")
addSbtPlugin("com.typesafe.sbt" % "sbt-osgi" % "0.6.0")
addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.2.1")
addSbtPlugin("com.etsy" % "sbt-checkstyle-plugin" % "0.4.1")
resolvers += "jgit-repo" at "http://download.eclipse.org/jgit/maven"
addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "0.6.2")
addSbtPlugin("com.typesafe.sbt" % "sbt-javaversioncheck" % "0.1.0")