1
2
3
4 package net.sourceforge.pmd.cli;
5
6 import java.util.Properties;
7
8 import net.sourceforge.pmd.PMD;
9 import net.sourceforge.pmd.lang.Language;
10 import net.sourceforge.pmd.PropertyDescriptor;
11 import net.sourceforge.pmd.lang.LanguageVersion;
12 import net.sourceforge.pmd.renderers.Renderer;
13 import net.sourceforge.pmd.renderers.RendererFactory;
14
15 import com.beust.jcommander.JCommander;
16 import com.beust.jcommander.ParameterException;
17
18
19
20
21
22 public class PMDCommandLineInterface {
23
24 private static JCommander jcommander = null;
25 public static final String PROG_NAME = "pmd";
26
27 public static final String NO_EXIT_AFTER_RUN = "net.sourceforge.pmd.cli.noExit";
28 public static final String STATUS_CODE_PROPERTY = "net.sourceforge.pmd.cli.status";
29
30 public static PMDParameters extractParameters(PMDParameters arguments, String[] args, String progName) {
31 try {
32 jcommander = new JCommander(arguments, args);
33 jcommander.setProgramName(progName);
34 if (arguments.isHelp()) {
35 jcommander.usage();
36 System.exit(0);
37 }
38 } catch (ParameterException e) {
39 System.out.println(buildUsageText());
40 System.out.println(e.getMessage());
41 }
42 return arguments;
43 }
44
45 public static String buildUsageText() {
46 final String launchCmd = "java -jar " + jarName();
47
48 StringBuilder usage = new StringBuilder();
49
50 String allCommandsDescription = null;
51 if ( jcommander != null && jcommander.getCommands() != null ) {
52 for ( String command : jcommander.getCommands().keySet() )
53 allCommandsDescription += jcommander.getCommandDescription(command) + PMD.EOL;
54 }
55
56
57 String fullText = PMD.EOL
58 + "Mandatory arguments:" + PMD.EOL
59 + "1) A java source code filename or directory" + PMD.EOL
60 + "2) A report format " + PMD.EOL
61 + "3) A ruleset filename or a comma-delimited string of ruleset filenames" + PMD.EOL
62 + PMD.EOL
63 + "For example: " + PMD.EOL
64 + "c:\\> " + launchCmd + "-d c:\\my\\source\\code -f html -R java-unusedcode" + PMD.EOL
65 + PMD.EOL;
66
67 fullText += supportedVersions() + PMD.EOL;
68
69 if ( allCommandsDescription != null ) {
70 fullText += "Optional arguments that may be put before or after the mandatory arguments: " + PMD.EOL
71 + allCommandsDescription + PMD.EOL;
72 }
73
74 fullText += "Available report formats and their configuration properties are:" + PMD.EOL
75 + getReports() + PMD.EOL
76 + getExamples(launchCmd) + PMD.EOL
77 + PMD.EOL + PMD.EOL;
78
79 return fullText += usage.toString();
80 }
81
82 private static String getExamples(String launchCmd) {
83 return getWindowsExample(launchCmd) + getUnixExample(launchCmd);
84 }
85
86 private static String getWindowsExample(String launchCmd) {
87 final String WINDOWS_PROMPT = "c:\\> ";
88 final String WINDOWS_PATH_TO_CODE = "c:\\my\\source\\code";
89
90 return "For example on windows: " + PMD.EOL
91 + WINDOWS_PROMPT + launchCmd + " -dir" + WINDOWS_PATH_TO_CODE + "-format text -R java-unusedcode,java-imports -version 1.5 -language java -debug" + PMD.EOL
92 + WINDOWS_PROMPT + launchCmd + " -dir" + WINDOWS_PATH_TO_CODE + "-f xml -rulesets java-basic,java-design -encoding UTF-8" + PMD.EOL
93 + WINDOWS_PROMPT + launchCmd + " -d" + WINDOWS_PATH_TO_CODE + "-rulesets java-typeresolution -auxclasspath commons-collections.jar;derby.jar" + PMD.EOL
94 + WINDOWS_PROMPT + launchCmd + " -d" + WINDOWS_PATH_TO_CODE + "-f html -R java-typeresolution -auxclasspath -d file:///C:/my/classpathfile" + PMD.EOL
95 + PMD.EOL;
96 }
97
98 private static String getUnixExample(String launchCmd) {
99 final String UNIX_PROMPT = "$ ";
100 return "For example on *nix: " + PMD.EOL
101 + UNIX_PROMPT + launchCmd + " -dir /home/workspace/src/main/java/code -f nicehtml -rulesets java-basic,java-design" + PMD.EOL
102 + UNIX_PROMPT + launchCmd + " -d ./src/main/java/code -f nicehtml -r java-basic,java-design -xslt my-own.xsl" + PMD.EOL
103 + UNIX_PROMPT + launchCmd + " -d ./src/main/java/code -f nicehtml -r java-typeresolution -auxclasspath commons-collections.jar:derby.jar"
104 + PMD.EOL;
105 }
106
107 private static String supportedVersions() {
108 return "Languages and version suported:" + PMD.EOL +
109 Language.commaSeparatedTerseNames(Language.findWithRuleSupport()) + PMD.EOL +
110 "Note that some language are not supported by PMD - only by CPD" + PMD.EOL;
111 }
112
113
114
115
116
117
118 public static void main(String[] args) {
119 System.out.println(PMDCommandLineInterface.buildUsageText());
120 }
121
122 public static String jarName() {
123 return "pmd-" + PMD.VERSION + ".jar";
124 }
125
126 private static String getReports() {
127 StringBuilder buf = new StringBuilder();
128 for (String reportName : RendererFactory.REPORT_FORMAT_TO_RENDERER.keySet()) {
129 Renderer renderer = RendererFactory.createRenderer(reportName, new Properties());
130 buf.append(" ").append(reportName).append(": ");
131 if (!reportName.equals(renderer.getName())) {
132 buf.append(" Deprecated alias for '" + renderer.getName()).append(PMD.EOL);
133 continue;
134 }
135 buf.append(renderer.getDescription()).append(PMD.EOL);
136
137 for (PropertyDescriptor<?> property : renderer.getPropertyDescriptors()) {
138 buf.append(" ").append(property.name()).append(" - ");
139 buf.append(property.description());
140 Object deflt = property.defaultValue();
141 if (deflt != null) buf.append(" default: ").append(deflt);
142 buf.append(PMD.EOL);
143 }
144
145
146 }
147 return buf.toString();
148 }
149
150 public static void run(String[] args) {
151 if ( isExitAfterRunSet() )
152 System.exit(PMD.run(args));
153 else
154 setStatusCode(PMD.run(args));
155 }
156
157 private static boolean isExitAfterRunSet() {
158 return (System.getenv(NO_EXIT_AFTER_RUN) == null ? false : true);
159 }
160
161 private static void setStatusCode(int statusCode) {
162 System.setProperty(STATUS_CODE_PROPERTY, Integer.toString(statusCode));
163 }
164
165 }