diff --git a/logback.xml b/logback.xml deleted file mode 100644 index ecbb26752..000000000 --- a/logback.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %d %-5p %c{2} : %m%n - - - - - - - - \ No newline at end of file diff --git a/pom.xml b/pom.xml index b1d872bab..a26efa5f3 100644 --- a/pom.xml +++ b/pom.xml @@ -26,8 +26,8 @@ 999999-SNAPSHOT jenkinsci/plugin-compat-tester - 1.4.5 1.6 + 2.0.6 Max @@ -46,27 +46,12 @@ org.slf4j slf4j-api - 2.0.6 + ${slf4j.version} - - ch.qos.logback - logback-access - ${logbackVersion} - - - ch.qos.logback - logback-classic - ${logbackVersion} - - - ch.qos.logback - logback-core - ${logbackVersion} - com.beust jcommander @@ -77,6 +62,11 @@ maven-scm-provider-svnjava 1.12 + + io.jenkins.lib + support-log-formatter + 1.2 + jakarta.servlet jakarta.servlet-api @@ -328,6 +318,11 @@ reflections 0.10.2 + + org.slf4j + slf4j-jdk14 + ${slf4j.version} + junit junit @@ -360,7 +355,7 @@ org.apache.maven.plugins maven-jar-plugin - 3.3.0 + @@ -407,6 +402,17 @@ + + org.apache.maven.plugins + maven-surefire-plugin + + + + org.jenkins.tools.test.logging.LoggingConfiguration + + alphabetical + + diff --git a/src/main/java/org/jenkins/tools/test/PluginCompatTester.java b/src/main/java/org/jenkins/tools/test/PluginCompatTester.java index a2adf6ea0..287ff9748 100644 --- a/src/main/java/org/jenkins/tools/test/PluginCompatTester.java +++ b/src/main/java/org/jenkins/tools/test/PluginCompatTester.java @@ -215,13 +215,13 @@ public PluginCompatReport testPlugins() final List pluginsToInclude = config.getIncludePlugins(); if (data.plugins.isEmpty() && pluginsToInclude != null && !pluginsToInclude.isEmpty()) { // Update Center returns empty info OR the "-war" option is specified for WAR without bundled plugins - System.out.println("WAR file does not contain plugin info, will try to extract it from UC for included plugins"); + LOGGER.log(Level.INFO, "WAR file does not contain plugin info; will try to extract it from UC for included plugins"); pluginsToCheck = new HashMap<>(pluginsToInclude.size()); UpdateSite.Data ucData = extractUpdateCenterData(pluginGroupIds); for (String plugin : pluginsToInclude) { UpdateSite.Plugin pluginData = ucData.plugins.get(plugin); if (pluginData != null) { - System.out.println("Adding " + plugin + " to the test scope"); + LOGGER.log(Level.INFO, "Adding {0} to the test scope", plugin); pluginsToCheck.put(plugin, pluginData); } } @@ -241,7 +241,7 @@ public PluginCompatReport testPlugins() Plugin extracted = extractFromLocalCheckout(); pluginsToCheck.put(artifactId, extracted); } catch (PluginSourcesUnavailableException e) { - LOGGER.log(Level.SEVERE, String.format("Local checkout provided but plugin sources are not available. Cannot test plugin [%s]", artifactId)); + LOGGER.log(Level.SEVERE, "Cannot test {0} because plugin sources are not available despite a local checkout being provided", artifactId); } } @@ -258,13 +258,13 @@ public PluginCompatReport testPlugins() boolean failed = false; SCMManagerFactory.getInstance().start(); ROOT_CYCLE: for(MavenCoordinates coreCoordinates : testedCores){ - System.out.println("Starting plugin tests on core coordinates : "+coreCoordinates.toString()); + LOGGER.log(Level.INFO, "Starting plugin tests on core coordinates {0}", coreCoordinates); for (Plugin plugin : pluginsToCheck.values()) { if(config.getIncludePlugins()==null || config.getIncludePlugins().contains(plugin.name.toLowerCase())){ PluginInfos pluginInfos = new PluginInfos(plugin.name, plugin.version, plugin.url); if(config.getExcludePlugins()!=null && config.getExcludePlugins().contains(plugin.name.toLowerCase())){ - System.out.println("Plugin "+plugin.name+" is in excluded plugins => test skipped !"); + LOGGER.log(Level.INFO, "Plugin {0} is in excluded plugins => test skipped", plugin.name); continue; } @@ -302,7 +302,7 @@ public PluginCompatReport testPlugins() || parentPom.groupId.equals("org.jvnet.hudson.plugins")) && coreCoordinates.version.matches("1[.][0-9]+[.][0-9]+") && new VersionNumber(coreCoordinates.version).compareTo(new VersionNumber("1.485")) < 0) { // TODO unless 1.480.3+ - LOGGER.log(Level.WARNING, "Cannot test against " + coreCoordinates.version + " due to lack of deployed POM for " + coreCoordinates.toGAV()); + LOGGER.log(Level.WARNING, "Cannot test against {0} due to lack of deployed POM for {1}", new Object[]{coreCoordinates.toGAV(), coreCoordinates.version}); actualCoreCoordinates = new MavenCoordinates(coreCoordinates.groupId, coreCoordinates.artifactId, coreCoordinates.version.replaceFirst("[.][0-9]+$", "")); } } @@ -315,7 +315,7 @@ && new VersionNumber(coreCoordinates.version).compareTo(new VersionNumber("1.485 } if(!config.isSkipTestCache() && report.isCompatTestResultAlreadyInCache(pluginInfos, actualCoreCoordinates, config.getTestCacheTimeout(), config.getCacheThresholdStatus())){ - System.out.println("Cache activated for plugin "+pluginInfos.pluginName+" => test skipped !"); + LOGGER.log(Level.INFO, "Cache activated for plugin {0} => test skipped", pluginInfos.pluginName); continue; // Don't do anything : we are in the cached interval ! :-) } @@ -383,7 +383,7 @@ && new VersionNumber(coreCoordinates.version).compareTo(new VersionNumber("1.485 } } } else { - System.out.println("Plugin "+plugin.name+" not in included plugins => test skipped !"); + LOGGER.log(Level.FINE, "Plugin {0} not in included plugins; skipping", plugin.name); } } } @@ -392,7 +392,7 @@ && new VersionNumber(coreCoordinates.version).compareTo(new VersionNumber("1.485 if(config.isGenerateHtmlReport() && config.reportFile != null && config.reportFile.exists()) { generateHtmlReportFile(); } else { - System.out.println("No HTML report is generated, because it has been disabled or no tests have been executed"); + LOGGER.log(Level.INFO, "No HTML report has been generated, either because report generation has been disabled or because no tests have been executed"); } if (failed && config.isFailOnError()) { @@ -448,13 +448,7 @@ private static String createBuildLogFilePathFor(String pluginName, String plugin private TestExecutionResult testPluginAgainst(MavenCoordinates coreCoordinates, Plugin plugin, MavenRunner.Config mconfig, PomData pomData, Map otherPlugins, Map pluginGroupIds, PluginCompatTesterHooks pcth, List overridenPlugins) throws PluginSourcesUnavailableException, PomExecutionException, IOException, PomTransformationException { - System.out.println(String.format("%n%n%n%n%n")); - System.out.println("#############################################"); - System.out.println("#############################################"); - System.out.println(String.format("##%n## Starting to test plugin %s v%s%n## against %s%n##", plugin.name, plugin.version, coreCoordinates)); - System.out.println("#############################################"); - System.out.println("#############################################"); - System.out.println(String.format("%n%n%n%n%n")); + LOGGER.log(Level.INFO, "\n\n\n\n\n\n#############################################\n#############################################\n##\n## Starting to test {0} {1} against {2}\n##\n#############################################\n#############################################\n\n\n\n\n", new Object[]{plugin.name, plugin.version, coreCoordinates}); File pluginCheckoutDir = new File(config.workDirectory.getAbsolutePath() + File.separator + plugin.name + File.separator); String parentFolder = StringUtils.EMPTY; @@ -476,19 +470,19 @@ private TestExecutionResult testPluginAgainst(MavenCoordinates coreCoordinates, pluginCheckoutDir = (File)beforeCheckout.get("checkoutDir"); } if (Files.isDirectory(pluginCheckoutDir.toPath())) { - System.out.println("Deleting working directory "+pluginCheckoutDir.getAbsolutePath()); + LOGGER.log(Level.INFO, "Deleting working directory {0}", pluginCheckoutDir.getAbsolutePath()); FileUtils.deleteDirectory(pluginCheckoutDir); } Files.createDirectory(pluginCheckoutDir.toPath()); - System.out.println("Created plugin checkout dir : "+pluginCheckoutDir.getAbsolutePath()); + LOGGER.log(Level.INFO, "Created plugin checkout directory {0}", pluginCheckoutDir.getAbsolutePath()); if (localCheckoutProvided()) { if (!onlyOnePluginIncluded()) { File localCheckoutPluginDir = new File(config.getLocalCheckoutDir(), plugin.name); File pomLocalCheckoutPluginDir = new File(localCheckoutPluginDir, "pom.xml"); if(pomLocalCheckoutPluginDir.exists()) { - System.out.println("Copy plugin directory from : " + localCheckoutPluginDir.getAbsolutePath()); + LOGGER.log(Level.INFO, "Copying plugin directory from {0}", localCheckoutPluginDir.getAbsolutePath()); FileUtils.copyDirectoryStructure(localCheckoutPluginDir, pluginCheckoutDir); } else { cloneFromSCM(pomData, plugin.name, plugin.version, pluginCheckoutDir, ""); @@ -497,7 +491,7 @@ private TestExecutionResult testPluginAgainst(MavenCoordinates coreCoordinates, // TODO this fails when it encounters symlinks (e.g. work/jobs/…/builds/lastUnstableBuild), // and even up-to-date versions of org.apache.commons.io.FileUtils seem to not handle links, // so may need to use something like http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/essential/io/examples/Copy.java - System.out.println("Copy plugin directory from : " + config.getLocalCheckoutDir().getAbsolutePath()); + LOGGER.log(Level.INFO, "Copy plugin directory from {0}", config.getLocalCheckoutDir().getAbsolutePath()); FileUtils.copyDirectoryStructure(config.getLocalCheckoutDir(), pluginCheckoutDir); } } else { @@ -505,21 +499,21 @@ private TestExecutionResult testPluginAgainst(MavenCoordinates coreCoordinates, cloneFromSCM(pomData, plugin.name, plugin.version, pluginCheckoutDir, ""); } } else { - // If the plugin exists in a different directory (multimodule plugins) + // If the plugin exists in a different directory (multi-module plugins) if (beforeCheckout.get("pluginDir") != null) { pluginCheckoutDir = (File)beforeCheckout.get("checkoutDir"); } if (beforeCheckout.get("parentFolder") != null) { parentFolder = (String) beforeCheckout.get("parentFolder"); } - System.out.println("The plugin has already been checked out, likely due to a multimodule situation. Continue."); + LOGGER.log(Level.INFO, "The plugin has already been checked out, likely due to a multi-module situation; continuing"); } } catch (ComponentLookupException e) { - System.err.println("Error : " + e.getMessage()); - throw new PluginSourcesUnavailableException("Problem while creating ScmManager !", e); + LOGGER.log(Level.SEVERE, "Failed to create ScmManager", e); + throw new PluginSourcesUnavailableException("Failed to create ScmManager", e); } catch (Exception e) { - System.err.println("Error : " + e.getMessage()); - throw new PluginSourcesUnavailableException("Problem while checking out plugin sources!", e); + LOGGER.log(Level.SEVERE, "Failed to check out plugin sources", e); + throw new PluginSourcesUnavailableException("Failed to check out plugin sources", e); } File buildLogFile = createBuildLogFile(config.reportFile, plugin.name, plugin.version, coreCoordinates); @@ -565,7 +559,7 @@ private TestExecutionResult testPluginAgainst(MavenCoordinates coreCoordinates, throw x; } catch (Exception x) { - x.printStackTrace(); + LOGGER.log(Level.WARNING, "Failed to transform POM; continuing", x); pomData.getWarningMessages().add(Functions.printThrowable(x)); // but continue } @@ -628,7 +622,7 @@ public void cloneFromSCM(PomData pomData, String name, String version, File chec if (connectionURL != null) { connectionURL = connectionURL.replace("git://", "https://"); // See: https://github.blog/2021-09-01-improving-git-protocol-security-github/ } - System.out.println("Checking out from SCM connection URL : " + connectionURL + " (" + name + "-" + version + ") at tag " + scmTag); + LOGGER.log(Level.INFO, "Checking out from SCM connection URL: {0} ({1}-{2}) at tag {3}", new Object[]{connectionURL, name, version, scmTag}); if (checkoutDirectory.isDirectory()) { FileUtils.deleteDirectory(checkoutDirectory); } @@ -651,10 +645,10 @@ private String getScmTag(PomData pomData, String name, String version){ String scmTag; if (pomData.getScmTag() != null) { scmTag = pomData.getScmTag(); - System.out.println(String.format("Using SCM tag '%s' from POM.", scmTag)); + LOGGER.log(Level.INFO, "Using SCM tag {0} from POM", scmTag); } else { scmTag = name + "-" + version; - System.out.println(String.format("POM did not provide an SCM tag. Inferring tag '%s'.", scmTag)); + LOGGER.log(Level.INFO, "POM did not provide an SCM tag; inferring tag {0}", scmTag); } return scmTag; } @@ -723,7 +717,7 @@ private UpdateSite.Data scanBom(HashMap pluginGroupIds, String p Manifest manifest = jis.getManifest(); if (manifest == null || manifest.getMainAttributes() == null) { // Skip this entry, is not a plugin and/or contains a malformed manifest so is not parseable - System.out.println("Entry " + name + "defined in the BOM looks non parseable, ignoring"); + LOGGER.log(Level.INFO, "Entry {0} defined in the BOM looks unparseable; continuing", name); continue; } String jenkinsVersion = manifest.getMainAttributes().getValue("Jenkins-Version"); @@ -780,7 +774,7 @@ private UpdateSite.Data scanBom(HashMap pluginGroupIds, String p } top.put("core", new JSONObject().accumulate("name", "core").accumulate("version",core).accumulate("url", "https://foobar")); } - System.out.println("Readed contents of " + config.getBom() + ": " + top); + LOGGER.log(Level.INFO, "Read contents of {0}: {1}", new Object[]{config.getBom(), top}); return newUpdateSiteData(new UpdateSite(DEFAULT_SOURCE_ID, null), top); } @@ -788,7 +782,7 @@ private List getBomEntries() throws IOException, XmlPullParserException, P File fullDepPom = new MavenBom(config.getBom()).writeFullDepPom(config.workDirectory); MavenRunner.Config mconfig = new MavenRunner.Config(config); - System.out.println(mconfig.userSettingsFile); + LOGGER.log(Level.INFO, "User settings file: {0}", mconfig.userSettingsFile); File buildLogFile = new File(config.workDirectory + File.separator + "bom-download.log"); @@ -908,7 +902,7 @@ private UpdateSite.Data scanWAR(File war, @Nonnull Map pluginGro if (!top.has("core")) { throw new IOException("no jenkins-core.jar in " + war); } - System.out.println("Scanned contents of " + war + " with " + plugins.size() + " plugins"); + LOGGER.log(Level.INFO, "Scanned contents of {0} with {1} plugins", new Object[]{war, plugins.size()}); return newUpdateSiteData(new UpdateSite(DEFAULT_SOURCE_ID, null), top); } @@ -1030,7 +1024,7 @@ private void addSplitPluginDependencies(String thisPlugin, MavenRunner.Config mc } finally { Files.delete(tmp.toPath()); } - System.out.println("Analysis: coreDep=" + coreDep + " pluginDeps=" + pluginDeps + " pluginDepsTest=" + pluginDepsTest); + LOGGER.log(Level.INFO, "Analysis: coreDep={0} pluginDeps={1} pluginDepsTest={2}" + pluginDepsTest, new Object[]{coreDep, pluginDeps, pluginDepsTest}); if (coreDep != null) { Map toAdd = new HashMap<>(); Map toReplace = new HashMap<>(); @@ -1042,7 +1036,7 @@ private void addSplitPluginDependencies(String thisPlugin, MavenRunner.Config mc if (plugin.getGroupId() != null) { if (pluginGroupIds.containsKey(plugin.getName())) { if (!plugin.getGroupId().equals(pluginGroupIds.get(plugin.getName()))) { - System.err.println("WARNING: mismatch between detected and explicit group ID for " + plugin.getName()); + LOGGER.log(Level.WARNING, "Mismatch between detected and explicit group ID for {0}", plugin.getName()); } } else { pluginGroupIds.put(plugin.getName(), plugin.getGroupId()); @@ -1054,7 +1048,7 @@ private void addSplitPluginDependencies(String thisPlugin, MavenRunner.Config mc String[] pieces = split.split(" "); String plugin = pieces[0]; if (splitCycles.contains(thisPlugin + ' ' + plugin)) { - System.out.println("Skipping implicit dep " + thisPlugin + " → " + plugin); + LOGGER.log(Level.INFO, "Skipping implicit dependency {0} → {1}", new Object[]{thisPlugin, plugin}); continue; } VersionNumber splitPoint = new VersionNumber(pieces[1]); @@ -1066,7 +1060,7 @@ private void addSplitPluginDependencies(String thisPlugin, MavenRunner.Config mc try { bundledV = new VersionNumber(bundledP.version); } catch (NumberFormatException x) { // TODO apparently this does not handle `1.0-beta-1` and the like?! - System.out.println("Skipping unparseable dep on " + bundledP.name + ": " + bundledP.version); + LOGGER.log(Level.INFO, "Skipping unparseable dependency on {0}: {1}", new Object[]{bundledP.name, bundledP.version}); continue; } if (bundledV.isNewerThan(declaredMinimum)) { @@ -1089,7 +1083,7 @@ private void addSplitPluginDependencies(String thisPlugin, MavenRunner.Config mc toAddTest = difference(toAdd, toAddTest); if (!toAdd.isEmpty() || !toReplace.isEmpty() || !toAddTest.isEmpty() || !toReplaceTest.isEmpty()) { - System.out.println("Adding/replacing plugin dependencies for compatibility: " + toAdd + " " + toReplace + "\nFor test: " + toAddTest + " " + toReplaceTest); + LOGGER.log(Level.INFO, "Adding/replacing plugin dependencies for compatibility: {0} {1}; for test: {2} {3}", new Object[]{toAdd, toReplace, toAddTest, toReplaceTest}); pom.addDependencies(toAdd, toReplace, toAddTest, toReplaceTest, pluginGroupIds, convertFromTestDep); } @@ -1141,11 +1135,11 @@ private void updateAllDependents(String parent, Plugin dependent, Map warEntries = jf.entries(); @@ -1183,16 +1177,16 @@ private void populateSplits(File war) throws IOException { // Since https://github.com/jenkinsci/jenkins/pull/3865 splits can depend on jdk version // So make sure we are not applying splits not intended for our JDK splits = removeSplitsBasedOnJDK(splits, jdkVersion); - System.out.println("found splits: " + splits); + LOGGER.log(Level.INFO, "Found splits: {0}", String.join(",", splits)); found++; } else if (entry.getName().equals("jenkins/split-plugin-cycles.txt")) { splitCycles = configLines(jis).collect(Collectors.toSet()); - System.out.println("found split cycles: " + splitCycles); + LOGGER.log(Level.INFO, "Found split cycles: {0}", String.join(",", splitCycles)); found++; } } if (found == 0) { - System.out.println("None found, falling back to hard-coded historical values."); + LOGGER.log(Level.INFO, "None found, falling back to hard-coded historical values"); splits = HISTORICAL_SPLITS; splitCycles = HISTORICAL_SPLIT_CYCLES; } else if (found != 2) { @@ -1214,7 +1208,7 @@ private List removeSplitsBasedOnJDK(List splits, JavaSpecificati if (jdkVersion.isNewerThanOrEqualTo(new JavaSpecificationVersion(tokens[3]))) { filterSplits.add(split); } else { - System.out.println("Not adding " + split + " as split because jdk specified " + tokens[3] + " is newer than running jdk " + jdkVersion); + LOGGER.log(Level.INFO, "Not adding {0} as split because JDK specified {1} is newer than running JDK {2}", new Object[]{split, tokens[3], jdkVersion}); } } else { filterSplits.add(split); diff --git a/src/main/java/org/jenkins/tools/test/PluginCompatTesterCli.java b/src/main/java/org/jenkins/tools/test/PluginCompatTesterCli.java index c4e45524a..100cc7377 100644 --- a/src/main/java/org/jenkins/tools/test/PluginCompatTesterCli.java +++ b/src/main/java/org/jenkins/tools/test/PluginCompatTesterCli.java @@ -35,6 +35,7 @@ import java.util.HashMap; import java.util.Map; import org.codehaus.plexus.PlexusContainerException; +import org.jenkins.tools.test.logging.LoggingConfiguration; import org.jenkins.tools.test.model.PluginCompatTesterConfig; import org.jenkins.tools.test.exception.PomExecutionException; import org.jenkins.tools.test.model.TestStatus; @@ -47,6 +48,14 @@ */ public class PluginCompatTesterCli { + static { + String configFile = System.getProperty("java.util.logging.config.file"); + String configClass = System.getProperty("java.util.logging.config.class"); + if (configClass == null && configFile == null) { + new LoggingConfiguration(); + } + } + @SuppressFBWarnings( value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", justification = diff --git a/src/main/java/org/jenkins/tools/test/hook/AbstractMultiParentHook.java b/src/main/java/org/jenkins/tools/test/hook/AbstractMultiParentHook.java index aa479cf3f..0f11c0439 100644 --- a/src/main/java/org/jenkins/tools/test/hook/AbstractMultiParentHook.java +++ b/src/main/java/org/jenkins/tools/test/hook/AbstractMultiParentHook.java @@ -6,6 +6,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; import org.apache.maven.scm.ScmException; import org.apache.maven.scm.ScmFileSet; @@ -24,10 +26,12 @@ import org.jenkins.tools.test.model.hook.PluginCompatTesterHookBeforeCheckout; /** - * Utility class to ease create simple hooks for multimodule projects + * Utility class to ease create simple hooks for multi-module projects */ public abstract class AbstractMultiParentHook extends PluginCompatTesterHookBeforeCheckout { + private static final Logger LOGGER = Logger.getLogger(AbstractMultiParentHook.class.getName()); + protected boolean firstRun = true; private PomData pomData; @@ -42,10 +46,10 @@ public Map action(Map moreInfo) throws Exception boolean shouldExecuteHook = config.getLocalCheckoutDir() == null || !config.getLocalCheckoutDir().exists(); if (shouldExecuteHook) { - System.out.println("Executing Hook for " + getParentProjectName()); + LOGGER.log(Level.INFO, "Executing hook for {0}", getParentProjectName()); // Determine if we need to run the download; only run for first identified plugin in the series if (firstRun) { - System.out.println("Preparing for Multimodule checkout"); + LOGGER.log(Level.INFO, "Preparing for multi-module checkout"); // Checkout to the parent directory. All other processes will be on the child directory File parentPath = new File(config.workDirectory.getAbsolutePath() + "/" + getParentFolder()); @@ -54,10 +58,10 @@ public Map action(Map moreInfo) throws Exception String scmTag; if (pomData.getScmTag() != null) { scmTag = pomData.getScmTag(); - System.out.println(String.format("Using SCM tag '%s' from POM.", scmTag)); + LOGGER.log(Level.INFO, "Using SCM tag {0} from POM", scmTag); } else { scmTag = getParentProjectName() + "-" + currentPlugin.version; - System.out.println(String.format("POM did not provide an SCM tag. Inferring tag '%s'.", scmTag)); + LOGGER.log(Level.INFO, "POM did not provide an SCM tag; inferring tag {0}", scmTag); } // Like PluginCompatTester.cloneFromSCM but with subdirectories trimmed: cloneFromSCM(currentPlugin, parentPath, scmTag, getUrl(), config.getFallbackGitHubOrganization()); @@ -70,7 +74,7 @@ public Map action(Map moreInfo) throws Exception // Change the "download"" directory; after download, it's simply used for reference File childPath = new File(config.workDirectory.getAbsolutePath() + "/" + getParentFolder() + "/" + getPluginFolderName(currentPlugin)); - System.out.println("Child path for " + currentPlugin.getDisplayName() + " " + childPath); + LOGGER.log(Level.INFO, "Child path for {0}: {1}", new Object[]{currentPlugin.getDisplayName(), childPath.getPath()}); moreInfo.put("checkoutDir", childPath); moreInfo.put("pluginDir", childPath); moreInfo.put("parentFolder", getParentFolder()); @@ -98,7 +102,7 @@ private void cloneFromSCM(UpdateSite.Plugin currentPlugin, File parentPath, Stri if (connectionURL != null) { connectionURL = connectionURL.replace("git://", "https://"); // See: https://github.blog/2021-09-01-improving-git-protocol-security-github/ } - System.out.println("Checking out from SCM connection URL: " + connectionURL + " (" + getParentProjectName() + "-" + currentPlugin.version + ") at tag " + scmTag); + LOGGER.log(Level.INFO, "Checking out from SCM connection URL {0}: {1} ({2}-{3}) at tag {4}", new Object[]{connectionURL, getParentProjectName(), currentPlugin.version, scmTag}); if (parentPath.isDirectory()) { FileUtils.deleteDirectory(parentPath); } @@ -124,11 +128,11 @@ public String getUrl() { protected void configureLocalCheckOut(UpdateSite.Plugin currentPlugin, File localCheckoutDir, Map moreInfo) { // Do nothing to keep compatibility with pre-existing Hooks - System.out.println("Ignoring localCheckoutDir for " + currentPlugin.getDisplayName()); + LOGGER.log(Level.INFO, "Ignoring local checkout directory for {0}", currentPlugin.getDisplayName()); } /** - * Returns the folder where the multimodule project parent will be checked out + * Returns the folder where the multi-module project parent will be checked out */ protected abstract String getParentFolder(); diff --git a/src/main/java/org/jenkins/tools/test/hook/ExampleMultiParent.java b/src/main/java/org/jenkins/tools/test/hook/ExampleMultiParent.java index 5f6fcdaf4..d7e543732 100644 --- a/src/main/java/org/jenkins/tools/test/hook/ExampleMultiParent.java +++ b/src/main/java/org/jenkins/tools/test/hook/ExampleMultiParent.java @@ -6,6 +6,8 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; import org.apache.maven.scm.ScmFileSet; import org.apache.maven.scm.ScmTag; import org.apache.maven.scm.command.checkout.CheckOutScmResult; @@ -19,9 +21,11 @@ * each plugin is in its own repository, these plugins automatically fail since they are "not * found". * - *

This is an example of what needs to change to handle multimodule parents. + *

This is an example of what needs to change to handle multi-module parents. */ public class ExampleMultiParent { //extends PluginCompatTesterHookBeforeCheckout { + private static final Logger LOGGER = Logger.getLogger(ExampleMultiParent.class.getName()); + private String parentUrl = "scm:git:git@github.com:jenkinsci/parent_repo.git"; private String parentName = "parent_repo"; private List allBundlePlugins = Arrays.asList("possible", "plugins"); @@ -50,12 +54,12 @@ public Map action(Map moreInfo) throws Exception // Determine if we need to run the download; only run for first identified plugin in the series if(firstRun){ - System.out.println("Preparing for Multimodule checkout."); + LOGGER.log(Level.INFO, "Preparing for multi-module checkout"); // Checkout to the parent directory. All other processes will be on the child directory File parentPath = new File(config.workDirectory.getAbsolutePath()+"/"+parentName); - System.out.println("Checking out from SCM connection URL : "+parentUrl+" ("+parentName+"-"+currentPlugin.version+")"); + LOGGER.log(Level.INFO, "Checking out from SCM connection URL: {0} ({1}-{2})", new Object[]{parentUrl, parentName, currentPlugin.version}); ScmManager scmManager = SCMManagerFactory.getInstance().createScmManager(); ScmRepository repository = scmManager.makeScmRepository(parentUrl); CheckOutScmResult result = scmManager.checkOut(repository, new ScmFileSet(parentPath), new ScmTag(parentName+"-"+currentPlugin.version)); diff --git a/src/main/java/org/jenkins/tools/test/hook/MultiParentCompileHook.java b/src/main/java/org/jenkins/tools/test/hook/MultiParentCompileHook.java index ae828753a..fda311677 100644 --- a/src/main/java/org/jenkins/tools/test/hook/MultiParentCompileHook.java +++ b/src/main/java/org/jenkins/tools/test/hook/MultiParentCompileHook.java @@ -12,6 +12,8 @@ import java.nio.file.StandardCopyOption; import java.util.List; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; import java.util.stream.Stream; import org.apache.commons.io.FileUtils; @@ -25,13 +27,15 @@ public class MultiParentCompileHook extends PluginCompatTesterHookBeforeCompile { + private static final Logger LOGGER = Logger.getLogger(MultiParentCompileHook.class.getName()); + protected MavenRunner runner; protected MavenRunner.Config mavenConfig; public static final String ESLINTRC = ".eslintrc"; public MultiParentCompileHook() { - System.out.println("Loaded multi-parent compile hook"); + LOGGER.log(Level.INFO, "Loaded multi-parent compile hook"); } @@ -39,14 +43,14 @@ public MultiParentCompileHook() { @SuppressFBWarnings(value = "REC_CATCH_EXCEPTION", justification = "silly rule") public Map action(Map moreInfo) throws Exception { try { - System.out.println("Executing multi-parent compile hook"); + LOGGER.log(Level.INFO, "Executing multi-parent compile hook"); PluginCompatTesterConfig config = (PluginCompatTesterConfig) moreInfo.get("config"); runner = new ExternalMavenRunner(config.getExternalMaven()); mavenConfig = getMavenConfig(config); File pluginDir = (File) moreInfo.get("pluginDir"); - System.out.println("Plugin dir is " + pluginDir); + LOGGER.log(Level.INFO, "Plugin dir is {0}", pluginDir); File localCheckoutDir = config.getLocalCheckoutDir(); if (localCheckoutDir != null) { @@ -72,12 +76,11 @@ public Map action(Map moreInfo) throws Exception moreInfo.put(OVERRIDE_DEFAULT_COMPILE, true); } - System.out.println("Executed multi-parent compile hook"); + LOGGER.log(Level.INFO, "Executed multi-parent compile hook"); return moreInfo; // Exceptions get swallowed, so we print to console here and rethrow again } catch (Exception e) { - System.out.println("Exception executing hook"); - System.out.println(e); + LOGGER.log(Level.WARNING, "Exception executing hook", e); throw e; } } @@ -142,12 +145,12 @@ private boolean isSnapshotMultiParentPlugin(String parentFolder, File path, File return false; } if (!path.getAbsolutePath().contains(parentFolder)) { - System.out.println(String.format("Something is really wrong here! parentFolder:%s not present in path %s", parentFolder, path.getAbsolutePath())); + LOGGER.log(Level.WARNING, "Parent folder {0} not present in path {1}", new Object[]{parentFolder, path.getAbsolutePath()}); return false; } File parentFile = path.getParentFile(); if (!StringUtils.equals(parentFolder, parentFile.getName())) { - System.out.println(String.format("Something is really wrong here! %s is not the parent folder of %s", parentFolder, path.getAbsolutePath())); + LOGGER.log(Level.WARNING, "{0} is not the parent folder of {1}", new Object[]{parentFolder, path.getAbsolutePath()}); return false; } @@ -159,9 +162,9 @@ private boolean isSnapshotMultiParentPlugin(String parentFolder, File path, File private File setupCompileResources(File path) throws IOException { - System.out.println("Cleaning up node modules if necessary"); + LOGGER.log(Level.INFO, "Cleaning up node modules if necessary"); removeNodeFolders(path); - System.out.println("Compile plugin log in " + path); + LOGGER.log(Level.INFO, "Plugin compilation log directory: {0}", path); return new File(path + "/compilePluginLog.log"); } diff --git a/src/main/java/org/jenkins/tools/test/hook/NodeCleanupBeforeCompileHook.java b/src/main/java/org/jenkins/tools/test/hook/NodeCleanupBeforeCompileHook.java index 31f0c3ee3..4145adbce 100644 --- a/src/main/java/org/jenkins/tools/test/hook/NodeCleanupBeforeCompileHook.java +++ b/src/main/java/org/jenkins/tools/test/hook/NodeCleanupBeforeCompileHook.java @@ -8,9 +8,13 @@ import java.io.File; import java.io.IOException; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; public class NodeCleanupBeforeCompileHook extends PluginCompatTesterHookBeforeCompile { + private static final Logger LOGGER = Logger.getLogger(NodeCleanupBeforeCompileHook.class.getName()); + @Override public Map action(Map moreInfo) throws Exception { PluginCompatTesterConfig config = (PluginCompatTesterConfig) moreInfo.get("config"); @@ -19,16 +23,15 @@ public Map action(Map moreInfo) throws Exception if (shouldExecuteHook) { File pluginDir = (File) moreInfo.get("pluginDir"); try { - System.out.println("Executing node and node_modules cleanup hook"); + LOGGER.log(Level.INFO, "Executing node and node_modules cleanup hook"); compile(pluginDir); return moreInfo; } catch (Exception e) { - System.out.println("Exception executing hook"); - System.out.println(e); + LOGGER.log(Level.WARNING, "Exception executing hook", e); throw e; } } else { - System.out.println("Hook not triggered. Continuing."); + LOGGER.log(Level.INFO, "Hook not triggered; continuing"); return moreInfo; } } @@ -38,7 +41,7 @@ public void validate(Map toCheck) { } private void compile(File path) throws PomExecutionException, IOException { - System.out.println("Calling removeNodeFolders"); + LOGGER.log(Level.INFO, "Calling removeNodeFolders"); removeNodeFolders(path); } diff --git a/src/main/java/org/jenkins/tools/test/hook/NonStandardTagHook.java b/src/main/java/org/jenkins/tools/test/hook/NonStandardTagHook.java index e716c93e7..bd871d8ae 100644 --- a/src/main/java/org/jenkins/tools/test/hook/NonStandardTagHook.java +++ b/src/main/java/org/jenkins/tools/test/hook/NonStandardTagHook.java @@ -9,6 +9,8 @@ import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; import org.apache.maven.scm.ScmFileSet; import org.apache.maven.scm.ScmTag; import org.apache.maven.scm.command.checkout.CheckOutScmResult; @@ -30,6 +32,8 @@ */ public class NonStandardTagHook extends PluginCompatTesterHookBeforeCheckout { + private static final Logger LOGGER = Logger.getLogger(NonStandardTagHook.class.getName()); + private final Properties affectedPlugins; private final List transformedPlugins = new LinkedList<>(); private final VersionComparator comparator = new VersionComparator(); @@ -45,8 +49,7 @@ public NonStandardTagHook() { } }); } catch (IOException e) { - System.err.println("WARNING: NonStandardTagHook was not able to load affected plugins, the hook will do nothing"); - e.printStackTrace(); + LOGGER.log(Level.WARNING, "NonStandardTagHook was not able to load affected plugins; continuing", e); } } @@ -69,7 +72,7 @@ public Map action(Map info) throws Exception { boolean shouldExecuteHook = config.getLocalCheckoutDir() == null || !config.getLocalCheckoutDir().exists(); if (shouldExecuteHook) { - System.out.println("Executing " + this.getClass().getSimpleName() + " for " + pomData.artifactId); + LOGGER.log(Level.INFO, "Executing {0} for {1}", new Object[]{this.getClass().getSimpleName(), pomData.artifactId}); // Checkout to the parent directory. All other processes will be on the child directory File checkoutPath = new File(config.workDirectory.getAbsolutePath() + "/" + pomData.artifactId); diff --git a/src/main/java/org/jenkins/tools/test/hook/TransformPom.java b/src/main/java/org/jenkins/tools/test/hook/TransformPom.java index 1eb84ab30..a12197351 100644 --- a/src/main/java/org/jenkins/tools/test/hook/TransformPom.java +++ b/src/main/java/org/jenkins/tools/test/hook/TransformPom.java @@ -21,7 +21,7 @@ public class TransformPom extends PluginCompatTesterHookBeforeExecution { private static final String NEW_PLUGINS_PARENT_VERSION_KEY = "newPluginsParentPom"; public TransformPom() { - System.out.println("Loaded TransformPom"); + LOGGER.log(Level.INFO, "Loaded TransformPom"); } /** @@ -47,8 +47,7 @@ public boolean check(Map info) { parentUnder233 = parentV2 && parent.compareVersionTo(PLUGINS_PARENT_POM_FOR_CORE_WITHOUT_WAR_TEST) < 0; } else { //TODO(oleg_nenashev): all these assumptions are unreliable at best (JENKINS-55169) - LOGGER.log(Level.WARNING, "Parent POM is missing for {0}. " + - "Likely it is Incrementals Plugin, hence assuming it's not a CloudBees one and that the version is above 3.4 (JENKINS-55169)", pomData.artifactId); + LOGGER.log(Level.FINE, "No parent POM for {0}", pomData.artifactId); isCB = false; parentV2 = true; parentUnder233 = false; diff --git a/src/main/java/org/jenkins/tools/test/hook/WarningsNGCheckoutHook.java b/src/main/java/org/jenkins/tools/test/hook/WarningsNGCheckoutHook.java index a3544c480..950ffb777 100644 --- a/src/main/java/org/jenkins/tools/test/hook/WarningsNGCheckoutHook.java +++ b/src/main/java/org/jenkins/tools/test/hook/WarningsNGCheckoutHook.java @@ -5,9 +5,13 @@ import java.io.File; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; public class WarningsNGCheckoutHook extends AbstractMultiParentHook { + private static final Logger LOGGER = Logger.getLogger(WarningsNGCheckoutHook.class.getName()); + @Override protected String getParentFolder() { return "warnings-ng-plugin"; @@ -51,7 +55,7 @@ protected void configureLocalCheckOut(UpdateSite.Plugin currentPlugin, File loca firstRun = false; // Change the "download"" directory; after download, it's simply used for reference - System.out.println("Child path for " + currentPlugin.getDisplayName() + " " + pluginDir); + LOGGER.log(Level.INFO, "Child path for {0}: {1}", new Object[]{currentPlugin.getDisplayName(), pluginDir.getPath()}); moreInfo.put("checkoutDir", pluginDir); moreInfo.put("pluginDir", pluginDir); } diff --git a/src/main/java/org/jenkins/tools/test/logging/LoggingConfiguration.java b/src/main/java/org/jenkins/tools/test/logging/LoggingConfiguration.java new file mode 100644 index 000000000..53db3dcf3 --- /dev/null +++ b/src/main/java/org/jenkins/tools/test/logging/LoggingConfiguration.java @@ -0,0 +1,29 @@ +package org.jenkins.tools.test.logging; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UncheckedIOException; +import java.util.MissingResourceException; +import java.util.logging.LogManager; + +/** + * A logging configuration class suitable for passing to {@code -Djava.util.logging.config.class}. + * + * @see LogManager#readConfiguration() + */ +public class LoggingConfiguration { + + public LoggingConfiguration() { + try (InputStream is = LoggingConfiguration.class.getResourceAsStream("logging.properties")) { + if (is == null) { + throw new MissingResourceException("Failed to load logging.properties", LoggingConfiguration.class.getName(), "logging.properties"); + } + + // Prefer new non-null values over old values. + LogManager.getLogManager().updateConfiguration(is, property -> + ((oldValue, newValue) -> oldValue == null && newValue == null ? null : (newValue == null ? oldValue : newValue))); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } +} diff --git a/src/main/java/org/jenkins/tools/test/maven/ExternalMavenRunner.java b/src/main/java/org/jenkins/tools/test/maven/ExternalMavenRunner.java index eaf5f777e..fc5b2e8a2 100644 --- a/src/main/java/org/jenkins/tools/test/maven/ExternalMavenRunner.java +++ b/src/main/java/org/jenkins/tools/test/maven/ExternalMavenRunner.java @@ -15,6 +15,8 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -28,6 +30,8 @@ */ public class ExternalMavenRunner implements MavenRunner { + private static final Logger LOGGER = Logger.getLogger(ExternalMavenRunner.class.getName()); + private static final String DISABLE_DOWNLOAD_LOGS = "-ntp"; @CheckForNull @@ -67,7 +71,7 @@ public void run(Config config, File baseDirectory, File buildLogFile, String... } cmd.addAll(config.mavenOptions); cmd.addAll(Arrays.asList(goals)); - System.out.println("running " + cmd + " in " + baseDirectory + " >> " + buildLogFile); + LOGGER.log(Level.INFO, "Running {0} in {1} >> {2}" + buildLogFile, new Object[]{String.join(" ", cmd), baseDirectory, buildLogFile}); try { Process p = new ProcessBuilder(cmd).directory(baseDirectory).redirectErrorStream(true).start(); List succeededPluginArtifactIds = new ArrayList<>(); @@ -98,8 +102,8 @@ public void run(Config config, File baseDirectory, File buildLogFile, String... } } w.flush(); - System.out.println("succeeded artifactIds: " + succeededPluginArtifactIds); - System.out.println("executed classname tests: " + getExecutedTests()); + LOGGER.log(Level.INFO, "Succeeded artifact IDs: {0}", String.join(",", succeededPluginArtifactIds)); + LOGGER.log(Level.INFO, "Executed tests: {0}", String.join(",", getExecutedTests())); } if (p.waitFor() != 0) { throw new PomExecutionException(cmd + " failed in " + baseDirectory, succeededPluginArtifactIds, @@ -107,10 +111,10 @@ public void run(Config config, File baseDirectory, File buildLogFile, String... new ExecutedTestNamesSolver().solve(getTypes(config), getExecutedTests(), baseDirectory)); } } catch (PomExecutionException x) { - x.printStackTrace(); + LOGGER.log(Level.WARNING, "Failed to run Maven", x); throw x; } catch (Exception x) { - x.printStackTrace(); + LOGGER.log(Level.WARNING, "Failed to run Maven", x); throw new PomExecutionException(x); } } diff --git a/src/main/java/org/jenkins/tools/test/model/MavenBom.java b/src/main/java/org/jenkins/tools/test/model/MavenBom.java index 2987e6e9d..f9d563dac 100644 --- a/src/main/java/org/jenkins/tools/test/model/MavenBom.java +++ b/src/main/java/org/jenkins/tools/test/model/MavenBom.java @@ -3,12 +3,13 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import org.apache.maven.model.Dependency; import org.apache.maven.model.Model; @@ -19,6 +20,8 @@ public class MavenBom { + private static final Logger LOGGER = Logger.getLogger(MavenBom.class.getName()); + private Model contents; public MavenBom(File path) throws IOException, XmlPullParserException { @@ -47,10 +50,8 @@ public File writeFullDepPom(File workDir) throws IOException { try (FileOutputStream out = new FileOutputStream(fullDepPom)) { writer.write(out, modified); return fullDepPom; - } catch (FileNotFoundException e) { - e.printStackTrace(); } catch (IOException e) { - e.printStackTrace(); + LOGGER.log(Level.WARNING, "Failed to write full dependency POM; continuing", e); } return null; } diff --git a/src/main/java/org/jenkins/tools/test/model/MavenPom.java b/src/main/java/org/jenkins/tools/test/model/MavenPom.java index ae7eabc4c..38c04d307 100644 --- a/src/main/java/org/jenkins/tools/test/model/MavenPom.java +++ b/src/main/java/org/jenkins/tools/test/model/MavenPom.java @@ -355,7 +355,7 @@ private void addPlugins(Map adding, Map p if (group != null && !group.isEmpty()) { dependency.addElement(GROUP_ID_ELEMENT).addText(group); } else { - System.err.println("WARNING: no known group ID for plugin " + dep.getKey()); + LOGGER.log(Level.WARNING,"No known group ID for plugin {0}", dep.getKey()); dependency.addElement(GROUP_ID_ELEMENT).addText("org.jenkins-ci.plugins"); } dependency.addElement(ARTIFACT_ID_ELEMENT).addText(dep.getKey()); diff --git a/src/main/java/org/jenkins/tools/test/model/PluginCompatTesterConfig.java b/src/main/java/org/jenkins/tools/test/model/PluginCompatTesterConfig.java index f68be440e..22f5feb41 100644 --- a/src/main/java/org/jenkins/tools/test/model/PluginCompatTesterConfig.java +++ b/src/main/java/org/jenkins/tools/test/model/PluginCompatTesterConfig.java @@ -34,6 +34,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; @@ -352,11 +353,11 @@ public Map retrieveMavenProperties() throws IOException { } if (res.containsKey("jvm")) { - System.out.println("WARNING: Maven properties already contain the 'jvm' argument. " + - "Overriding the previous Test JDK home value '" + res.get("jvm") + + LOGGER.log(Level.WARNING, "Maven properties already contain the 'jvm' argument; " + + "overriding the previous test JDK home value '" + res.get("jvm") + "' by the explicit argument: " + testJDKHome); } else { - System.out.println("Using custom Test JDK home: " + testJDKHome); + LOGGER.log(Level.INFO, "Using custom test JDK home: {0}", testJDKHome); } final String javaCmdAbsolutePath = getTestJavaCommandPath(); res.put("jvm", javaCmdAbsolutePath); @@ -365,8 +366,8 @@ public Map retrieveMavenProperties() throws IOException { // Merge test Java args if needed if (StringUtils.isNotBlank(testJavaArgs)) { if (res.containsKey("argLine")) { - System.out.println("WARNING: Maven properties already contain the 'argLine' argument. " + - "Merging value from properties and from the command line"); + LOGGER.log(Level.WARNING, "Maven properties already contain the 'argLine' argument; " + + "merging value from properties and from the command line"); res.put("argLine", res.get("argLine") + " " + testJavaArgs); } else { res.put("argLine", testJavaArgs); @@ -393,7 +394,7 @@ private String getTestJavaCommandPath() { public String getTestJavaVersion() throws IOException { String javaCmdAbsolutePath = getTestJavaCommandPath(); if (javaCmdAbsolutePath == null) { - LOGGER.info("testJdkHome unset, using java available from the PATH"); + LOGGER.log(Level.INFO, "Test JDK home unset; using Java from PATH"); javaCmdAbsolutePath = "java"; } final Process process = new ProcessBuilder().command(javaCmdAbsolutePath, "-XshowSettings:properties -version").redirectErrorStream(true).start(); diff --git a/src/main/java/org/jenkins/tools/test/model/PluginRemoting.java b/src/main/java/org/jenkins/tools/test/model/PluginRemoting.java index d8ced4c13..2931c1f6c 100644 --- a/src/main/java/org/jenkins/tools/test/model/PluginRemoting.java +++ b/src/main/java/org/jenkins/tools/test/model/PluginRemoting.java @@ -83,7 +83,7 @@ private String retrievePomContentFromHpi() throws PluginSourcesUnavailableExcept try { return retrievePomContentFromHpiRemoteUrl(new URL(hpiRemoteUrl)); } catch (MalformedURLException e) { - LOGGER.log(Level.INFO, String.format("hpi reference %s is not a remote URL", hpiRemoteUrl)); + LOGGER.log(Level.WARNING, "HPI reference {0} is not a remote URL", hpiRemoteUrl); return retrievePomContentFromHpiFileReference(); } } @@ -92,8 +92,8 @@ private String retrievePomContentFromHpiRemoteUrl(URL url) throws PluginSourcesU try { return retrievePomContentFromInputStream(url.openStream()); } catch (IOException e) { - System.err.println("Error : " + e.getMessage()); - throw new PluginSourcesUnavailableException("Problem while retrieving pom content in hpi !", e); + LOGGER.log(Level.WARNING, "Failed to retrieve POM content from HPI remote URL", e); + throw new PluginSourcesUnavailableException("Failed to retrieve POM content from HPI remote URL", e); } } @@ -102,8 +102,8 @@ private String retrievePomContentFromHpiFileReference() throws PluginSourcesUnav String fileReference = hpiRemoteUrl.replaceAll("jar:", "").replaceAll("!/name.hpi", ""); return retrievePomContentFromInputStream(FileUtils.openInputStream(new File(fileReference))); } catch (IOException e) { - System.err.println("Error : " + e.getMessage()); - throw new PluginSourcesUnavailableException("Problem while retrieving pom content in hpi !", e); + LOGGER.log(Level.WARNING, "Failed to retrieve POM content from HPI file reference", e); + throw new PluginSourcesUnavailableException("Failed to retrieve POM content from HPI file reference", e); } } @@ -123,8 +123,8 @@ private String retrievePomContentFromInputStream(InputStream pluginUrlStream) th return sb.toString(); } catch (Exception e) { - System.err.println("Error : " + e.getMessage()); - throw new PluginSourcesUnavailableException("Problem while retrieving pom content in hpi !", e); + LOGGER.log(Level.WARNING, "Failed to retrieve POM content from input stream", e); + throw new PluginSourcesUnavailableException("Failed to retrieve POM content from input stream", e); } } @@ -132,8 +132,8 @@ private String retrievePomContentFromXmlFile() throws PluginSourcesUnavailableEx try { return FileUtils.readFileToString(pomFile); } catch(Exception e) { - System.err.println("Error : " + e.getMessage()); - throw new PluginSourcesUnavailableException(String.format("Problem while retrieving pom content from file %s", pomFile), e); + LOGGER.log(Level.WARNING, String.format("Failed to retrieve POM content from XML file '%s'", pomFile), e); + throw new PluginSourcesUnavailableException(String.format("Failed to retrieve POM content from XML file '%s'", pomFile), e); } } @@ -167,24 +167,20 @@ public PomData retrievePomData() throws PluginSourcesUnavailableException { String parentNode = xpath.evaluate("/project/parent", doc); if (StringUtils.isNotBlank(parentNode)) { - LOGGER.log(Level.INFO, parentNode); + LOGGER.log(Level.FINE, "Parent POM: {0}", parentNode); parent = new MavenCoordinates( getValueOrFail(doc, xpath, "/project/parent/groupId"), getValueOrFail(doc, xpath, "/project/parent/artifactId"), getValueOrFail(doc, xpath, "/project/parent/version")); } else { - LOGGER.log(Level.WARNING, "No parent POM reference for artifact {0}, " + - "likely a plugin with Incrementals support is used (Jenkins JEP-305). " + - "Will try to ignore it (FTR https://issues.jenkins-ci.org/browse/JENKINS-55169). " + - "hpiRemoteUrl={1}, pomFile={2}", - new Object[] {artifactId, hpiRemoteUrl, pomFile}); + LOGGER.log(Level.FINE, "No parent POM for {0}", artifactId); } } catch (ParserConfigurationException | SAXException | IOException e) { - System.err.println("Error : " + e.getMessage()); - throw new PluginSourcesUnavailableException("Problem during pom.xml parsing", e); + LOGGER.log(Level.WARNING, "Failed to parse pom.xml", e); + throw new PluginSourcesUnavailableException("Failed to parse pom.xml", e); } catch (XPathExpressionException e) { - System.err.println("Error : " + e.getMessage()); - throw new PluginSourcesUnavailableException("Problem while retrieving plugin's scm connection", e); + LOGGER.log(Level.WARNING, "Failed to retrieve SCM connection", e); + throw new PluginSourcesUnavailableException("Failed to retrieve SCM connection", e); } PomData pomData = new PomData(artifactId, packaging, scmConnection, scmTag, parent, groupId); diff --git a/src/main/java/org/jenkins/tools/test/model/hook/PluginCompatTesterHooks.java b/src/main/java/org/jenkins/tools/test/model/hook/PluginCompatTesterHooks.java index 2ab5efad7..41a3d6023 100644 --- a/src/main/java/org/jenkins/tools/test/model/hook/PluginCompatTesterHooks.java +++ b/src/main/java/org/jenkins/tools/test/model/hook/PluginCompatTesterHooks.java @@ -16,6 +16,8 @@ import java.util.Map; import java.util.Queue; import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; import java.util.stream.Collectors; import org.reflections.Reflections; import org.reflections.util.ConfigurationBuilder; @@ -29,6 +31,8 @@ * never be called. */ public class PluginCompatTesterHooks { + private static final Logger LOGGER = Logger.getLogger(PluginCompatTesterHooks.class.getName()); + private Set classLoaders = new HashSet<>(Collections.singletonList(PluginCompatTesterHooks.class.getClassLoader())); private List hookPrefixes = new ArrayList<>(); private static Map>> hooksByType = new HashMap<>(); @@ -103,19 +107,18 @@ private Map runHooks(String stage, Map elements) // Modifications build on each other, pertinent checks should be handled in the hook for(PluginCompatTesterHook hook : beforeHooks) { try { - System.out.println("Processing " + hook.getClass().getName()); if(!excludeHooks.contains(hook.getClass().getName()) && hook.check(elements)) { + LOGGER.log(Level.INFO, "Running hook: {0}", hook.getClass().getName()); elements = hook.action(elements); hook.validate(elements); } else { - System.out.println("Hook not triggered. Continuing."); + LOGGER.log(Level.FINE, "Skipping hook: {0}", hook.getClass().getName()); } } catch (RuntimeException re) { //this type of exception should stop processing the plugins. Throw it up the chain throw re; } catch (Exception ex) { - ex.printStackTrace(); - System.out.println("Cannot make transformation; continue."); + LOGGER.log(Level.WARNING, "Failed to run hook; continuing", ex); } } return elements; @@ -179,7 +182,7 @@ private Map> findHooks(String stage) { // Ignore abstract hooks if (!Modifier.isAbstract(c.getModifiers())) { try { - System.out.println("Hook: " + c.getName()); + LOGGER.log(Level.FINE, "Loading hook: {0}", c.getName()); Constructor constructor = c.getConstructor(); PluginCompatTesterHook hook = (PluginCompatTesterHook) constructor.newInstance(); @@ -193,8 +196,7 @@ private Map> findHooks(String stage) { sortedHooks.put(plugin, allForType); } } catch (Exception ex) { - System.out.println("Error when loading " + c.getName()); - ex.printStackTrace(); + LOGGER.log(Level.WARNING, "Error when loading " + c.getName() + "; continuing", ex); } } } diff --git a/src/main/resources/org/jenkins/tools/test/logging/logging.properties b/src/main/resources/org/jenkins/tools/test/logging/logging.properties new file mode 100644 index 000000000..4c3a2d1b4 --- /dev/null +++ b/src/main/resources/org/jenkins/tools/test/logging/logging.properties @@ -0,0 +1,38 @@ +############################################################ +# Default Logging Configuration File +# +# You can use a different file by specifying a filename +# with the java.util.logging.config.file system property. +# For example, java -Djava.util.logging.config.file=myfile +############################################################ + +############################################################ +# Global properties +############################################################ + +# "handlers" specifies a comma-separated list of log Handler +# classes. These handlers will be installed during VM startup. +# Note that these classes must be on the system classpath. +# By default we only configure a ConsoleHandler, which will only +# show messages at the INFO and above levels. +handlers= java.util.logging.ConsoleHandler + +# Default global logging level. +# This specifies which kinds of events are logged across +# all loggers. For any given facility this global level +# can be overridden by a facility-specific level +.level= INFO + +############################################################ +# Handler specific properties. +# Describes specific configuration info for Handlers. +############################################################ + +java.util.logging.ConsoleHandler.formatter = io.jenkins.lib.support_log_formatter.SupportLogFormatter + +############################################################ +# Facility-specific properties. +# Provides extra control for each logger. +############################################################ + +org.reflections.level= WARNING diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml deleted file mode 100755 index ecbb26752..000000000 --- a/src/test/resources/logback-test.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %d %-5p %c{2} : %m%n - - - - - - - - \ No newline at end of file