forked from phoedos/pmd
Merge pull request #4843 from adangel/cli-banner-display
[cli] Display pmd banner, version improvement, logging
This commit is contained in:
commit
daa741c817
@ -39,7 +39,7 @@ See also [Getting Started](https://docs.pmd-code.org/latest/pmd_userdocs_install
|
||||
|
||||
**Demo:**
|
||||
|
||||
This shows how PMD can detect for loops, that can be replaced by for-each loops.
|
||||
This shows how PMD analyses [openjdk](https://github.com/openjdk/jdk):
|
||||
|
||||
![Demo](docs/images/userdocs/pmd-demo.gif)
|
||||
|
||||
|
31
docs/images/userdocs/README.md
Normal file
31
docs/images/userdocs/README.md
Normal file
@ -0,0 +1,31 @@
|
||||
## How to create pmd-demo.gif
|
||||
|
||||
### Prepare
|
||||
|
||||
```shell
|
||||
mkdir $HOME/pmd-demo
|
||||
cd $HOME/pmd-demo
|
||||
curl -L -o jdk-master.zip https://github.com/openjdk/jdk/archive/refs/heads/master.zip
|
||||
unzip jdk-master.zip
|
||||
alias pmd=$HOME/PMD/source/pmd/pmd-dist/target/pmd-bin-7.0.0-SNAPSHOT/bin/pmd
|
||||
clear
|
||||
pmd --version
|
||||
pmd check -R rulesets/java/quickstart.xml -d jdk-master/src/java.base -f text --cache pmd.cache --report-file jdk-report.txt
|
||||
```
|
||||
|
||||
Second terminal window: `cd $HOME/pmd-demo; tail -f jdk-report.txt`
|
||||
|
||||
### Recording
|
||||
|
||||
Record screencast with https://github.com/EasyScreenCast/EasyScreenCast (a gnome3 extension)
|
||||
|
||||
The recorded screencast can be found in `$HOME/Videos`.
|
||||
|
||||
### Converting
|
||||
|
||||
Convert webm to gif: https://engineering.giphy.com/how-to-make-gifs-with-ffmpeg/
|
||||
|
||||
```shell
|
||||
cd $HOME/Videos
|
||||
ffmpeg -i pmd7-demo.webm -filter_complex "[0:v] fps=12,scale=960:-1,split [a][b];[a] palettegen [p];[b][p] paletteuse" pmd7-demo.gif
|
||||
```
|
Binary file not shown.
Before Width: | Height: | Size: 2.1 MiB After Width: | Height: | Size: 3.0 MiB |
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.cli.commands.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.pmd.PMDVersion;
|
||||
import net.sourceforge.pmd.cli.internal.PmdBanner;
|
||||
|
||||
import picocli.CommandLine;
|
||||
|
||||
class PMDVersionProvider implements CommandLine.IVersionProvider {
|
||||
@Override
|
||||
public String[] getVersion() throws Exception {
|
||||
List<String> lines = new ArrayList<>(PmdBanner.loadBanner());
|
||||
lines.add(PMDVersion.getFullVersionName());
|
||||
lines.add("Java version: " + System.getProperty("java.version") + ", vendor: " + System.getProperty("java.vendor") + ", runtime: " + System.getProperty("java.home"));
|
||||
return lines.toArray(new String[0]);
|
||||
}
|
||||
}
|
@ -4,11 +4,8 @@
|
||||
|
||||
package net.sourceforge.pmd.cli.commands.internal;
|
||||
|
||||
import net.sourceforge.pmd.PMDVersion;
|
||||
|
||||
import picocli.AutoComplete.GenerateCompletion;
|
||||
import picocli.CommandLine.Command;
|
||||
import picocli.CommandLine.IVersionProvider;
|
||||
|
||||
@Command(name = "pmd", mixinStandardHelpOptions = true,
|
||||
versionProvider = PMDVersionProvider.class,
|
||||
@ -20,11 +17,3 @@ import picocli.CommandLine.IVersionProvider;
|
||||
public class PmdRootCommand {
|
||||
|
||||
}
|
||||
|
||||
class PMDVersionProvider implements IVersionProvider {
|
||||
|
||||
@Override
|
||||
public String[] getVersion() throws Exception {
|
||||
return new String[] { "PMD " + PMDVersion.VERSION };
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.cli.internal;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public final class PmdBanner {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(PmdBanner.class);
|
||||
|
||||
private static final String BANNER_RESOURCE = "/net/sourceforge/pmd/cli/internal/banner.txt";
|
||||
|
||||
private PmdBanner() {}
|
||||
|
||||
public static List<String> loadBanner() {
|
||||
List<String> lines = new ArrayList<>();
|
||||
|
||||
try (BufferedReader bannerReader = new BufferedReader(
|
||||
new InputStreamReader(PmdBanner.class.getResourceAsStream(BANNER_RESOURCE), StandardCharsets.UTF_8))) {
|
||||
String line = bannerReader.readLine();
|
||||
while (line != null) {
|
||||
lines.add(line);
|
||||
line = bannerReader.readLine();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOGGER.debug("Couldn't load banner", e);
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
}
|
@ -44,6 +44,10 @@ public final class PmdRootLogger {
|
||||
// need to reload the logger with the new configuration
|
||||
log = LoggerFactory.getLogger(PMD_CLI_LOGGER);
|
||||
resetLogLevel = true;
|
||||
|
||||
// logging, mostly for testing purposes
|
||||
Level defaultLogLevel = Slf4jSimpleConfiguration.getDefaultLogLevel();
|
||||
log.debug("Log level is at {}", defaultLogLevel);
|
||||
}
|
||||
|
||||
PmdReporter pmdReporter = setupMessageReporter();
|
||||
@ -67,9 +71,6 @@ public final class PmdRootLogger {
|
||||
PmdReporter pmdReporter = new SimpleMessageReporter(log);
|
||||
// always install java.util.logging to slf4j bridge
|
||||
Slf4jSimpleConfiguration.installJulBridge();
|
||||
// logging, mostly for testing purposes
|
||||
Level defaultLogLevel = Slf4jSimpleConfiguration.getDefaultLogLevel();
|
||||
log.info("Log level is at {}", defaultLogLevel);
|
||||
return pmdReporter;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
████ ████
|
||||
██ ██
|
||||
██ █████ █ ███ ███ ███████ ██
|
||||
███ ██ ███ ████ ████ ██ ██ ███
|
||||
███ ███████ ██ ████ ██ ██ ██ ███
|
||||
██ ██ ██ ██ ██ ███████ ██
|
||||
██ ██
|
||||
████ ████
|
@ -11,6 +11,7 @@ import static org.hamcrest.CoreMatchers.startsWith;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.emptyString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
@ -90,7 +91,7 @@ class CpdCliTest extends BaseCliTest {
|
||||
@Test
|
||||
void debugLogging() throws Exception {
|
||||
CliExecutionResult result = runCliSuccessfully("--debug", "--minimum-tokens", "340", "--dir", SRC_DIR);
|
||||
result.checkStdErr(containsString("[main] INFO net.sourceforge.pmd.cli - Log level is at TRACE"));
|
||||
result.checkStdErr(containsString("[DEBUG] Log level is at TRACE"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -102,7 +103,7 @@ class CpdCliTest extends BaseCliTest {
|
||||
@Test
|
||||
void defaultLogging() throws Exception {
|
||||
CliExecutionResult result = runCliSuccessfully("--minimum-tokens", "340", "--dir", SRC_DIR);
|
||||
result.checkStdErr(containsString("[main] INFO net.sourceforge.pmd.cli - Log level is at INFO"));
|
||||
result.checkStdErr(not(containsString("[DEBUG] Log level is at TRACE")));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -199,14 +199,13 @@ class PmdCliTest extends BaseCliTest {
|
||||
@Test
|
||||
void debugLogging() throws Exception {
|
||||
CliExecutionResult result = runCliSuccessfully("--debug", "--dir", srcDir.toString(), "--rulesets", RULESET_NO_VIOLATIONS);
|
||||
result.checkStdErr(containsString("[main] INFO net.sourceforge.pmd.cli - Log level is at TRACE"));
|
||||
result.checkStdErr(containsString("[DEBUG] Log level is at TRACE"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void defaultLogging() throws Exception {
|
||||
CliExecutionResult result = runCliSuccessfully("--dir", srcDir.toString(), "--rulesets", RULESET_NO_VIOLATIONS);
|
||||
result.checkStdErr(containsString("[main] INFO net.sourceforge.pmd.cli - Log level is at INFO"));
|
||||
result.checkStdErr(not(containsPattern("Adding file .*"))); // not in debug mode
|
||||
result.checkStdErr(not(containsString("[DEBUG] Log level is at TRACE")));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -11,8 +11,42 @@
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<!-- default values for the properties provided by git-commit-id-maven-plugin -->
|
||||
<git.commit.id>unknown</git.commit.id>
|
||||
<git.commit.time>unknown</git.commit.time>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>io.github.git-commit-id</groupId>
|
||||
<artifactId>git-commit-id-maven-plugin</artifactId>
|
||||
<version>7.0.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>get-the-git-infos</id>
|
||||
<goals>
|
||||
<goal>revision</goal>
|
||||
</goals>
|
||||
<phase>initialize</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<failOnUnableToExtractRepoInfo>true</failOnUnableToExtractRepoInfo>
|
||||
<includeOnlyProperties>
|
||||
<includeOnlyProperty>^git.commit.id$</includeOnlyProperty>
|
||||
<includeOnlyProperty>^git.commit.time$</includeOnlyProperty>
|
||||
</includeOnlyProperties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
|
@ -23,24 +23,38 @@ public final class PMDVersion {
|
||||
*/
|
||||
public static final String VERSION;
|
||||
|
||||
private static final String UNKNOWN_VERSION = "unknown";
|
||||
private static final String RELEASE_TIMESTAMP;
|
||||
private static final String GIT_COMMIT_ID;
|
||||
private static final String GIT_COMMIT_TIME;
|
||||
|
||||
private static final String UNKNOWN = "unknown";
|
||||
|
||||
/*
|
||||
* Determines the version from maven's generated pom.properties file.
|
||||
*/
|
||||
static {
|
||||
String pmdVersion = UNKNOWN_VERSION;
|
||||
try (InputStream stream = PMDVersion.class.getResourceAsStream("/META-INF/maven/net.sourceforge.pmd/pmd-core/pom.properties")) {
|
||||
String pmdVersion = UNKNOWN;
|
||||
String releaseTimestamp = UNKNOWN;
|
||||
String gitCommitId = UNKNOWN;
|
||||
String gitCommitTime = UNKNOWN;
|
||||
try (InputStream stream = PMDVersion.class.getResourceAsStream("pmd-core-version.properties")) {
|
||||
if (stream != null) {
|
||||
final Properties properties = new Properties();
|
||||
properties.load(stream);
|
||||
pmdVersion = properties.getProperty("version");
|
||||
releaseTimestamp = properties.getProperty("releaseTimestamp");
|
||||
|
||||
gitCommitId = properties.getProperty("gitCommitId");
|
||||
gitCommitTime = properties.getProperty("gitCommitTime");
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
LOG.debug("Couldn't determine version of PMD", e);
|
||||
}
|
||||
|
||||
VERSION = pmdVersion;
|
||||
RELEASE_TIMESTAMP = releaseTimestamp;
|
||||
GIT_COMMIT_ID = gitCommitId;
|
||||
GIT_COMMIT_TIME = gitCommitTime;
|
||||
}
|
||||
|
||||
private PMDVersion() {
|
||||
@ -55,7 +69,7 @@ public final class PMDVersion {
|
||||
*/
|
||||
public static String getNextMajorRelease() {
|
||||
if (isUnknown()) {
|
||||
return UNKNOWN_VERSION;
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
final int major = Integer.parseInt(VERSION.split("\\.")[0]);
|
||||
@ -68,7 +82,7 @@ public final class PMDVersion {
|
||||
*/
|
||||
@SuppressWarnings("PMD.LiteralsFirstInComparisons")
|
||||
public static boolean isUnknown() {
|
||||
return UNKNOWN_VERSION.equals(VERSION);
|
||||
return UNKNOWN.equals(VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -78,4 +92,11 @@ public final class PMDVersion {
|
||||
public static boolean isSnapshot() {
|
||||
return VERSION.endsWith("-SNAPSHOT");
|
||||
}
|
||||
|
||||
public static String getFullVersionName() {
|
||||
if (isSnapshot()) {
|
||||
return "PMD " + VERSION + " (" + GIT_COMMIT_ID + ", " + GIT_COMMIT_TIME + ")";
|
||||
}
|
||||
return "PMD " + VERSION + " (" + GIT_COMMIT_ID + ", " + RELEASE_TIMESTAMP + ")";
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
#
|
||||
# BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
#
|
||||
|
||||
# version and releaseTimestamp are from the parent pom.xml
|
||||
version=${project.version}
|
||||
releaseTimestamp=${project.build.outputTimestamp}
|
||||
|
||||
# gitCommitId and gitCommitTime are provided by git-commit-id-maven-plugin
|
||||
gitCommitId=${git.commit.id}
|
||||
gitCommitTime=${git.commit.time}
|
@ -9,6 +9,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import net.sourceforge.pmd.FooRule;
|
||||
import net.sourceforge.pmd.PMDVersion;
|
||||
import net.sourceforge.pmd.lang.document.FileId;
|
||||
import net.sourceforge.pmd.lang.document.FileLocation;
|
||||
import net.sourceforge.pmd.lang.document.TextRange2d;
|
||||
@ -49,9 +50,11 @@ class XSLTRendererTest extends AbstractRendererTest {
|
||||
|
||||
@Override
|
||||
String filter(String expected) {
|
||||
return expected.replaceAll("<h2>PMD unknown Report\\. Generated on .+</h2>",
|
||||
"<h2>PMD unknown Report. Generated on ...</h2>")
|
||||
.replaceAll("\r\n", "\n"); // make the test run on Windows, too
|
||||
return expected.replaceAll("<h2>PMD " + PMDVersion.VERSION + " Report\\. Generated on .+</h2>",
|
||||
"<h2>PMD unknown Report. Generated on ...</h2>")
|
||||
.replaceAll("<title>PMD " + PMDVersion.VERSION + " Report</title>",
|
||||
"<title>PMD unknown Report</title>")
|
||||
.replaceAll("\r\n", "\n"); // make the test run on Windows, too
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -5,11 +5,11 @@
|
||||
org.slf4j.simpleLogger.logFile=System.err
|
||||
org.slf4j.simpleLogger.showDateTime=false
|
||||
org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd'T'HH:mm:ss.SSSXXX
|
||||
org.slf4j.simpleLogger.showThreadName=true
|
||||
org.slf4j.simpleLogger.showThreadName=false
|
||||
org.slf4j.simpleLogger.showThreadId=false
|
||||
org.slf4j.simpleLogger.showLogName=true
|
||||
org.slf4j.simpleLogger.showLogName=false
|
||||
org.slf4j.simpleLogger.showShortLogName=false
|
||||
org.slf4j.simpleLogger.levelInBrackets=false
|
||||
org.slf4j.simpleLogger.levelInBrackets=true
|
||||
|
||||
# Default log level for all loggers
|
||||
# Must be one of "trace", "debug", "info", "warn", "error" or "off"
|
||||
|
@ -5,11 +5,11 @@
|
||||
org.slf4j.simpleLogger.logFile=System.err
|
||||
org.slf4j.simpleLogger.showDateTime=false
|
||||
org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd'T'HH:mm:ss.SSSXXX
|
||||
org.slf4j.simpleLogger.showThreadName=true
|
||||
org.slf4j.simpleLogger.showThreadName=false
|
||||
org.slf4j.simpleLogger.showThreadId=false
|
||||
org.slf4j.simpleLogger.showLogName=true
|
||||
org.slf4j.simpleLogger.showLogName=false
|
||||
org.slf4j.simpleLogger.showShortLogName=false
|
||||
org.slf4j.simpleLogger.levelInBrackets=false
|
||||
org.slf4j.simpleLogger.levelInBrackets=true
|
||||
|
||||
# Default log level for all loggers
|
||||
# Must be one of "trace", "debug", "info", "warn", "error" or "off"
|
||||
|
@ -174,13 +174,13 @@ class BinaryDistributionIT extends AbstractBinaryDistributionTest {
|
||||
|
||||
result = PMDExecutor.runPMD(createTemporaryReportFile(), tempDir, "-d", srcDir, "-R", "src/test/resources/rulesets/sample-ruleset.xml");
|
||||
result.assertExitCode(4);
|
||||
result.assertErrorOutputContains("[main] INFO net.sourceforge.pmd.cli - Log level is at INFO");
|
||||
result.assertNoErrorInReport("[DEBUG] Log level is at TRACE");
|
||||
|
||||
|
||||
// now with debug
|
||||
result = PMDExecutor.runPMD(createTemporaryReportFile(), tempDir, "-d", srcDir, "-R", "src/test/resources/rulesets/sample-ruleset.xml", "--debug");
|
||||
result.assertExitCode(4);
|
||||
result.assertErrorOutputContains("[main] INFO net.sourceforge.pmd.cli - Log level is at TRACE");
|
||||
result.assertErrorOutputContains("[DEBUG] Log level is at TRACE");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -5,11 +5,11 @@
|
||||
org.slf4j.simpleLogger.logFile=System.err
|
||||
org.slf4j.simpleLogger.showDateTime=false
|
||||
org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd'T'HH:mm:ss.SSSXXX
|
||||
org.slf4j.simpleLogger.showThreadName=true
|
||||
org.slf4j.simpleLogger.showThreadName=false
|
||||
org.slf4j.simpleLogger.showThreadId=false
|
||||
org.slf4j.simpleLogger.showLogName=true
|
||||
org.slf4j.simpleLogger.showLogName=false
|
||||
org.slf4j.simpleLogger.showShortLogName=false
|
||||
org.slf4j.simpleLogger.levelInBrackets=false
|
||||
org.slf4j.simpleLogger.levelInBrackets=true
|
||||
|
||||
# Default log level for all loggers
|
||||
# Must be one of "trace", "debug", "info", "warn", "error" or "off"
|
||||
|
Loading…
x
Reference in New Issue
Block a user