diff options
author | Tor Norbye <tnorbye@google.com> | 2012-07-20 16:24:07 -0700 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2012-07-23 15:36:02 -0700 |
commit | a55067435f57c7a25f416ecde509d790a5e0799e (patch) | |
tree | d321798bed2dda4a85f31789aa680c47dddebac5 | |
parent | 08eecafc50dceff0e7eb6960763c2b6ca5601524 (diff) | |
download | sdk-a55067435f57c7a25f416ecde509d790a5e0799e.zip sdk-a55067435f57c7a25f416ecde509d790a5e0799e.tar.gz sdk-a55067435f57c7a25f416ecde509d790a5e0799e.tar.bz2 |
Add lint target for ant
Running "ant lint" will now run lint on the project, and dump out the
errors to the console as well as also export the errors to lint.xml
and lint.html int the bin/ directory.
This changeset also modifies the lint CLI to allow multiple
simultaneous result reporters - so you don't have to run lint twice in
order to get both an .xml and an .html report for example (which is
useful when you're running lint on a continuous integration server,
and you want the .xml file for the lint plugin trend graph and the
html file as a user readable report to click through to from the build
page.)
Change-Id: Idf8f3f5de0857eb9e7180267a066ae933640682d
-rw-r--r-- | anttasks/src/anttasks.properties | 1 | ||||
-rw-r--r-- | anttasks/src/com/android/ant/LintExecTask.java | 86 | ||||
-rw-r--r-- | files/ant/build.xml | 22 | ||||
-rw-r--r-- | lint/cli/src/com/android/tools/lint/Main.java | 73 | ||||
-rw-r--r-- | lint/cli/src/com/android/tools/lint/TextReporter.java | 8 | ||||
-rw-r--r-- | lint/cli/src/com/android/tools/lint/XmlReporter.java | 2 |
6 files changed, 176 insertions, 16 deletions
diff --git a/anttasks/src/anttasks.properties b/anttasks/src/anttasks.properties index 04047e5..78b6513 100644 --- a/anttasks/src/anttasks.properties +++ b/anttasks/src/anttasks.properties @@ -18,3 +18,4 @@ zipalign: com.android.ant.ZipAlignTask xpath: com.android.ant.XPathTask if: com.android.ant.IfElseTask propertybyreplace: com.android.ant.PropertyByReplaceTask +lint: com.android.ant.LintExecTask diff --git a/anttasks/src/com/android/ant/LintExecTask.java b/anttasks/src/com/android/ant/LintExecTask.java new file mode 100644 index 0000000..64a6c00 --- /dev/null +++ b/anttasks/src/com/android/ant/LintExecTask.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * 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.android.ant; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.taskdefs.ExecTask; +import org.apache.tools.ant.types.Path; + +/** + * Custom task to execute lint + */ +public class LintExecTask extends ExecTask { + + private String mExecutable; + private String mHtml; + private String mXml; + + /** + * Sets the value of the "executable" attribute. + * @param executable the value. + */ + public void setExecutable(Path executable) { + mExecutable = TaskHelper.checkSinglePath("executable", executable); + } + + /** + * Sets the value of the "html" attribute: a path to a file or directory name + * where the HTML report should be written. + * + * @param html path to the html report + */ + public void setHtml(Path html) { + mHtml = TaskHelper.checkSinglePath("html", html); + } + + /** + * Sets the value of the "xml" attribute: a path to a file or directory name + * where the XML report should be written. + * + * @param xml path to the xml report + */ + public void setXml(Path xml) { + mXml = TaskHelper.checkSinglePath("xml", xml); + } + + @Override + public void execute() throws BuildException { + + ExecTask task = new ExecTask(); + task.setProject(getProject()); + task.setOwningTarget(getOwningTarget()); + task.setExecutable(mExecutable); + task.setTaskName("lint"); + task.setFailonerror(true); + + task.createArg().setValue("--text"); + task.createArg().setValue("stdout"); + + if (mHtml != null) { + task.createArg().setValue("--html"); + task.createArg().setValue(mHtml); + } + + if (mXml != null) { + task.createArg().setValue("--xml"); + task.createArg().setValue(mXml); + } + + task.createArg().setValue(getProject().getBaseDir().getAbsolutePath()); + task.execute(); + } +} diff --git a/files/ant/build.xml b/files/ant/build.xml index 1ec0632..769889c 100644 --- a/files/ant/build.xml +++ b/files/ant/build.xml @@ -77,6 +77,17 @@ <!-- Verbosity --> <property name="verbose" value="false" /> + <!-- Output location of the HTML report for the "lint" target. + Ideally this would be specified as + value="${out.dir}/lint.html" + but we can't make a forward reference to the definition for + ${out.dir}, and it is not a configurable property (yet). + --> + <property name="lint.out.html" value="bin/lint.html" /> + + <!-- Output location of the XML report for the "lint" target --> + <property name="lint.out.xml" value="bin/lint.xml" /> + <!-- ******************************************************* --> <!-- ********************* Custom Tasks ******************** --> <!-- ******************************************************* --> @@ -138,6 +149,7 @@ <property name="aapt" location="${android.platform.tools.dir}/aapt${exe}" /> <property name="dx" location="${android.platform.tools.dir}/dx${bat}" /> <property name="renderscript" location="${android.platform.tools.dir}/llvm-rs-cc${exe}"/> + <property name="lint" location="${android.tools.dir}/lint${bat}" /> <!-- Renderscript include Path --> <path id="android.renderscript.include.path"> @@ -1275,6 +1287,16 @@ </if> </target> + <!-- ******************************************************* --> + <!-- ********** Run Lint on the project ********* --> + <!-- ******************************************************* --> + + <target name="lint" + description="Runs lint on the project to look for potential bugs" > + <lint executable="${lint}" + html="${lint.out.html}" + xml="${lint.out.xml}" /> + </target> <!-- ******************************************************* --> <!-- ********** Install/uninstall specific targets ********* --> diff --git a/lint/cli/src/com/android/tools/lint/Main.java b/lint/cli/src/com/android/tools/lint/Main.java index 24c7cda..5e51106 100644 --- a/lint/cli/src/com/android/tools/lint/Main.java +++ b/lint/cli/src/com/android/tools/lint/Main.java @@ -40,13 +40,17 @@ import com.android.tools.lint.detector.api.Location; import com.android.tools.lint.detector.api.Position; import com.android.tools.lint.detector.api.Project; import com.android.tools.lint.detector.api.Severity; +import com.google.common.collect.Lists; import com.google.common.io.Closeables; +import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; +import java.io.FileWriter; import java.io.IOException; import java.io.PrintStream; import java.io.PrintWriter; +import java.io.Writer; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -76,6 +80,7 @@ public class Main extends LintClient { private static final String ARG_HTML = "--html"; //$NON-NLS-1$ private static final String ARG_SIMPLEHTML = "--simplehtml"; //$NON-NLS-1$ private static final String ARG_XML = "--xml"; //$NON-NLS-1$ + private static final String ARG_TEXT = "--text"; //$NON-NLS-1$ private static final String ARG_CONFIG = "--config"; //$NON-NLS-1$ private static final String ARG_URL = "--url"; //$NON-NLS-1$ private static final String ARG_VERSION = "--version"; //$NON-NLS-1$ @@ -108,7 +113,7 @@ public class Main extends LintClient { private int mErrorCount; private int mWarningCount; private boolean mShowLines = true; - private Reporter mReporter; + private List<Reporter> mReporters = Lists.newArrayList(); private boolean mQuiet; private boolean mWarnAll; private boolean mNoWarnings; @@ -283,7 +288,7 @@ public class Main extends LintClient { if (arg.equals(ARG_SIMPLEHTML)) { reporter.setSimpleFormat(true); } - mReporter = reporter; + mReporters.add(reporter); } catch (IOException e) { log(e, null); System.exit(ERRNO_INVALIDARGS); @@ -306,7 +311,7 @@ public class Main extends LintClient { if (arg.equals(ARG_SIMPLEHTML)) { htmlReporter.setSimpleFormat(true); } - mReporter = htmlReporter; + mReporters.add(htmlReporter); } catch (IOException e) { log(e, null); System.exit(ERRNO_INVALIDARGS); @@ -329,11 +334,45 @@ public class Main extends LintClient { System.exit(ERRNO_EXISTS); } try { - mReporter = new XmlReporter(this, output); + mReporters.add(new XmlReporter(this, output)); } catch (IOException e) { log(e, null); System.exit(ERRNO_INVALIDARGS); } + } else if (arg.equals(ARG_TEXT)) { + if (index == args.length - 1) { + System.err.println("Missing XML output file name"); + System.exit(ERRNO_INVALIDARGS); + } + + Writer writer = null; + boolean closeWriter; + String outputName = args[++index]; + if (outputName.equals("stdout")) { //$NON-NLS-1$ + writer = new PrintWriter(System.out, true); + closeWriter = false; + } else { + File output = getOutArgumentPath(outputName); + if (output.exists()) { + boolean delete = output.delete(); + if (!delete) { + System.err.println("Could not delete old " + output); + System.exit(ERRNO_EXISTS); + } + } + if (output.canWrite()) { + System.err.println("Cannot write XML output file " + output); + System.exit(ERRNO_EXISTS); + } + try { + writer = new BufferedWriter(new FileWriter(output)); + } catch (IOException e) { + log(e, null); + System.exit(ERRNO_INVALIDARGS); + } + closeWriter = true; + } + mReporters.add(new TextReporter(this, writer, closeWriter)); } else if (arg.equals(ARG_DISABLE) || arg.equals(ARG_IGNORE)) { if (index == args.length - 1) { System.err.println("Missing categories or id's to disable"); @@ -438,22 +477,24 @@ public class Main extends LintClient { System.exit(ERRNO_INVALIDARGS); } - if (mReporter == null) { + if (mReporters.isEmpty()) { if (urlMap != null) { System.err.println(String.format( "Warning: The %1$s option only applies to HTML reports (%2$s)", ARG_URL, ARG_HTML)); } - mReporter = new TextReporter(this, new PrintWriter(System.out, true)); + mReporters.add(new TextReporter(this, new PrintWriter(System.out, true), false)); } else { if (urlMap == null) { // By default just map from /foo to file:///foo // TODO: Find out if we need file:// on Windows. urlMap = "=file://"; //$NON-NLS-1$ } else { - if (!mReporter.isSimpleFormat()) { - mReporter.setBundleResources(true); + for (Reporter reporter : mReporters) { + if (!reporter.isSimpleFormat()) { + reporter.setBundleResources(true); + } } } @@ -472,7 +513,9 @@ public class Main extends LintClient { String value = s.substring(index + 1); map.put(key, value); } - mReporter.setUrlMap(map); + for (Reporter reporter : mReporters) { + reporter.setUrlMap(map); + } } } @@ -487,11 +530,13 @@ public class Main extends LintClient { Collections.sort(mWarnings); - try { - mReporter.write(mErrorCount, mWarningCount, mWarnings); - } catch (IOException e) { - log(e, null); - System.exit(ERRNO_INVALIDARGS); + for (Reporter reporter : mReporters) { + try { + reporter.write(mErrorCount, mWarningCount, mWarnings); + } catch (IOException e) { + log(e, null); + System.exit(ERRNO_INVALIDARGS); + } } System.exit(mSetExitCode ? (mHasErrors ? ERRNO_ERRORS : 0) : 0); diff --git a/lint/cli/src/com/android/tools/lint/TextReporter.java b/lint/cli/src/com/android/tools/lint/TextReporter.java index 63ee857..7bce91f 100644 --- a/lint/cli/src/com/android/tools/lint/TextReporter.java +++ b/lint/cli/src/com/android/tools/lint/TextReporter.java @@ -33,16 +33,19 @@ import java.util.List; @Beta public class TextReporter extends Reporter { private final Writer mWriter; + private final boolean mClose; /** * Constructs a new {@link TextReporter} * * @param client the client * @param writer the writer to write into + * @param close whether the writer should be closed when done */ - public TextReporter(Main client, Writer writer) { + public TextReporter(Main client, Writer writer, boolean close) { super(client, null); mWriter = writer; + mClose = close; } @Override @@ -161,6 +164,9 @@ public class TextReporter extends Reporter { errorCount, warningCount)); mWriter.write('\n'); mWriter.flush(); + if (mClose) { + mWriter.close(); + } } } }
\ No newline at end of file diff --git a/lint/cli/src/com/android/tools/lint/XmlReporter.java b/lint/cli/src/com/android/tools/lint/XmlReporter.java index 03fc937..f924def 100644 --- a/lint/cli/src/com/android/tools/lint/XmlReporter.java +++ b/lint/cli/src/com/android/tools/lint/XmlReporter.java @@ -111,7 +111,7 @@ public class XmlReporter extends Reporter { mWriter.close(); String path = mOutput.getAbsolutePath(); - System.out.println(String.format("Wrote HTML report to %1$s", path)); + System.out.println(String.format("Wrote XML report to %1$s", path)); } private static void writeAttribute(Writer writer, int indent, String name, String value) |