Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added new feature to fail based on different conditions #363

Conversation

abelsromero
Copy link
Member

@abelsromero abelsromero commented Aug 4, 2018

Addresses: #261, #178

Features are complete, but there's an issue with duplicated asciidoctor messages asciidoctor/asciidoctorj#669. Depending on suggestions we can merge or review the feature.

Feature summary
This PR adds a new configuration element as follows:

<logHandler>
	<outputToConsole>true</outputToConsole>
	<failIf>
		<severity>WARNING</severity>
		<containsText>super-important-document.adoc</containsText>
	</failIf>
</logHandler>
  • outputToConsole: redirects asciidoctor messages to maven's logger. Messages are shown as Maven's INFO during renderitzation. Messages will appear twice as mentioned in issue Unable to prevent messages from showing in console using LogHandler asciidoctorj#669.
  • severity: named so to align with AsciidoctorJ property. Will make the build fail if a message of this severity level is found. It only matches the exact level, not same and above. I did this for simplicity but I am open to suggestions, implementation is trivial. I finally decided to filter all messages above certain level to allow capturing all messages easily, also, feels more natural to understand.
  • containsText: named so instead of matchesText because it just asserts that, a contains. I considered the option of allowing regex, but this made configuration more complex and less expressive for simple cases like a simple contains. Adding regex options could be done with another option or some custom syntax in the field.

Note that if both severity and containsText are set, only messages that match both are captured.
Messages that match severity and/or containsText are shown as Maven ERROR (independently from outputToConsole), so that CIs can capture them as cause of build fail. Also, an initial error message showing the number of issues found is returned.

If someone wants to create a custom report like mentioned in #261, you can register a custom LogHandler using the SPI interface (added integration test for that). However, this has some limitations with some formats that need to "close" and estructure (see asciidoctor/asciidoctor#2832).

Other notes

  • Filenames are formated to show relative path from project sourceDirectory. I considered that showing the absolute path as provided by AsciidoctorJ logger bloates the messages. Showing full path could be enabled with a new boolean option in the sections if requested.
  • Since severity and containsText are validated after the renderitzation the target document (html, pdf, etc.) can be found in the target directory. I don't see any reason to delete it.
  • I know the code is not the best, but can be improved in the future with Java8 features.

Other changes to code

  • Updated AsciidoctorJ to 1.5.67 and updated InlineMacroProcessor test extension to new especification
  • Aligned JRuby with AsciidoctorJ: updated jruby-complete to 9.1.16.0: updated maven-plugin-plugin from 3.4 to 3.5 to fix issue after updating jruby-complete
  • Refactored mocking of Plexus in tests.

I kept code as Java 7 compatible, but AsciidoctorJ is 1.8. I'd add that to docs and release notes when PR is agreed. I did not want to add more things to the mix.

@abelsromero abelsromero force-pushed the add_capture_of_Asciidoctor_log_messages branch from 37b32b2 to 20f4c02 Compare August 4, 2018 20:18
@coveralls
Copy link

coveralls commented Aug 4, 2018

Coverage Status

Coverage increased (+1.6%) to 67.633% when pulling d2b17e1 on abelsromero:add_capture_of_Asciidoctor_log_messages into 869aa78 on asciidoctor:master.

@abelsromero
Copy link
Member Author

Added README, no more changes to make.

@abelsromero
Copy link
Member Author

no comments?

cc @mojavelinux

@lpetit-yseop
Copy link

Hello,

Overall, I'd be interested in having the build fail whenever there's a missing file to include, image to embed, etc.
Failing to fail fast seems like a recipe for a documentation whose quality declines over time without anybody noticing … (or else I'll have to write Unit Tests for my documentation, yuk!).

I understand that the feature addressed by this PR could help me do what I want, short of being able to configure asciidoctor to emit ERRORS instead of WARNINGS.

Just so you know there are people around here watching the progress of the Pull Request ;-)

@abelsromero abelsromero merged commit f38a472 into asciidoctor:master Sep 12, 2018
@lpetit-yseop
Copy link

Hey, just built locally and tried the new feature (why haven't I done so earlier? dunno…)

The <failIf><severity>WARN</severity></failIf> option works like a charm!!

On a side note, the <outputToConsole> did not work that well:

  • if not set, I have no asciidoctor log displayed => not even the WARN on the missing included file
  • if explicitly set to true via <outputToConsole>true</outputToConsole>, I get jruby errors printed on the console like:
Sep 13, 2018 12:01:14 PM org.asciidoctor.internal.JRubyAsciidoctor log
WARNING: Unexpected exception while logging Asciidoctor log entry
java.lang.NullPointerException
	at org.asciidoctor.maven.log.LogRecordHelper.format(LogRecordHelper.java:33)
	at org.asciidoctor.maven.log.MemoryLogHandler.log(MemoryLogHandler.java:34)
	at org.asciidoctor.internal.JRubyAsciidoctor.log(JRubyAsciidoctor.java:664)
	at org.asciidoctor.log.internal.JavaLogger.add(JavaLogger.java:89)
	at org.asciidoctor.log.internal.JavaLogger$INVOKER$i$0$2$add.call(JavaLogger$INVOKER$i$0$2$add.gen)
	at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:77)
	at org.jruby.ir.instructions.CallBase.interpret(CallBase.java:432)
	at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:360)
	at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:84)
	at org.jruby.internal.runtime.methods.InterpretedIRMethod.INTERPRET_METHOD(InterpretedIRMethod.java:186)
	at org.jruby.internal.runtime.methods.InterpretedIRMethod.call(InterpretedIRMethod.java:173)
	at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:153)
	at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:315)
	at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:127)
	at org.jruby.runtime.InterpretedIRBlockBody.commonYieldPath(InterpretedIRBlockBody.java:141)
	at org.jruby.runtime.IRBlockBody.doYield(IRBlockBody.java:186)
	at org.jruby.runtime.BlockBody.yield(BlockBody.java:116)
	at org.jruby.runtime.Block.yield(Block.java:165)
	at org.jruby.RubyString.gsubCommon19(RubyString.java:2635)
	at org.jruby.RubyString.gsubCommon19(RubyString.java:2589)
	at org.jruby.RubyString.gsub19(RubyString.java:2547)
	at org.jruby.RubyString$INVOKER$i$gsub19.call(RubyString$INVOKER$i$gsub19.gen)
	at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:163)
	at org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:170)
	at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:336)
	at org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:159)
	at org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:90)
	at org.jruby.internal.runtime.methods.InterpretedIRMethod.INTERPRET_METHOD(InterpretedIRMethod.java:218)
	at org.jruby.internal.runtime.methods.InterpretedIRMethod.call(InterpretedIRMethod.java:209)
	at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:181)
	at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:324)

@lpetit-yseop
Copy link

Well, maybe I spoke a little bit too early @abelsromero : when I stop deliberately putting errors (e.g. including inexistant files) in my asciidocs, then I expect the build to succeed.
Instead, I've got a NullPointerException, quite similar to the one above. With the difference that this exception is logged at maven level as an error and fails the build:

[INFO] Rendered /home/dev/yseop-suite/com.yseop.suite/com.yseop.manager.installer/src/main/asciidoc/yseop-manager-installation-guide.adoc
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 12.905 s
[INFO] Finished at: 2018-09-13T12:35:50+02:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.asciidoctor:asciidoctor-maven-plugin:1.5.7-SNAPSHOT:process-asciidoc (asciidoc-to-html) on project com.yseop.manager.installer: Execution asciidoc-to-html of goal org.asciidoctor:asciidoctor-maven-plugin:1.5.7-SNAPSHOT:process-asciidoc failed.: NullPointerException -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.asciidoctor:asciidoctor-maven-plugin:1.5.7-SNAPSHOT:process-asciidoc (asciidoc-to-html) on project com.yseop.manager.installer: Execution asciidoc-to-html of goal org.asciidoctor:asciidoctor-maven-plugin:1.5.7-SNAPSHOT:process-asciidoc failed.
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:213)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:154)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:146)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:954)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:288)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:192)
    at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:498)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:289)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:229)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:415)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:356)
Caused by: org.apache.maven.plugin.PluginExecutionException: Execution asciidoc-to-html of goal org.asciidoctor:asciidoctor-maven-plugin:1.5.7-SNAPSHOT:process-asciidoc failed.
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:148)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:208)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:154)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:146)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:954)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:288)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:192)
    at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:498)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:289)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:229)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:415)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:356)
Caused by: java.lang.NullPointerException
    at org.asciidoctor.maven.log.LogRecordHelper.format (LogRecordHelper.java:33)
    at org.asciidoctor.maven.AsciidoctorMojo.execute (AsciidoctorMojo.java:266)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:208)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:154)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:146)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:954)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:288)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:192)
    at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:498)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:289)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:229)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:415)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:356)

@mojavelinux
Copy link
Member

I like the proposal and I'm glad you decided to move forward with it. I think the containsText is especially clever because it satisfies the functionality several people have been using to layer on top of their build.

If there are improvements to be made, I agree we should handle them as discrete issues. You don't want an issue to get so huge it never gets delivered.

@abelsromero abelsromero deleted the add_capture_of_Asciidoctor_log_messages branch October 21, 2018 10:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants