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

Show how to generate EPUB and MOBI #13

Open
mraible opened this issue Oct 14, 2015 · 46 comments
Open

Show how to generate EPUB and MOBI #13

mraible opened this issue Oct 14, 2015 · 46 comments
Assignees

Comments

@mraible
Copy link

mraible commented Oct 14, 2015

There is an example project that shows how to generate an EPUB document. The documentation for asciidoctor-epub3 says it's also capable of generating a MOBI document.

https://github.com/asciidoctor/asciidoctor-epub3

Can you please document how to generate an EPUB and a MOBI document in the same project? Here's what I tried. A build/asciidoctor/kf8 directory is created, but there's nothing in it.

asciidoctor {
    backends 'html5', 'pdf', 'epub3', 'kf8'
    attributes 'sourcedir': '../../../main/webapp',
            'source-highlighter': 'coderay',
            'imagesdir': './images',
             toc: 'left',
             icons: 'font',
             linkattrs: true,
             encoding: 'utf-8',
            'setanchors': 'true',
            'idprefix': '',
            'idseparator': '-',
            'docinfo1': 'true'
}
@danhyun
Copy link
Member

danhyun commented Oct 14, 2015

That's a great request. Last I checked I believe the epub3 backend should generate an epub first then use that as a basis for the conversion to mobi. I'll look into adding a mobi specific example.

@danhyun danhyun self-assigned this Oct 14, 2015
@mraible
Copy link
Author

mraible commented Oct 29, 2015

Just curious - what's the difference between the generated index.epub (when using the defaults) and the index-kf8.epub (that's generated when specifying attributes 'ebook-format': 'kf8')? They both seem to render just fine in iBooks.

@mojavelinux mojavelinux changed the title Show how to demonstrate generating EPUB and MOBI Show how to generate EPUB and MOBI Oct 29, 2015
@mojavelinux
Copy link
Member

index-kf8.epub is an intermediary file for generating .mobi. Kindlegen requires a few changes to the EPUB3 in order to properly produce a .mobi file and this file has those changes. Otherwise, it's just a temp file for debugging (so you can see what we sent to kindlegen).

@mojavelinux
Copy link
Member

kf8 isn't a separate backend. Instead, you have to run Asciidoctor twice using a different value for the ebook-format attribute each time.

  • The first time, ebook-format=epub3
  • The second time, ebook-format=kf8

To handle this case, I recommend having a separate Asciidoctor task rather than a collection of backends in a single Asciidoctor task.

However, it might be nice if the Gradle plugin detected the kf8 backend and created another invocation of the epub3 backend with ebook-format set. Perhaps open an issue in the Gradle plugin and we can figure out how to best handle this scenario.

@rwinch
Copy link
Member

rwinch commented Oct 29, 2015

@mojavelinux I was just looking into putting a sample together. The sample is just trying to do kf8 for now.

Running with the asciidoctor-epub3 (ruby) it seems to work. However, Gradle seems I get the following error:

$ ./gradlew asciidoctor --stacktrace
:asciidoctor
Wrote KF8 to /Users/rwinch/code/asciidoctor-gradle-examples/asciidoc-to-epub3-kf8-example/build/asciidoc/epub3/example-manual-kf8.epub
:asciidoctor FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':asciidoctor'.
> Error running Asciidoctor

* Try:
Run with --info or --debug option to get more log output.

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':asciidoctor'.
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:69)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
    at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
    at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:64)
    at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
    at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:52)
    at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
    at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
    at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:208)
    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:186)
    at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:62)
    at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:50)
    at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:25)
    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:111)
    at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:37)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:62)
    at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23)
    at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:68)
    at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:62)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:55)
    at org.gradle.initialization.DefaultGradleLauncher$6.run(DefaultGradleLauncher.java:174)
    at org.gradle.internal.Factories$1.create(Factories.java:22)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:62)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:47)
    at org.gradle.initialization.DefaultGradleLauncher.runBuildOperation(DefaultGradleLauncher.java:189)
    at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:171)
    at org.gradle.initialization.DefaultGradleLauncher.access$200(DefaultGradleLauncher.java:35)
    at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:104)
    at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:97)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:62)
    at org.gradle.initialization.DefaultGradleLauncher.runRootBuildOperation(DefaultGradleLauncher.java:184)
    at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:97)
    at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:86)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:93)
    at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28)
    at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:43)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:27)
    at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:72)
    at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:44)
    at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:49)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
    at org.gradle.util.Swapper.swap(Swapper.java:38)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.health.DaemonHealthTracker.execute(DaemonHealthTracker.java:47)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:66)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:71)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.health.HintGCAfterBuild.execute(HintGCAfterBuild.java:41)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
    at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:246)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
    at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
Caused by: org.gradle.api.GradleException: Error running Asciidoctor
    at org.asciidoctor.gradle.AsciidoctorTask.processDocumentsAndResources(AsciidoctorTask.groovy:659)
    at org.asciidoctor.gradle.AsciidoctorTask.this$4$processDocumentsAndResources(AsciidoctorTask.groovy)
    at org.asciidoctor.gradle.AsciidoctorTask$this$4$processDocumentsAndResources.callCurrent(Unknown Source)
    at org.asciidoctor.gradle.AsciidoctorTask.processAsciidocSources(AsciidoctorTask.groovy:592)
    at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:75)
    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.doExecute(AnnotationProcessingTaskFactory.java:226)
    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:219)
    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:208)
    at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:585)
    at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:568)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
    ... 69 more
Caused by: org.jruby.exceptions.RaiseException: (LoadError) no such file to load -- kindlegen
    at org.jruby.RubyKernel.require(org/jruby/RubyKernel.java:1065)
    at RUBY.require(/Users/rwinch/.gradle/caches/modules-2/files-2.1/org.jruby/jruby-complete/1.7.16.1/b76682bd0966a31dab60dc5e275d8b28ac17c38f/jruby-complete-1.7.16.1.jar!/META-INF/jruby.home/lib/ruby/shared/rubygems/core_ext/kernel_require.rb:55)
    at RUBY.distill_epub_to_mobi(/Users/rwinch/.gradle/caches/modules-2/files-2.1/org.asciidoctor/asciidoctorj-epub3/1.5.0-alpha.4/12eb495d3d07b1a62c587e70a9243776f57bc8cd/asciidoctorj-epub3-1.5.0-alpha.4.jar!/gems/asciidoctor-epub3-1.5.0.alpha.4/lib/asciidoctor-epub3/packager.rb:459)
    at RUBY.package(/Users/rwinch/.gradle/caches/modules-2/files-2.1/org.asciidoctor/asciidoctorj-epub3/1.5.0-alpha.4/12eb495d3d07b1a62c587e70a9243776f57bc8cd/asciidoctorj-epub3-1.5.0-alpha.4.jar!/gems/asciidoctor-epub3-1.5.0.alpha.4/lib/asciidoctor-epub3/packager.rb:449)
    at RUBY.write(/Users/rwinch/.gradle/caches/modules-2/files-2.1/org.asciidoctor/asciidoctorj-epub3/1.5.0-alpha.4/12eb495d3d07b1a62c587e70a9243776f57bc8cd/asciidoctorj-epub3-1.5.0-alpha.4.jar!/gems/asciidoctor-epub3-1.5.0.alpha.4/lib/asciidoctor-epub3/converter.rb:37)
    at RUBY.write(/Users/rwinch/.gradle/caches/modules-2/files-2.1/org.asciidoctor/asciidoctorj/1.5.2/39d33f739ec1c46f6e908a725264eb74b23c9f99/asciidoctorj-1.5.2.jar!/gems/asciidoctor-1.5.2/lib/asciidoctor/document.rb:1051)
    at RUBY.convert(/Users/rwinch/.gradle/caches/modules-2/files-2.1/org.asciidoctor/asciidoctorj/1.5.2/39d33f739ec1c46f6e908a725264eb74b23c9f99/asciidoctorj-1.5.2.jar!/gems/asciidoctor-1.5.2/lib/asciidoctor.rb:1504)
    at RUBY.convert_file(/Users/rwinch/.gradle/caches/modules-2/files-2.1/org.asciidoctor/asciidoctorj/1.5.2/39d33f739ec1c46f6e908a725264eb74b23c9f99/asciidoctorj-1.5.2.jar!/gems/asciidoctor-1.5.2/lib/asciidoctor.rb:1562)
    at RUBY.convertFile(<script>:68)
    at org.jruby.gen.InterfaceImpl996036484.convertFile(org/jruby/gen/InterfaceImpl996036484.gen:13)
    at org.asciidoctor.gradle.AsciidoctorProxyImpl.renderFile(AsciidoctorProxyImpl.groovy:26)
    at org.asciidoctor.gradle.AsciidoctorTask.processSingleFile(AsciidoctorTask.groovy:672)
    at org.asciidoctor.gradle.AsciidoctorTask$_processDocumentsAndResources_closure7.doCall(AsciidoctorTask.groovy:652)
    at org.asciidoctor.gradle.AsciidoctorTask.processDocumentsAndResources(AsciidoctorTask.groovy:647)
    at org.asciidoctor.gradle.AsciidoctorTask.processAsciidocSources(AsciidoctorTask.groovy:592)


BUILD FAILED

Total time: 2.098 secs

@mojavelinux
Copy link
Member

When running in the AsciidoctorJ environment, it's necessary to specify the path to kindlegen using the environment variable KINDLEGEN. We probably need another way to pass this information other than an environment variable, but that's the current state of things.

We're not allowed to bundle kindlegen in the jar, which is why this is an exception in the AsciidoctorJ environment.

KINDLEGEN=/path/to/kindlegen gradle asciidoctor

Note that the path is to the kindlegen binary itself.

@rwinch
Copy link
Member

rwinch commented Oct 29, 2015

@mojavelinux Thanks for the tip. I'm curious why it works with Ruby? Is it different rules?

@mojavelinux
Copy link
Member

kindlegen isn't really a gem. It's just using gem install to run a script (partly Ruby, partly make) that downloads kindlegen and puts it into a temporary directory. Technically, the same exact thing could be done in the Gradle build, and that's what we should do.

Since we never run gem install in AsciidoctorJ, this script never runs.

I've been talking to Matt Raible about probably just bringing in the code that downloads and extracts Kindlegen into Asciidoctor EPUB3 so it works consistently everywhere.

@mojavelinux
Copy link
Member

@mojavelinux
Copy link
Member

Btw, here's the kindlegen download script that currently gets run when you execute gem install kindlegen.

https://github.com/tdtds/kindlegen/blob/master/ext/kindlegen/extconf.rb

@rwinch
Copy link
Member

rwinch commented Oct 29, 2015

I've been talking to Matt Raible about probably just bringing in the code that downloads and extracts Kindlegen into Asciidoctor EPUB3 so it works consistently everywhere.

Thanks for the reply. Does that mean I should probably hold off on putting the sample together since this will be improved? Or is it far enough out that putting something together would be valuable?

@mojavelinux
Copy link
Member

I would just start with a comment in the build.gradle file. That gives a hint to people stopping by and documents future work.

I would say that to generate a KF8/MOBI file that you need to do two things:

  • define the ebook-format attribute as kf8 (default value is epub3)
  • pass the path to the kindlegen binary using the environment variable KINDLEGEN

Also note that if you want to generate both the EPUB3 and the KF8/MOBI, you need two invocations of Asciidoctor using the epub3 backend.

That at least lays the groundwork.

@mojavelinux
Copy link
Member

You might also note that there will be a *-kf8.epub3 generated in the output directory. That is a temporary file and should only be used for debugging.

@mojavelinux
Copy link
Member

Eventually that tmp file will get nuked unless the debug flag is enabled.

@mraible
Copy link
Author

mraible commented Oct 29, 2015

Is it possible to have a build.gradle file that defines two separate configurations for the Asciidoctor plugin? For example, I'd like one task that has html5, pdf and epub backends, then another one that has ebook-format=kf8 specified. Or even better, separate tasks for each and one that groups them all together. I suppose I could do two separate build files, but that doesn't seem very DRY.

@rwinch
Copy link
Member

rwinch commented Oct 29, 2015

Both are possible. I'll try and put something together tonight.

For example, I'd like one task that has html5, pdf and epub backends, then another one that has ebook-format=kf8 specified. Or even better, separate tasks for each and one that groups them all together.

This is possible. I don't have time at the moment, but I think I can whip something up tonight that does it for you.

I suppose I could do two separate build files, but that doesn't seem very DRY.

You could get around this by including a gradle file with the common configuration, but I think the multiple tasks is better.

@mojavelinux
Copy link
Member

I know there are examples of this floating around. Here are some:

Here's a rough snippet to give you an idea:

apply plugin: 'org.asciidoctor.convert'
import org.asciidoctor.gradle.AsciidoctorTask

tasks.withType(AsciidoctorTask) { task ->
    sourceDir "$sources"
    outputDir "$output"
    sources {
      include 'index.adoc'
    }
    attributes = 'source-highlighter': 'coderay',
        experimental: true,
        toc: 'right',
        idprefix: '',
        idseparator: '-'
}

task generateHtml(type: AsciidoctorTask, description: 'Generates single page HTML') {
    backends 'html5'
}

task generatePdf(type: AsciidoctorTask, description: 'Generates PDF') {
    backends 'pdf'
}

task generateEpub(type: AsciidoctorTask, description: 'Generates EPUB3') {
    backends 'epub3'
}

@mraible
Copy link
Author

mraible commented Oct 30, 2015

Thanks @mojavelinux. Here's what I came up with:

import org.asciidoctor.gradle.AsciidoctorTask

tasks.withType(AsciidoctorTask) { task ->
    attributes 'sourcedir': '../../../main/webapp',
        'source-highlighter': 'coderay',
        'epub3-stylesdir': './styles/epub',
        'imagesdir': './images',
        toc: 'left',
        icons: 'font',
        linkattrs: true,
        encoding: 'utf-8',
        'setanchors': true,
        'idprefix': '',
        'idseparator': '-',
        'docinfo1': 'true'
}

task html(type: AsciidoctorTask, description: 'Generates single page HTML') {
    backends 'html5'
}

task pdf(type: AsciidoctorTask, description: 'Generates PDF') {
    requires file('src/main/ruby/asciidoctor-pdf-extensions.rb')
    backends 'pdf'
}

task epub(type: AsciidoctorTask, description: 'Generates EPUB3') {
    backends 'epub3'
}

task mobi(type: AsciidoctorTask, description: 'Generates MOBI') {
    backends 'epub3'
    attributes 'sourcedir': '../../../main/webapp',
        'source-highlighter': 'coderay',
        'epub3-stylesdir': './styles/epub',
        'ebook-format': 'kf8',
        'imagesdir': './images',
        toc: 'left',
        icons: 'font',
        linkattrs: true,
        encoding: 'utf-8',
        'setanchors': true,
        'idprefix': '',
        'idseparator': '-',
        'docinfo1': 'true'
}

defaultTasks 'html', 'pdf', 'epub', 'mobi'

The major issue I've found is that the 'epub' task fails, so 'mobi' never gets kicked off. The index.epub file seems to be generated OK, so I'm not sure why it fails.

$ ./gradlew --stacktrace
:html
:pdf
Passing through unknown backend: pdf
> Building 25% > :pdfProcessing colophon...
Processing building-an-app-with-jhipster...
Processing jhipsters-ui-components...
Processing jhipsters-api-building-blocks...
50% > :epubWrote EPUB3 to /Users/mraible/dev/jhipster-book/build/asciidoc/epub3/index.epub
:epub FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':epub'.
> Error running Asciidoctor

* Try:
Run with --info or --debug option to get more log output.

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':epub'.
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:69)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
    at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
    at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:64)
    at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
    at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:42)
    at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
    at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
    at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
    at org.gradle.api.internal.AbstractTask.executeWithoutThrowingTaskFailure(AbstractTask.java:305)
    at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.executeTask(AbstractTaskPlanExecutor.java:79)
    at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:63)
    at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:51)
    at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:23)
    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:88)
    at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:29)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:62)
    at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23)
    at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:68)
    at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:62)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:55)
    at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:149)
    at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:106)
    at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:86)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:80)
    at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:33)
    at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:24)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:36)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:26)
    at org.gradle.launcher.cli.RunBuildAction.run(RunBuildAction.java:51)
    at org.gradle.internal.Actions$RunnableActionAdapter.execute(Actions.java:171)
    at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:237)
    at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:210)
    at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:35)
    at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:24)
    at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:206)
    at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:169)
    at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:33)
    at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:22)
    at org.gradle.launcher.Main.doAction(Main.java:33)
    at org.gradle.launcher.bootstrap.EntryPoint.run(EntryPoint.java:45)
    at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(ProcessBootstrap.java:54)
    at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:35)
    at org.gradle.launcher.GradleMain.main(GradleMain.java:23)
    at org.gradle.wrapper.BootstrapMainStarter.start(BootstrapMainStarter.java:30)
    at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:127)
    at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:56)
Caused by: org.gradle.api.GradleException: Error running Asciidoctor
    at org.asciidoctor.gradle.AsciidoctorTask.processDocumentsAndResources(AsciidoctorTask.groovy:659)
    at org.asciidoctor.gradle.AsciidoctorTask.this$4$processDocumentsAndResources(AsciidoctorTask.groovy)
    at org.asciidoctor.gradle.AsciidoctorTask$this$4$processDocumentsAndResources.callCurrent(Unknown Source)
    at org.asciidoctor.gradle.AsciidoctorTask.processAsciidocSources(AsciidoctorTask.groovy:592)
    at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:63)
    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.doExecute(AnnotationProcessingTaskFactory.java:218)
    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:211)
    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:200)
    at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:579)
    at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:562)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
    ... 47 more
Caused by: org.jruby.exceptions.RaiseException: (NoMethodError) undefined method `to_ios' for #<Asciidoctor::Epub3::Packager:0x6242e42f>
    at RUBY.postprocess_xhtml(uri:classloader:/gems/asciidoctor-epub3-1.5.0.alpha.4/lib/asciidoctor-epub3/packager.rb:303)
    at RUBY.block in add_content(uri:classloader:/gems/asciidoctor-epub3-1.5.0.alpha.4/lib/asciidoctor-epub3/packager.rb:250)
    at org.jruby.RubyArray.each(org/jruby/RubyArray.java:1560)
    at org.jruby.RubyEnumerable.each_with_index(org/jruby/RubyEnumerable.java:1016)
    at RUBY.block in add_content(uri:classloader:/gems/asciidoctor-epub3-1.5.0.alpha.4/lib/asciidoctor-epub3/packager.rb:248)
    at org.jruby.RubyBasicObject.instance_eval(org/jruby/RubyBasicObject.java:1633)
    at RUBY.block in ordered(uri:classloader:/gems/gepub-0.6.9.2/lib/gepub/resource_builder.rb:40)
    at RUBY.ordered(uri:classloader:/gems/gepub-0.6.9.2/lib/gepub/package.rb:166)
    at RUBY.ordered(uri:classloader:/gems/gepub-0.6.9.2/lib/gepub/book.rb:205)
    at RUBY.ordered(uri:classloader:/gems/gepub-0.6.9.2/lib/gepub/resource_builder.rb:39)
    at RUBY.block in add_content(uri:classloader:/gems/asciidoctor-epub3-1.5.0.alpha.4/lib/asciidoctor-epub3/packager.rb:245)
    at org.jruby.RubyBasicObject.instance_eval(org/jruby/RubyBasicObject.java:1633)
    at RUBY.initialize(uri:classloader:/gems/gepub-0.6.9.2/lib/gepub/resource_builder.rb:33)
    at RUBY.resources(uri:classloader:/gems/gepub-0.6.9.2/lib/gepub/builder.rb:292)
    at RUBY.add_content(uri:classloader:/gems/asciidoctor-epub3-1.5.0.alpha.4/lib/asciidoctor-epub3/packager.rb:240)
    at RUBY.block in package(uri:classloader:/gems/asciidoctor-epub3-1.5.0.alpha.4/lib/asciidoctor-epub3/packager.rb:422)
    at org.jruby.RubyBasicObject.instance_eval(org/jruby/RubyBasicObject.java:1633)
    at RUBY.initialize(uri:classloader:/gems/gepub-0.6.9.2/lib/gepub/builder.rb:185)
    at RUBY.package(uri:classloader:/gems/asciidoctor-epub3-1.5.0.alpha.4/lib/asciidoctor-epub3/packager.rb:340)
    at RUBY.write(uri:classloader:/gems/asciidoctor-epub3-1.5.0.alpha.4/lib/asciidoctor-epub3/converter.rb:37)
    at RUBY.write(uri:classloader:/gems/asciidoctor-1.5.2/lib/asciidoctor/document.rb:1051)
    at RUBY.convert(uri:classloader:/gems/asciidoctor-1.5.2/lib/asciidoctor.rb:1504)
    at RUBY.convert_file(uri:classloader:/gems/asciidoctor-1.5.2/lib/asciidoctor.rb:1562)
    at RUBY.convertFile(<script>:68)

It seems this is an open issue: asciidoctor/asciidoctor-epub3#25

It might be possible to set a KINDLEGEN environment variable using something like the following, but I'm not sure how to make a task dependent on two types.

http://stackoverflow.com/questions/22605947/how-do-set-environment-variable-in-gradle-via-task

I'd be nice to consolidate the attributes too. The following seems to accomplish this:

def attrs = ['sourcedir'         : '../../../main/webapp',
             'source-highlighter': 'coderay',
             'epub3-stylesdir'   : './styles/epub',
             'imagesdir'         : './images',
             toc                 : 'left',
             icons               : 'font',
             linkattrs           : true,
             encoding            : 'utf-8',
             'setanchors'        : true,
             'idprefix'          : '',
             'idseparator'       : '-',
             'docinfo1'          : 'true']

tasks.withType(AsciidoctorTask) { task ->
    attributes attrs
}

task html(type: AsciidoctorTask, description: 'Generates single page HTML') {
    backends 'html5'
}

task pdf(type: AsciidoctorTask, description: 'Generates PDF') {
    requires file('src/main/ruby/asciidoctor-pdf-extensions.rb')
    backends 'pdf'
}

task epub(type: AsciidoctorTask, description: 'Generates EPUB3') {
    backends 'epub3'
}

task mobi(type: AsciidoctorTask, description: 'Generates MOBI') {
    backends 'epub3'
    attrs.put('ebook-format', 'kf8')
    attributes attrs
}

@mraible
Copy link
Author

mraible commented Oct 30, 2015

To get this to run and create HTML5, PDF, EPUB and MOBI formats, I added an 'all' task:

pdf.shouldRunAfter html
epub.shouldRunAfter pdf

task all(dependsOn: ['html', 'pdf', 'epub', 'mobi'])

defaultTasks 'all'

Then I created a build.sh that runs all (which creates the .epub but fails the build), followed by mobi with KINDLEGEN specified.

#!/usr/bin/env bash
./gradlew clean all
KINDLEGEN=/opt/tools/kindlegen/kindlegen ./gradlew mobi

@rwinch
Copy link
Member

rwinch commented Oct 30, 2015

I didn't get any free time last night to complete the sample. Seems like @mraible beat me to getting it working.

I updated the sample to automatically download kindlegen (only supports OSX and Linux at the moment). I also set the gradlew script to export the KINDLEGEN environment variable to the location that the Gradle build will unzip the kindlegen script.

However, I'm getting an error that is posted below. Occasionally it appears to work, but not sure why. Any ideas as to what is wrong?

$ gradlew asciidoctor --stacktrace --debug --no-daemon
...
12:57:26.775 [DEBUG] [org.asciidoctor.internal.JRubyAsciidoctor] asciidoctor -B /Users/rwinch/code/asciidoctor-gradle-examples/asciidoc-to-epub3-kf8-example/src/docs/asciidoc -S UNSAFE -d book -b epub3 -a build-gradle=/Users/rwinch/code/asciidoctor-gradle-examples/asciidoc-to-epub3-kf8-example/build.gradle -a sourcedir=/Users/rwinch/code/asciidoctor-gradle-examples/asciidoc-to-epub3-kf8-example/src/main/java -a endpoint-url=http://example.org -a source-highlighter=coderay -a imagesdir=images -a toc=left -a icons=font -a setanchors=true -a idprefix -a idseparator=- -a docinfo1=true -a ebook-format=kf8 -a projectdir=../../.. -a rootdir=../../.. -a project-name=asciidoc-to-html-example -a project-group -a project-version=1.0.0-SNAPSHOT /Users/rwinch/code/asciidoctor-gradle-examples/asciidoc-to-epub3-kf8-example/src/docs/asciidoc/example-manual.adoc
12:57:27.747 [QUIET] [system.out] Wrote KF8 to /Users/rwinch/code/asciidoctor-gradle-examples/asciidoc-to-epub3-kf8-example/build/asciidoc/epub3/example-manual-kf8.epub
12:57:27.771 [ERROR] [system.err] file:/Users/rwinch/.gradle/caches/modules-2/files-2.1/org.jruby/jruby-complete/1.7.16.1/b76682bd0966a31dab60dc5e275d8b28ac17c38f/jruby-complete-1.7.16.1.jar!/jruby/kernel19/process.rb:13 warning: unsupported spawn option: in
12:57:27.812 [QUIET] [system.out] 
12:57:27.813 [QUIET] [system.out] *************************************************************
12:57:27.813 [QUIET] [system.out]  Amazon kindlegen(MAC OSX) V2.9 build 1028-0897292 
12:57:27.813 [QUIET] [system.out]  A command line e-book compiler 
12:57:27.813 [QUIET] [system.out]  Copyright Amazon.com and its Affiliates 2014 
12:57:27.814 [QUIET] [system.out] *************************************************************
12:57:27.814 [QUIET] [system.out] 
12:57:27.835 [QUIET] [system.out] Info(prcgen):I1047: Added metadata dc:Title        "Example Manual"
12:57:27.836 [QUIET] [system.out] Info(prcgen):I1047: Added metadata dc:Date         "2014-09-09T05:00:00Z"
12:57:27.836 [QUIET] [system.out] Info(prcgen):I1047: Added metadata dc:Creator      "Doc Writer"
12:57:27.836 [QUIET] [system.out] Info(prcgen):I1047: Added metadata dc:Creator      "Asciidoctor"
12:57:27.837 [QUIET] [system.out] Info(prcgen):I1047: Added metadata dc:Contributor  "Doc Writer"
12:57:27.839 [QUIET] [system.out] Info(prcgen):I1002: Parsing files  0000001
12:57:27.878 [QUIET] [system.out] Info(cssparser):I10004: @rules other than @import, @charset and @font-face are not supported.
12:57:27.947 [QUIET] [system.out] Info(prcgen):I1015: Building PRC file
12:57:27.950 [QUIET] [system.out] Info(prcgen):I1006: Resolving hyperlinks
12:57:28.319 [QUIET] [system.out] Info(pagemap):I8000: No Page map found in the book
12:57:28.329 [QUIET] [system.out] Info(prcgen):I1045: Computing UNICODE ranges used in the book
12:57:28.329 [QUIET] [system.out] Info(prcgen):I1046: Found UNICODE range: Basic Latin [20..7E]
12:57:28.330 [QUIET] [system.out] Info(prcgen):I1017: Building PRC file, record count:   0000001
12:57:28.331 [QUIET] [system.out] Info(prcgen):I1039: Final stats - text compressed to (in % of original size):  64.36%
12:57:28.331 [QUIET] [system.out] Info(prcgen):I1040: The document identifier is: "Example_Manual"
12:57:28.331 [QUIET] [system.out] Info(prcgen):I1041: The file format version is V6
12:57:28.331 [QUIET] [system.out] Info(prcgen):I1031: Saving PRC file
12:57:28.332 [QUIET] [system.out] Info(prcgen):I1032: PRC built successfully
12:57:28.359 [QUIET] [system.out] Info(prcgen):I1016: Building enhanced PRC file
12:57:28.360 [QUIET] [system.out] Info(prcgen):I1007: Resolving mediaidlinks
12:57:28.360 [QUIET] [system.out] Info(prcgen):I1011: Writing mediaidlinks
12:57:28.360 [QUIET] [system.out] Info(prcgen):I1009: Resolving guide items
12:57:28.360 [QUIET] [system.out] Info(prcgen):I1017: Building PRC file, record count:   0000009
12:57:28.360 [QUIET] [system.out] Info(prcgen):I1039: Final stats - text compressed to (in % of original size):  44.31%
12:57:28.361 [QUIET] [system.out] Info(prcgen):I1041: The file format version is V8
12:57:28.362 [QUIET] [system.out] Info(prcgen):I15000:  Approximate Standard Mobi Deliverable file size :   0000075KB
12:57:28.363 [QUIET] [system.out] Info(prcgen):I15001:  Approximate KF8 Deliverable file size :   0000397KB
12:57:28.376 [QUIET] [system.out] Info(prcgen):I1036: Mobi file built successfully
12:57:28.395 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Finished executing task ':asciidoctor'
12:57:28.395 [LIFECYCLE] [class org.gradle.TaskExecutionLogger] :asciidoctor FAILED
12:57:28.396 [INFO] [org.gradle.execution.taskgraph.AbstractTaskPlanExecutor] :asciidoctor (Thread[Daemon worker,5,main]) completed. Took 6.114 secs.
12:57:28.396 [DEBUG] [org.gradle.execution.taskgraph.AbstractTaskPlanExecutor] Task worker [Thread[Daemon worker,5,main]] finished, busy: 29.191 secs, idle: 0.002 secs
12:57:28.402 [ERROR] [org.gradle.BuildExceptionReporter] 
12:57:28.406 [ERROR] [org.gradle.BuildExceptionReporter] FAILURE: Build failed with an exception.
12:57:28.406 [ERROR] [org.gradle.BuildExceptionReporter] 
12:57:28.407 [ERROR] [org.gradle.BuildExceptionReporter] * What went wrong:
12:57:28.407 [ERROR] [org.gradle.BuildExceptionReporter] Execution failed for task ':asciidoctor'.
12:57:28.407 [ERROR] [org.gradle.BuildExceptionReporter] > Error running Asciidoctor
12:57:28.408 [ERROR] [org.gradle.BuildExceptionReporter] 
12:57:28.408 [ERROR] [org.gradle.BuildExceptionReporter] * Exception is:
12:57:28.409 [ERROR] [org.gradle.BuildExceptionReporter] org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':asciidoctor'.
12:57:28.409 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:69)
12:57:28.409 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
12:57:28.409 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
12:57:28.410 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:64)
12:57:28.410 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
12:57:28.410 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:52)
12:57:28.410 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
12:57:28.410 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
12:57:28.411 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
12:57:28.411 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:203)
12:57:28.411 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:185)
12:57:28.411 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:62)
12:57:28.411 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:50)
12:57:28.412 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:25)
12:57:28.412 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:110)
12:57:28.412 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:37)
12:57:28.412 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
12:57:28.412 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.execution.DefaultBuildExecuter.access$000(DefaultBuildExecuter.java:23)
12:57:28.413 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.execution.DefaultBuildExecuter$1.proceed(DefaultBuildExecuter.java:43)
12:57:28.413 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
12:57:28.413 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
12:57:28.414 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:30)
12:57:28.414 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.initialization.DefaultGradleLauncher$4.run(DefaultGradleLauncher.java:154)
12:57:28.415 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.internal.Factories$1.create(Factories.java:22)
12:57:28.415 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
12:57:28.415 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:52)
12:57:28.415 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:151)
12:57:28.416 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.initialization.DefaultGradleLauncher.access$200(DefaultGradleLauncher.java:32)
12:57:28.416 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:99)
12:57:28.416 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:93)
12:57:28.416 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
12:57:28.417 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:62)
12:57:28.417 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:93)
12:57:28.417 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:82)
12:57:28.417 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:94)
12:57:28.417 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28)
12:57:28.418 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
12:57:28.418 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:43)
12:57:28.418 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:28)
12:57:28.418 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:77)
12:57:28.418 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:47)
12:57:28.418 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:52)
12:57:28.419 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
12:57:28.419 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
12:57:28.419 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
12:57:28.420 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
12:57:28.420 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
12:57:28.420 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
12:57:28.420 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
12:57:28.421 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
12:57:28.421 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
12:57:28.421 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
12:57:28.421 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.util.Swapper.swap(Swapper.java:38)
12:57:28.421 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
12:57:28.422 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
12:57:28.422 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.health.DaemonHealthTracker.execute(DaemonHealthTracker.java:47)
12:57:28.422 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
12:57:28.422 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:66)
12:57:28.422 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
12:57:28.423 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
12:57:28.423 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:71)
12:57:28.423 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
12:57:28.423 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
12:57:28.423 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.health.HintGCAfterBuild.execute(HintGCAfterBuild.java:41)
12:57:28.424 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
12:57:28.424 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
12:57:28.424 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:246)
12:57:28.424 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
12:57:28.424 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
12:57:28.425 [ERROR] [org.gradle.BuildExceptionReporter] Caused by: org.gradle.api.GradleException: Error running Asciidoctor
12:57:28.425 [ERROR] [org.gradle.BuildExceptionReporter]    at org.asciidoctor.gradle.AsciidoctorTask.processDocumentsAndResources(AsciidoctorTask.groovy:659)
12:57:28.425 [ERROR] [org.gradle.BuildExceptionReporter]    at org.asciidoctor.gradle.AsciidoctorTask.this$4$processDocumentsAndResources(AsciidoctorTask.groovy)
12:57:28.425 [ERROR] [org.gradle.BuildExceptionReporter]    at org.asciidoctor.gradle.AsciidoctorTask.processAsciidocSources(AsciidoctorTask.groovy:592)
12:57:28.425 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:75)
12:57:28.426 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.doExecute(AnnotationProcessingTaskFactory.java:227)
12:57:28.426 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:220)
12:57:28.426 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:209)
12:57:28.426 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:585)
12:57:28.426 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:568)
12:57:28.426 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
12:57:28.427 [ERROR] [org.gradle.BuildExceptionReporter]    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
12:57:28.427 [ERROR] [org.gradle.BuildExceptionReporter]    ... 68 more
12:57:28.427 [ERROR] [org.gradle.BuildExceptionReporter] Caused by: org.jruby.exceptions.RaiseException: (Errno::ECHILD) No child processes
12:57:28.427 [ERROR] [org.gradle.BuildExceptionReporter] 
12:57:28.427 [LIFECYCLE] [org.gradle.BuildResultLogger] 
12:57:28.428 [LIFECYCLE] [org.gradle.BuildResultLogger] BUILD FAILED
12:57:28.428 [LIFECYCLE] [org.gradle.BuildResultLogger] 

@mojavelinux
Copy link
Member

Caused by: org.jruby.exceptions.RaiseException: (Errno::ECHILD) No child processes

This likely has something to do with these lines and how we are calling the external command.

https://github.com/asciidoctor/asciidoctor-epub3/blob/master/lib/asciidoctor-epub3/packager.rb#L463-L465

Perhaps in the JRuby environment popen2e isn't working or isn't always working, or is returning some funky result. It's probably best just to put a try/catch around it and if it fails to return a happy value we just move on because clearly it's invoking kindlegen.

It might also have to do with JRuby 1.7. I wonder if the same problem happens if you use JRuby 9000 instead. I know they fixed some things with native process threads, so maybe this is that issue.

@mojavelinux
Copy link
Member

undefined method `to_ios' for #Asciidoctor::Epub3::Packager:0x6242e42f

I think this happens when an entry gets into the spine collection that isn't the type it expects. It's obviously assuming too much at the moment, but that's the only possible explanation I can think of.

@mojavelinux
Copy link
Member

Actually, I'm starting think that something is trying to convert the document after its already converted because this message is coming after the file is written. Hmm....

@mojavelinux
Copy link
Member

Yep, that's definitely what is happening. For some reason we are going back into the converter again at the very end and I have no idea what state things are in at that point.

@mojavelinux
Copy link
Member

I have a suspicion that what a converter implements its own write method (as is the case with the EPUB3 converter), AsciidoctorJ is calling the write method twice.

@mojavelinux
Copy link
Member

Aha! The problem is that you aren't specifying a source document, so it's attempting to convert all the AsciiDoc files. Asciidoctor EPUB3 can only be run on a spine document, so as a result you are getting wild results.

sources { include 'index.adoc' }

We definitely need to make it so that Asciidoctor EPUB3 doesn't choke on an arbitrary AsciiDoc document. But for now, that's the rule.

@mojavelinux
Copy link
Member

Btw, if you want to test against local gems, here are the steps. First, setup a gemset for RVM (which of course, you need to have)

$ rvm use 2.2@debugging --create

Then, install the gems you need:

$ gem install asciidoctor-pdf --pre
  gem install asciidoctor-epub3 --pre

Finally, set the following in your Asciidoctor task.

setGemPath file("${System.getenv()['HOME']}/.rvm/gems/ruby-2.2.2@debugging")

What that does is make JRuby use gems installed on your system instead of the gems in the AsciidoctorJ jar. This allows you to modify the Ruby files to add debug statements and such. You can also debug the files if you use something like RubyMine.

@rwinch
Copy link
Member

rwinch commented Oct 31, 2015

@mojavelinux Thanks for the tip. Two follow up questions:

  • I'm curious why I need to do that since the other adoc files start with _. It seems that generally files that start with _ are ignored by the default. If I run using html5 backend without the sources defined, only a single .html file is created. I'm curious..."Why this is different for kf8?"
  • I added sources { include 'example-manual.adoc' } to the sample, but the error still remains. Did I have a typo of some sort? I did try the update sources { include 'example-manual.adoc' } with html5 backend and it renders fine, so I don't think I messed up the sources configuration.

@mojavelinux
Copy link
Member

I'm curious why I need to do that since the other adoc files start with _.

We're talking about two different repositories. This was a problem specific to the JHipster book, which didn't have the leading _. For this repository, it won't be needed...though it's probably save to specify the spine document since in the epub3 backend only makes sense to run on the "master" file.

I added sources { include 'example-manual.adoc' } to the sample, but the error still remains. Did I have a typo of some sort?

I think the problem you are getting is different. Though, I bet it still has to do with the structure of the document. I'll take a closer look.

@mojavelinux
Copy link
Member

...so I checked and the problem is that the example-manual.adoc in the asciidoc-to-epub3-example project doesn't conform to the structure that Asciidoctor EPUB3 currently requires. I want to emphasize that I do want to remove this restriction, but if we are talking about what is already released, then we must adhere to it to avoid errors.

https://github.com/asciidoctor/asciidoctor-epub3#declaring-the-spine

@mojavelinux
Copy link
Member

We have two separate things going on here:

  1. The ebook is generating, but it is incomplete and missing a TOC. This is because the structure of the AsciiDoc document isn't conforming to what is currently required by the converter.
  2. There's an error running the child process in some cases.

I don't really understand the problem with (2) and I'm not able to reproduce it (yet).

I just wanted to make it clear that (1) and (2) are separate issues as far as I can tell.

@mojavelinux
Copy link
Member

Btw, love the automatic download of Kindlegen! I'm trying out your sample now.

@mojavelinux
Copy link
Member

Aha! I bet my suspicion about Posix spawn in JRuby 1.7 is right.

jruby/kernel19/process.rb:13 warning: unsupported spawn option: in

As far as I understand it this was one of the main things fixed in JRuby 9000. So in this subproject, we should use JRuby 9000.

@mojavelinux
Copy link
Member

I also set the gradlew script to export the KINDLEGEN environment variable to the location that the Gradle build will unzip the kindlegen script.

Ah, so that's how you do it! Good thinking. Yet another area that the Gradle docs really let us down (unless my Googling is getting weak).

@mraible
Copy link
Author

mraible commented Nov 1, 2015

I'm happy to confirm that changing the following from:

tasks.withType(AsciidoctorTask) { task ->
    attributes attrs
}

To:

tasks.withType(AsciidoctorTask) { task ->
    attributes attrs
    sources {
        include 'index.adoc'
    }
}

Does indeed fix any failure issues I had with EPUB and MOBI. Here's my build.sh:

#!/usr/bin/env bash
KINDLEGEN=/opt/tools/kindlegen/kindlegen ./gradlew clean all --stacktrace

And here's the output from running it after the change.

$ sh build.sh 
:clean
:html
:pdf
Passing through unknown backend: pdf
> Building 33% > :pdfProcessing colophon...
Processing building-an-app-with-jhipster...
Processing jhipsters-ui-components...
Processing jhipsters-api-building-blocks...
50% > :epubWrote EPUB3 to /Users/mraible/dev/jhipster-book/build/asciidoc/epub3/index.epub
:epub
> Building 66% > :mobiWrote KF8 to /Users/mraible/dev/jhipster-book/build/asciidoc/epub3/index-kf8.epub

*************************************************************
 Amazon kindlegen(MAC OSX) V2.9 build 1028-0897292 
 A command line e-book compiler 
 Copyright Amazon.com and its Affiliates 2014 
*************************************************************

Info(prcgen):I1047: Added metadata dc:Title        "The JHipster Mini-Book"
Info(prcgen):I1047: Added metadata dc:Date         "2015-10-31T06:00:00Z"
Info(prcgen):I1047: Added metadata dc:Creator      "Matt Raible"
Info(prcgen):I1047: Added metadata dc:Creator      "Asciidoctor"
Info(prcgen):I1047: Added metadata dc:Subject      "AngularJS"
Info(prcgen):I1047: Added metadata dc:Subject      "Bootstrap"
Info(prcgen):I1047: Added metadata dc:Subject      "Spring Boot"
Info(prcgen):I1047: Added metadata dc:Contributor  "Matt Raible"
Info(cssparser):I10004: @rules other than @import, @charset and @font-face are not supported.
Info(prcgen):I1002: Parsing files  0000010
Info(prcgen):I1015: Building PRC file
Info(prcgen):I1006: Resolving hyperlinks
Warning(prcgen):W14001: Hyperlink not resolved:  /var/folders/fc/_yl631td525bt3bqrd3fg7f40000gp/T/mobi-IrxCod/OEBPS/building-an-app-with-jhipster.xhtml#Browsersync
Warning(prcgen):W14002: Some hyperlinks could not be resolved.
Info(pagemap):I8000: No Page map found in the book
Info(prcgen):I1045: Computing UNICODE ranges used in the book
Info(prcgen):I1046: Found UNICODE range: Basic Latin [20..7E]
Info(prcgen):I1046: Found UNICODE range: Latin-1 Supplement [A0..FF]
Info(prcgen):I1046: Found UNICODE range: General Punctuation - Windows 1252 [2018..201A]
Info(prcgen):I1046: Found UNICODE range: Enclosed Alphanumerics [2460..24FF]
Info(prcgen):I1046: Found UNICODE range: Dingbats [2700..27BF]
Info(prcgen):I1046: Found UNICODE range: Arrows [2190..21FF]
Info(prcgen):I1046: Found UNICODE range: Latin Extended-A [100..17F]
Info(prcgen):I1046: Found UNICODE range: Box Drawing [2500..257F]
Info(prcgen):I1017: Building PRC file, record count:   0000099
Info(prcgen):I1039: Final stats - text compressed to (in % of original size):  41.92%
Info(prcgen):I1040: The document identifier is: "The_JHipster_Mini-Book"
Info(prcgen):I1041: The file format version is V6
Info(prcgen):I1031: Saving PRC file
Info(prcgen):I1032: PRC built successfully
Info(prcgen):I1016: Building enhanced PRC file
Info(prcgen):I1007: Resolving mediaidlinks
Info(prcgen):I1011: Writing mediaidlinks
Info(prcgen):I1009: Resolving guide items
Info(prcgen):I1017: Building PRC file, record count:   0000126
Info(prcgen):I1039: Final stats - text compressed to (in % of original size):  42.18%
Info(prcgen):I1041: The file format version is V8
Info(prcgen):I15000:  Approximate Standard Mobi Deliverable file size :   0002874KB
Info(prcgen):I15001:  Approximate KF8 Deliverable file size :   0003233KB
Info(prcgen):I1036: Mobi file built successfully
Wrote MOBI to /Users/mraible/dev/jhipster-book/build/asciidoc/epub3/index.mobi
:mobi
:all

BUILD SUCCESSFUL

Total time: 1 mins 48.329 secs

@mojavelinux
Copy link
Member

Fantastic news! Thanks for following up.

Having the kf8/mobi generation in the Gradle examples will definitely help avoid this stumbling block in the future. I've also marked it as a priority to address the failure when running the epub3 backend on an arbitrary AsciiDoc structure (asciidoctor/asciidoctor-epub3#25).

ysb33r pushed a commit to ysb33r/asciidoctor-gradle-examples that referenced this issue Nov 21, 2015
@mojavelinux
Copy link
Member

@rwinch I think we should move forward with merging your branch with the Kindlegen download tasks. Want to send a pull request?

I was thinking that the Kindlegen download would probably make a pretty kick ass plugin, since we can't otherwise distribute Kindlegen. The task might be something like "kindlegen-install" and perhaps "kindlegen-run". wdyt?

@paulvickers
Copy link

paulvickers commented Aug 10, 2016

Thanks for this thread. I now have a version of @mraible's build.gradle and build.sh working to generate epub, html, and pdf in one go. However, there is something that @mraible has done that keeps generating errors for me. In my html task I want to use custom admonition blocks that I have defined in the file source/lib/httlap-blocks.rb.

My folder structure is:

source/
  -- mainfile.ad
  -- asciidoc/chapter source files...
  -- Images/ image files ...
  -- lib/
         -- httlap-blocks.rb
         -- asciidoctor-pdf-extensions.rb

Here is the HTML task from build.gradle

task html(type: AsciidoctorTask, description: 'Generates single page HTML') {
    requires file('source/lib/httlap-blocks.rb')
    backends 'html5'

    resources {
       from (sourceDir) {
          include 'Images/*.png'
       }
    into './'
    }
}

Alas, when I run ./gradlew html -info I get the following error message:

(LoadError) no such file to load -- /Volumes/SSDDisk/gitRepos/httlap/source/lib/httlap-blocks

This is interesting because the real path is:

/Volumes/SSD Disk/git Repos/httlap/source/lib/httlap-blocks

When I copy the httlap repo to a path that has no spaces in the name the error goes away. How do we ensure correct handling of paths with spaces in them?

@paulvickers
Copy link

paulvickers commented Aug 11, 2016

I've been experimenting a bit more. It seems the requires command is somehow stripping the whitespace out of path names. Consider:

task html(type: AsciidoctorTask, description: 'Generates single page HTML') {
    println sourceDir
    def libPath = '' +sourceDir + '/lib/httlap-blocks'
    println libPath
    requires file (libPath)
    backends 'html5'
    attributes 'stylesheet': 'PVasciidoctor-default.css'    
    resources {
       from (sourceDir) {
          include 'Images/*.png'
       }
    into './'
    }
}

If I then run in quiet mode: ./gradlew html -quiet I get the following output:

/Volumes/SSD Disk/git Repos/httlap/source
/Volumes/SSD Disk/git Repos/httlap/source/lib/httlap-blocks

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':html'.
> (LoadError) no such file to load -- /Volumes/SSDDisk/gitRepos/httlap/source/lib/httlap-blocks

The two println statements are correctly showing the spaces in the path name, including the concatenated libPath, but as soon as libPath is passed to requires file then the spaces in the path name get stripped and the process fails.

@mojavelinux
Copy link
Member

Spaces in file names are rarely supported cross platform and should be avoided at all costs. I think it's generally accepted that having a space in file name is an input error. There are numerous components that could be mangling it, from Gradle to JRuby or something in between.

@mojavelinux
Copy link
Member

Despite my rant, this appears to have been fixed in the upcoming release of the Asciidoctor Gradle plugin. You can see the change here:

asciidoctor/asciidoctor-gradle-plugin@25142d4#diff-467e6edfd5f5943cc0fdf8e11457f034L586

(I still think spaces in file names are a bad idea, but at least the case you reported has been solved).

@paulvickers
Copy link

Thanks, Dan. I agree and wouldn't put spaces in the actual file names myself, but it is quite normal for folder names to have spaces in them (I'm thinking of the Windows 'My Documents' folder, for example). I had tried escaping the spaces in folder names, but it didn't work. I'll pull the latest version of AD-gradle and report back.

@paulvickers
Copy link

How do I force it to use this version of AS-gradle? Or do I just need to wait for the new release to go live?

@mojavelinux
Copy link
Member

I had tried escaping the spaces in folder names, but it didn't work.

To clarify, this didn't work because the Gradle plugin was previously removing spaces explicitly.

How do I force it to use this version of AS-gradle?

This should really be covered in the README of the Gradle plugin. However, it is not currently.

Clone the project:

git clone https://github.com/asciidoctor/asciidoctor-gradle-plugin

Switch to the project

cd asciidoctor-gradle-plugin

Install the project to your local Maven repository

./gradlew pTML

Configure the dependency in your build.gradle

buildscript {
    repositories {
        mavenLocal()
        maven { url "https://plugins.gradle.org/m2/" }
    }
    dependencies {
        classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.6.0-SNAPSHOT'
    }
}

@paulvickers
Copy link

Thanks! I can confirm that worked. Much appreciated.

@mojavelinux
Copy link
Member

Great news!

mraible added a commit to mraible/jhipster-book that referenced this issue Mar 6, 2020
mraible added a commit to mraible/jhipster-book that referenced this issue Mar 6, 2020
asciidoctor/asciidoctor-gradle-examples#13 (comment)

Former-commit-id: 0f776369c01d4023d56f45905e70ab4ab79ba859
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants