if (args.length < 1) {
printUsage(System.err);
System.exit(ERRNO_USAGE);
}
IssueRegistry registry = new BuiltinIssueRegistry();
// When running lint from the command line, warn if the project is a Gradle project
// since those projects may have custom project configuration that the command line
// runner won't know about.
LintCliClient client = new LintCliClient(mFlags) {
@NonNull
@Override
protected Project createProject(@NonNull File dir, @NonNull File referenceDir) {
Project project = super.createProject(dir, referenceDir);
if (project.isGradleProject()) {
@SuppressWarnings("SpellCheckingInspection")
String message = String.format("\"%1$s\" is a Gradle project. To correctly "
+ "analyze Gradle projects, you should run \"gradlew :lint\" instead.",
project.getName());
Location location = Location.create(project.getDir());
Context context = new Context(mDriver, project, project, project.getDir());
if (context.isEnabled(IssueRegistry.LINT_ERROR)) {
report(context,
IssueRegistry.LINT_ERROR,
project.getConfiguration().getSeverity(IssueRegistry.LINT_ERROR),
location, message, null);
}
}
return project;
}
};
// Mapping from file path prefix to URL. Applies only to HTML reports
String urlMap = null;
List<File> files = new ArrayList<File>();
for (int index = 0; index < args.length; index++) {
String arg = args[index];
if (arg.equals(ARG_HELP)
|| arg.equals("-h") || arg.equals("-?")) { //$NON-NLS-1$ //$NON-NLS-2$
if (index < args.length - 1) {
String topic = args[index + 1];
if (topic.equals("suppress") || topic.equals("ignore")) {
printHelpTopicSuppress();
System.exit(ERRNO_HELP);
} else {
System.err.println(String.format("Unknown help topic \"%1$s\"", topic));
System.exit(ERRNO_INVALID_ARGS);
}
}
printUsage(System.out);
System.exit(ERRNO_HELP);
} else if (arg.equals(ARG_LIST_IDS)) {
// Did the user provide a category list?
if (index < args.length - 1 && !args[index + 1].startsWith("-")) { //$NON-NLS-1$
String[] ids = args[++index].split(",");
for (String id : ids) {
if (registry.isCategoryName(id)) {
// List all issues with the given category
String category = id;
for (Issue issue : registry.getIssues()) {
// Check prefix such that filtering on the "Usability" category
// will match issue category "Usability:Icons" etc.
if (issue.getCategory().getName().startsWith(category) ||
issue.getCategory().getFullName().startsWith(category)) {
listIssue(System.out, issue);
}
}
} else {
System.err.println("Invalid category \"" + id + "\".\n");
displayValidIds(registry, System.err);
System.exit(ERRNO_INVALID_ARGS);
}
}
} else {
displayValidIds(registry, System.out);
}
System.exit(ERRNO_SUCCESS);
} else if (arg.equals(ARG_SHOW)) {
// Show specific issues?
if (index < args.length - 1 && !args[index + 1].startsWith("-")) { //$NON-NLS-1$
String[] ids = args[++index].split(",");
for (String id : ids) {
if (registry.isCategoryName(id)) {
// Show all issues in the given category
String category = id;
for (Issue issue : registry.getIssues()) {
// Check prefix such that filtering on the "Usability" category
// will match issue category "Usability:Icons" etc.
if (issue.getCategory().getName().startsWith(category) ||
issue.getCategory().getFullName().startsWith(category)) {
describeIssue(issue);
System.out.println();
}
}
} else if (registry.isIssueId(id)) {
describeIssue(registry.getIssue(id));
System.out.println();
} else {
System.err.println("Invalid id or category \"" + id + "\".\n");
displayValidIds(registry, System.err);
System.exit(ERRNO_INVALID_ARGS);
}
}
} else {
showIssues(registry);
}
System.exit(ERRNO_SUCCESS);
} else if (arg.equals(ARG_FULL_PATH)
|| arg.equals(ARG_FULL_PATH + "s")) { // allow "--fullpaths" too
mFlags.setFullPath(true);
} else if (arg.equals(ARG_SHOW_ALL)) {
mFlags.setShowEverything(true);
} else if (arg.equals(ARG_QUIET) || arg.equals("-q")) {
mFlags.setQuiet(true);
} else if (arg.equals(ARG_NO_LINES)) {
mFlags.setShowSourceLines(false);
} else if (arg.equals(ARG_EXIT_CODE)) {
mFlags.setSetExitCode(true);
} else if (arg.equals(ARG_VERSION)) {
printVersion(client);
System.exit(ERRNO_SUCCESS);
} else if (arg.equals(ARG_URL)) {
if (index == args.length - 1) {
System.err.println("Missing URL mapping string");
System.exit(ERRNO_INVALID_ARGS);
}
String map = args[++index];
// Allow repeated usage of the argument instead of just comma list
if (urlMap != null) {
urlMap = urlMap + ',' + map;
} else {
urlMap = map;
}
} else if (arg.equals(ARG_CONFIG)) {
if (index == args.length - 1 || !endsWith(args[index + 1], DOT_XML)) {
System.err.println("Missing XML configuration file argument");
System.exit(ERRNO_INVALID_ARGS);
}
File file = getInArgumentPath(args[++index]);
if (!file.exists()) {
System.err.println(file.getAbsolutePath() + " does not exist");
System.exit(ERRNO_INVALID_ARGS);
}
mFlags.setDefaultConfiguration(file);
} else if (arg.equals(ARG_HTML) || arg.equals(ARG_SIMPLE_HTML)) {
if (index == args.length - 1) {
System.err.println("Missing HTML output file name");
System.exit(ERRNO_INVALID_ARGS);
}
File output = getOutArgumentPath(args[++index]);
// Get an absolute path such that we can ask its parent directory for
// write permission etc.
output = output.getAbsoluteFile();
if (output.isDirectory() ||
(!output.exists() && output.getName().indexOf('.') == -1)) {
if (!output.exists()) {
boolean mkdirs = output.mkdirs();
if (!mkdirs) {
log(null, "Could not create output directory %1$s", output);
System.exit(ERRNO_EXISTS);
}
}
try {
MultiProjectHtmlReporter reporter =
new MultiProjectHtmlReporter(client, output);
if (arg.equals(ARG_SIMPLE_HTML)) {
reporter.setSimpleFormat(true);
}
mFlags.getReporters().add(reporter);
} catch (IOException e) {
log(e, null);
System.exit(ERRNO_INVALID_ARGS);
}
continue;
}
if (output.exists()) {
boolean delete = output.delete();
if (!delete) {
System.err.println("Could not delete old " + output);
System.exit(ERRNO_EXISTS);
}
}
if (output.getParentFile() != null && !output.getParentFile().canWrite()) {
System.err.println("Cannot write HTML output file " + output);
System.exit(ERRNO_EXISTS);
}
try {
HtmlReporter htmlReporter = new HtmlReporter(client, output);
if (arg.equals(ARG_SIMPLE_HTML)) {
htmlReporter.setSimpleFormat(true);
}
mFlags.getReporters().add(htmlReporter);
} catch (IOException e) {
log(e, null);
System.exit(ERRNO_INVALID_ARGS);
}
} else if (arg.equals(ARG_XML)) {
if (index == args.length - 1) {
System.err.println("Missing XML output file name");
System.exit(ERRNO_INVALID_ARGS);
}
File output = getOutArgumentPath(args[++index]);
// Get an absolute path such that we can ask its parent directory for
// write permission etc.
output = output.getAbsoluteFile();
if (output.exists()) {
boolean delete = output.delete();
if (!delete) {
System.err.println("Could not delete old " + output);
System.exit(ERRNO_EXISTS);
}
}
if (output.getParentFile() != null && !output.getParentFile().canWrite()) {
System.err.println("Cannot write XML output file " + output);
System.exit(ERRNO_EXISTS);
}
try {
mFlags.getReporters().add(new XmlReporter(client, output));
} catch (IOException e) {
log(e, null);
System.exit(ERRNO_INVALID_ARGS);
}
} else if (arg.equals(ARG_TEXT)) {
if (index == args.length - 1) {
System.err.println("Missing text output file name");
System.exit(ERRNO_INVALID_ARGS);
}
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);
// Get an absolute path such that we can ask its parent directory for
// write permission etc.
output = output.getAbsoluteFile();
if (output.exists()) {
boolean delete = output.delete();
if (!delete) {
System.err.println("Could not delete old " + output);
System.exit(ERRNO_EXISTS);
}
}
if (output.getParentFile() != null && !output.getParentFile().canWrite()) {
System.err.println("Cannot write text output file " + output);
System.exit(ERRNO_EXISTS);
}
try {
writer = new BufferedWriter(new FileWriter(output));
} catch (IOException e) {
log(e, null);
System.exit(ERRNO_INVALID_ARGS);
}
closeWriter = true;
}
mFlags.getReporters().add(new TextReporter(client, mFlags, 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");
System.exit(ERRNO_INVALID_ARGS);
}
String[] ids = args[++index].split(",");
for (String id : ids) {
if (registry.isCategoryName(id)) {
// Suppress all issues with the given category
String category = id;
for (Issue issue : registry.getIssues()) {
// Check prefix such that filtering on the "Usability" category
// will match issue category "Usability:Icons" etc.
if (issue.getCategory().getName().startsWith(category) ||
issue.getCategory().getFullName().startsWith(category)) {
mFlags.getSuppressedIds().add(issue.getId());
}
}
} else if (!registry.isIssueId(id)) {
System.err.println("Invalid id or category \"" + id + "\".\n");
displayValidIds(registry, System.err);
System.exit(ERRNO_INVALID_ARGS);
} else {
mFlags.getSuppressedIds().add(id);
}
}
} else if (arg.equals(ARG_ENABLE)) {
if (index == args.length - 1) {
System.err.println("Missing categories or id's to enable");
System.exit(ERRNO_INVALID_ARGS);
}
String[] ids = args[++index].split(",");
for (String id : ids) {
if (registry.isCategoryName(id)) {
// Enable all issues with the given category
String category = id;
for (Issue issue : registry.getIssues()) {
if (issue.getCategory().getName().startsWith(category) ||
issue.getCategory().getFullName().startsWith(category)) {
mFlags.getEnabledIds().add(issue.getId());
}
}
} else if (!registry.isIssueId(id)) {
System.err.println("Invalid id or category \"" + id + "\".\n");
displayValidIds(registry, System.err);
System.exit(ERRNO_INVALID_ARGS);
} else {
mFlags.getEnabledIds().add(id);
}
}
} else if (arg.equals(ARG_CHECK)) {
if (index == args.length - 1) {
System.err.println("Missing categories or id's to check");
System.exit(ERRNO_INVALID_ARGS);
}
Set<String> checkedIds = mFlags.getExactCheckedIds();
if (checkedIds == null) {
checkedIds = new HashSet<String>();
mFlags.setExactCheckedIds(checkedIds);
}
String[] ids = args[++index].split(",");
for (String id : ids) {
if (registry.isCategoryName(id)) {
// Check all issues with the given category
String category = id;
for (Issue issue : registry.getIssues()) {
// Check prefix such that filtering on the "Usability" category
// will match issue category "Usability:Icons" etc.
if (issue.getCategory().getName().startsWith(category) ||
issue.getCategory().getFullName().startsWith(category)) {
checkedIds.add(issue.getId());
}
}
} else if (!registry.isIssueId(id)) {
System.err.println("Invalid id or category \"" + id + "\".\n");
displayValidIds(registry, System.err);
System.exit(ERRNO_INVALID_ARGS);
} else {
checkedIds.add(id);