diff --git a/src/main/java/hudson/MockExtensionLists.java b/src/main/java/hudson/MockExtensionLists.java index fb6183f..044471d 100644 --- a/src/main/java/hudson/MockExtensionLists.java +++ b/src/main/java/hudson/MockExtensionLists.java @@ -17,30 +17,30 @@ import jenkins.model.Jenkins; public class MockExtensionLists { - private static Map extensionLists = new HashMap(); + private static Map> extensionLists = new HashMap>(); - public ExtensionList getMockExtensionList(HyperLocalPluginManger hlpm, Jenkins hudson, Class type) { + public ExtensionList getMockExtensionList(HyperLocalPluginManger hlpm, Jenkins hudson, Class type) { if(extensionLists.get(type.getName()) != null) { return extensionLists.get(type.getName()); } else { - MockExtensionList mockList = new MockExtensionList(hlpm, hudson, type); + MockExtensionList mockList = new MockExtensionList<>(hlpm, hudson, type); extensionLists.put(type.getName(), mockList.getMockExtensionList()); return mockList.getMockExtensionList(); } } - private class MockExtensionList { - ExtensionList mockExtensionList; + private class MockExtensionList { + ExtensionList mockExtensionList; - public MockExtensionList(HyperLocalPluginManger hlpm, Jenkins hudson, Class type) { - ExtensionList realList = ExtensionList.create(hudson, type); + public MockExtensionList(HyperLocalPluginManger hlpm, Jenkins hudson, Class type) { + ExtensionList realList = ExtensionList.create(hudson, type); mockExtensionList = spy(realList); doReturn("Locking resources").when(mockExtensionList).getLoadLock(); doAnswer(mockLoad(hlpm)).when(mockExtensionList).load(); } - private Answer>> mockLoad(HyperLocalPluginManger hlpm) { + private Answer>> mockLoad(HyperLocalPluginManger hlpm) { return new Answer>>() { public List> answer(InvocationOnMock invocation) throws Throwable { return hlpm.getPluginStrategy().findComponents(mockExtensionList.extensionType, (Hudson)null); @@ -48,7 +48,7 @@ public List> answer(InvocationOnMock invocation) throws Th }; } - public ExtensionList getMockExtensionList(){ + public ExtensionList getMockExtensionList(){ return mockExtensionList; } } diff --git a/src/main/java/org/jenkinsci/pipeline_steps_doc_generator/HyperLocalPluginManger.java b/src/main/java/org/jenkinsci/pipeline_steps_doc_generator/HyperLocalPluginManger.java index 853efb8..78d034d 100644 --- a/src/main/java/org/jenkinsci/pipeline_steps_doc_generator/HyperLocalPluginManger.java +++ b/src/main/java/org/jenkinsci/pipeline_steps_doc_generator/HyperLocalPluginManger.java @@ -34,6 +34,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.logging.Level; +import java.util.logging.Logger; /** * Acts as a PluginManager that operates outside the normal startup process of Jenkins. Essentially, this captures the @@ -44,6 +45,7 @@ * use calls to Jenkins. */ public class HyperLocalPluginManger extends LocalPluginManager{ + private static final Logger LOG = Logger.getLogger(HyperLocalPluginManger.class.getName()); private final ModClassicPluginStrategy strategy; public final UberPlusClassLoader uberPlusClassLoader = new UberPlusClassLoader(); private final boolean checkCycles; @@ -126,7 +128,7 @@ public void run(Reactor session1) throws Exception { private boolean isDuplicate(PluginWrapper p) { String shortName = p.getShortName(); if (inspectedShortNames.containsKey(shortName)) { - System.out.println("Ignoring "+arc+" because "+inspectedShortNames.get(shortName)+" is already loaded"); + LOG.info("Ignoring "+arc+" because "+inspectedShortNames.get(shortName)+" is already loaded"); return true; } @@ -164,7 +166,7 @@ private void addTo(List dependencies, List cycle) throws hudson.util.CyclicGraphDetector.CycleDetectedException { - System.out.println("FATAL: found cycle in plugin dependencies: (root="+q+", deactivating all involved) "+Util.join(cycle," -> ")); + LOG.severe("FATAL: found cycle in plugin dependencies: (root="+q+", deactivating all involved) "+Util.join(cycle," -> ")); for (PluginWrapper pluginWrapper : cycle) { pluginWrapper.setHasCycleDependency(true); failedPlugins.add(new FailedPlugin(pluginWrapper.getShortName(), new CycleDetectedException(cycle))); @@ -205,7 +207,7 @@ public final class UberPlusClassLoader extends ClassLoader { * Make generated types visible. * Keyed by the generated class name. */ - private ConcurrentMap> generatedClasses = new ConcurrentHashMap>(); + private ConcurrentMap>> generatedClasses = new ConcurrentHashMap>>(); /** Cache of loaded, or known to be unloadable, classes. */ private final Map> loaded = new HashMap>(); private final Map byPlugin = new HashMap(); @@ -214,16 +216,16 @@ public UberPlusClassLoader() { super(PluginManager.class.getClassLoader()); } - public void addNamedClass(String className, Class c) { - generatedClasses.put(className,new WeakReference(c)); + public void addNamedClass(String className, Class c) { + generatedClasses.put(className,new WeakReference>(c)); } @Override protected Class findClass(String name) throws ClassNotFoundException { //likely want to avoid this, but we'll deal with it right now. - WeakReference wc = generatedClasses.get(name); + WeakReference> wc = generatedClasses.get(name); if (wc!=null) { - Class c = wc.get(); + Class c = wc.get(); if (c!=null) return c; else generatedClasses.remove(name,wc); } @@ -270,7 +272,7 @@ protected Class findClass(String name) throws ClassNotFoundException { } else { for (PluginWrapper p : activePlugins) { try { - Class c = p.classLoader.loadClass(name); + Class c = p.classLoader.loadClass(name); synchronized (byPlugin){ byPlugin.put(c.getName(), p.getShortName()); } @@ -447,7 +449,7 @@ private Collection> _find(Class type, List extType; if (e instanceof Class) { - extType = (Class) e; + extType = (Class) e; } else if (e instanceof Field) { extType = ((Field)e).getType(); @@ -465,20 +467,20 @@ private Collection> _find(Class type, List extensionType, ClassLoader cl) { for (IndexItem item : getIndices(cl)) { try { AnnotatedElement e = item.element(); Class extType; if (e instanceof Class) { - extType = (Class) e; + extType = (Class) e; } else if (e instanceof Field) { extType = ((Field)e).getType(); @@ -490,14 +492,10 @@ public void scout(Class extensionType, ClassLoader cl) { // according to JDK-4993813 this is the only way to force class initialization Class.forName(extType.getName(),true,extType.getClassLoader()); } catch (Exception | LinkageError e) { - System.out.println("Failed to scout " + item.className() + "\n" + e); + LOG.fine("Failed to scout " + item.className() + "\n" + e); } } } - - private Level logLevel(IndexItem item) { - return item.annotation().optional() ? Level.FINE : Level.WARNING; - } } /** @@ -510,11 +508,11 @@ protected String getPluginNameForDescriptor(Descriptor d) { try { uberPlusClassLoader.findClass(className); } catch (ClassNotFoundException e) { - e.printStackTrace(); + LOG.log(Level.WARNING, "Class not found", e); } String pluginName = uberPlusClassLoader.getByPlugin().get(className); if (pluginName == null) { - System.out.println("No plugin found, assuming core: " + className); + LOG.info("No plugin found, assuming core: " + className); return "core"; } return pluginName.trim(); diff --git a/src/main/java/org/jenkinsci/pipeline_steps_doc_generator/PipelineStepExtractor.java b/src/main/java/org/jenkinsci/pipeline_steps_doc_generator/PipelineStepExtractor.java index 0759ba3..ac61faf 100644 --- a/src/main/java/org/jenkinsci/pipeline_steps_doc_generator/PipelineStepExtractor.java +++ b/src/main/java/org/jenkinsci/pipeline_steps_doc_generator/PipelineStepExtractor.java @@ -32,6 +32,7 @@ import javax.annotation.CheckForNull; import javax.annotation.Nonnull; + import java.io.File; import java.io.IOException; import java.io.Serializable; @@ -46,6 +47,8 @@ import java.util.Set; import java.util.TreeSet; import java.util.function.Predicate; +import java.util.logging.Level; +import java.util.logging.Logger; import java.util.stream.Stream; import static org.mockito.Mockito.*; @@ -54,6 +57,10 @@ * Process and find all the Pipeline steps definied in Jenkins plugins. */ public class PipelineStepExtractor { + private static final Logger LOG = Logger.getLogger(PipelineStepExtractor.class.getName()); + static { + System.setProperty("java.util.logging.SimpleFormatter.format","[%4$-7s] %5$s %6$s%n"); + } @Option(name="-homeDir",usage="Root directory of the plugin folder. This serves as the root directory of the PluginManager.") public String homeDir = null; @@ -69,18 +76,16 @@ public static void main(String[] args){ CmdLineParser p = new CmdLineParser(pse); p.parseArgument(args); } catch(Exception ex){ - ex.printStackTrace(); - System.out.println("There was an error with parsing the commands, defaulting to the home directory."); + LOG.log(Level.SEVERE, "There was an error with parsing the commands, defaulting to the home directory.", ex); } try{ Map>> steps = pse.findSteps(); pse.generateAscii(steps, pse.pluginManager); pse.generateDeclarativeAscii(); } catch(Exception ex){ - ex.printStackTrace(); - System.out.println("Error in finding all the steps"); + LOG.log(Level.SEVERE, "Error in finding all the steps", ex); } - System.out.println("CONVERSION COMPLETE!"); + LOG.info("CONVERSION COMPLETE!"); System.exit(0); //otherwise environment hangs around } @@ -128,8 +133,7 @@ public Map>> findSteps(){ completeListing.put(opt, exists); } } catch (Exception ex){ - ex.printStackTrace(); - //log exception, job essentially fails + LOG.log(Level.SEVERE, "Step generation failed", ex); } return completeListing; @@ -206,7 +210,7 @@ protected void runTask(Task task) throws Exception { new InitReactorRunner() { @Override protected void onInitMilestoneAttained(InitMilestone milestone) { - System.out.println("init milestone attained " + milestone); + LOG.info("init milestone attained " + milestone); } }.run(reactor); } @@ -239,7 +243,7 @@ public void generateAscii(Map>> allSte allAscii.mkdirs(); String allAsciiPath = allAscii.getAbsolutePath(); for(String plugin : allSteps.keySet()){ - System.out.println("processing " + plugin); + LOG.info("processing " + plugin); Map> byPlugin = allSteps.get(plugin); PluginWrapper thePlugin = pluginManager.getPlugin(plugin); String displayName = thePlugin == null ? "Jenkins Core" : thePlugin.getDisplayName(); @@ -248,8 +252,7 @@ public void generateAscii(Map>> allSte try { FileUtils.writeStringToFile(new File(allAsciiPath, plugin + ".adoc"), whole9yards, StandardCharsets.UTF_8); } catch (Exception ex){ - ex.printStackTrace(); - System.out.println("Error generating plugin file for " + plugin + ". Skip."); + LOG.log(Level.SEVERE, "Error generating plugin file for " + plugin + ". Skip.", ex); //continue to next plugin } } @@ -268,12 +271,12 @@ public void generateDeclarativeAscii() { Map, Predicate> filters = getDeclarativeFilters(); for (Map.Entry>> entry : getDeclarativeDirectives().entrySet()) { - System.out.println("Generating docs for directive " + entry.getKey()); + LOG.info("Generating docs for directive " + entry.getKey()); Map> pluginDescMap = new HashMap<>(); for (Class d : entry.getValue()) { Predicate filter = filters.get(d); - System.out.println(" - Loading descriptors of type " + d.getSimpleName() + " with filter: " + (filter != null)); + LOG.info(" - Loading descriptors of type " + d.getSimpleName() + " with filter: " + (filter != null)); pluginDescMap = processDescriptors(d, pluginDescMap, filter); } @@ -281,9 +284,8 @@ public void generateDeclarativeAscii() { try{ FileUtils.writeStringToFile(new File(declPath, entry.getKey() + ".adoc"), whole9yards, StandardCharsets.UTF_8); - } catch (Exception ex){ - ex.printStackTrace(); - System.out.println("Error generating directive file for " + entry.getKey() + ". Skip."); + } catch (Exception ex) { + LOG.log(Level.SEVERE, "Error generating directive file for " + entry.getKey() + ". Skip.", ex); //continue to next directive } } diff --git a/src/main/java/org/jenkinsci/pipeline_steps_doc_generator/ToAsciiDoc.java b/src/main/java/org/jenkinsci/pipeline_steps_doc_generator/ToAsciiDoc.java index b67b3ec..acf42f3 100644 --- a/src/main/java/org/jenkinsci/pipeline_steps_doc_generator/ToAsciiDoc.java +++ b/src/main/java/org/jenkinsci/pipeline_steps_doc_generator/ToAsciiDoc.java @@ -28,12 +28,15 @@ import java.util.Optional; import java.util.Set; import java.util.Stack; +import java.util.logging.Level; +import java.util.logging.Logger; import java.util.stream.Collectors; //fake out unit tests import hudson.Main; public class ToAsciiDoc { + private static final Logger LOG = Logger.getLogger(ToAsciiDoc.class.getName()); /** * Keeps track of nested {@link DescribableModel#getType()} to avoid recursion. */ @@ -81,6 +84,7 @@ private static String describeType(ParameterType type) throws Exception { } } else if (type instanceof ErrorType) { //Shouldn't hit this; open a ticket Exception x = ((ErrorType) type).getError(); + LOG.log(Level.FINE, "Encountered ErrorType object with exception:" + x); if(x instanceof NoStaplerConstructorException || x instanceof UnsupportedOperationException) { String msg = x.toString(); typeInfo.append("").append(msg.substring(msg.lastIndexOf(" ")).trim()).append("\n"); @@ -99,8 +103,13 @@ private static String generateAttrHelp(DescribableParameter param) throws Except if (help != null && !help.equals("")) { attrHelp.append(helpify(help)).append("\n"); } - ParameterType type = param.getType(); - attrHelp.append("
    ").append(describeType(type)).append("
"); + try { + String typeDesc = describeType(param.getType()); + attrHelp.append("
    ").append(typeDesc).append("
"); + } catch (RuntimeException | Error ex) { + LOG.log(Level.WARNING, "Restricted description of attribute " + + param.getName(), ex); + } return attrHelp.toString(); } @@ -164,7 +173,7 @@ public static String generateStepHelp(QuasiDescriptor d){ } } catch (Exception | Error ex) { mkDesc.append("").append(ex).append(""); - System.out.println("Description of " + d.real.clazz + " skipped, encountered " + ex); + LOG.log(Level.SEVERE, "Description of " + d.real.clazz + " skipped, encountered ", ex); } return mkDesc.append("\n\n\n++++\n").toString(); } @@ -174,7 +183,7 @@ private static void appendSimpleStepDescription(StringBuilder mkDesc, Class c mkDesc.append(generateHelp(new DescribableModel<>(clazz), true)); } catch (Exception ex) { mkDesc.append(getHelp("help.html", clazz)); - System.out.println("Description of " + clazz + " restricted, encountered " + ex); + LOG.log(Level.WARNING, "Description of " + clazz + " restricted, encountered ", ex); } } @@ -207,14 +216,10 @@ private static String generateDescribableHelp(Descriptor d) { StringBuilder mkDesc = new StringBuilder(header(3)).append(" `").append(symbols.iterator().next()).append("`: ").append(d.getDisplayName()).append("\n"); try { mkDesc.append(generateHelp(new DescribableModel<>(d.clazz), true)).append("\n\n"); - } catch (Exception ex) { - ex.printStackTrace(); + } catch (Exception | Error ex) { + LOG.log(Level.SEVERE, "Problem generating help for descriptor", ex); // backtick-plus for safety - monospace literal string mkDesc.append("`+").append(ex).append("+`\n\n"); - } catch (Error err) { - err.printStackTrace(); - // backtick-plus for safety - monospace literal string - mkDesc.append("`+").append(err).append("+`\n\n"); } return mkDesc.toString(); } else {