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

Support post processing with --watch #411

Open
valencik opened this issue Oct 26, 2020 · 1 comment
Open

Support post processing with --watch #411

valencik opened this issue Oct 26, 2020 · 1 comment

Comments

@valencik
Copy link
Contributor

TLDR: I would like to invoke some external command every time mdoc finishes generating files while in file watching mode.

Motivation:

I use mdoc to generate typesafe markdown files, and then use pandoc to turn the markdown into html (or any other format pandoc supports). The current workflow looks like:

coursier launch org.scalameta:mdoc_2.13:2.2.10 -- --in hello.md --out mhello.md \
  && pandoc --from=markdown --to=html5 mhello.md --output=hello.html

I'd prefer to be able to leverage mdoc's file watcher mode (--watch) to gain the performance benefits.

I had assumed this would require the life cycle code in #245 but perhaps not?

@olafurpg
Copy link
Member

Thank you for reporting! I can see how this would be useful. This feature is unrelated to #245, that PR is about managing the life-cycle of custom modifiers.

I think the best way to implement this feature would be to add some kind of "mdoc event protocol" akin to Bazel's "build event protocol" (https://docs.bazel.build/versions/master/build-event-protocol.html#consuming-the-build-event-protocol). Users could hook into the stream of mdoc events with a service provider. Rough sketch of the API

final class EventHandlerContext private[mdoc] (
  val workingDirectory: Path
  // other useful information
)
final class OnWatchIterationComplete private[mdoc] (
  val updatedFiles: List[Path]
)
abstract class EventHandler {
  def withContext(params: EventHandlerContext): EventHandler = this
  def onWatchIterationComplete(params: OnWatchIterationComplete): Unit = ()
  // We can add new hooks in the future as long as they have a default implementation
}
object EventHandler {
  def default(): List[EventHandler] = default(this.getClass.getClassLoader)
  def default(classLoader: ClassLoader): List[EventHandler] =
    ServiceLoader.load(classOf[EventHandler], classLoader).iterator().asScala.toList
}

The watch event can be sent to handlers around this method here

def handleWatchEvent(event: DirectoryChangeEvent): Unit = {

Does this make sense? WDYT?

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

No branches or pull requests

2 participants